# HG changeset patch # User Marcin Kuzminski # Date 1366676311 -7200 # Node ID d9b89874edf9dbe94c3f1e6693c78ef84331561c # Parent a3b1016855f87b8a982bb1f471e675314662bcbb UserGroup on UserGroup permissions implementation. - user group can have another usergroup assigned - it's impossible to assign usergroup on the same usergroup diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/controllers/admin/users_groups.py --- a/rhodecode/controllers/admin/users_groups.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/controllers/admin/users_groups.py Tue Apr 23 02:18:31 2013 +0200 @@ -33,7 +33,8 @@ from pylons.i18n.translation import _ from rhodecode.lib import helpers as h -from rhodecode.lib.exceptions import UserGroupsAssignedException +from rhodecode.lib.exceptions import UserGroupsAssignedException,\ + RepoGroupAssignmentError from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\ HasUserGroupPermissionAnyDecorator, HasPermissionAnyDecorator @@ -94,10 +95,7 @@ key=lambda u: u[1].lower()) repo_model = RepoModel() c.users_array = repo_model.get_users_js() - - # commented out due to not now supporting assignment for user group - # on user group - c.users_groups_array = "[]" # repo_model.get_users_groups_js() + c.users_groups_array = repo_model.get_users_groups_js() c.available_permissions = config['available_permissions'] def __load_defaults(self, user_group_id): @@ -125,6 +123,10 @@ data.update({'u_perm_%s' % p.user.username: p.permission.permission_name}) + for p in user_group.user_group_user_group_to_perm: + data.update({'g_perm_%s' % p.user_group.users_group_name: + p.permission.permission_name}) + return data def index(self, format='html'): @@ -261,8 +263,12 @@ form = UserGroupPermsForm()().to_python(request.POST) # set the permissions ! - UserGroupModel()._update_permissions(user_group, form['perms_new'], - form['perms_updates']) + try: + UserGroupModel()._update_permissions(user_group, form['perms_new'], + form['perms_updates']) + except RepoGroupAssignmentError: + h.flash(_('Target group cannot be the same'), category='error') + return redirect(url('edit_users_group', id=id)) #TODO: implement this #action_logger(self.rhodecode_user, 'admin_changed_repo_permissions', # repo_name, self.ip_addr, self.sa) @@ -294,7 +300,8 @@ UserGroupModel().revoke_user_permission(user_group=id, user=obj_id) elif obj_type == 'user_group': - pass + UserGroupModel().revoke_users_group_permission(target_user_group=id, + user_group=obj_id) Session().commit() except Exception: log.error(traceback.format_exc()) diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/lib/exceptions.py --- a/rhodecode/lib/exceptions.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/lib/exceptions.py Tue Apr 23 02:18:31 2013 +0200 @@ -62,6 +62,10 @@ pass +class RepoGroupAssignmentError(Exception): + pass + + class HTTPLockedRC(HTTPClientError): """ Special Exception For locked Repos in RhodeCode, the return code can diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/lib/vcs/exceptions.py --- a/rhodecode/lib/vcs/exceptions.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/lib/vcs/exceptions.py Tue Apr 23 02:18:31 2013 +0200 @@ -89,5 +89,6 @@ class ImproperArchiveTypeError(VCSError): pass + class CommandError(VCSError): pass diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/model/db.py --- a/rhodecode/model/db.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/model/db.py Tue Apr 23 02:18:31 2013 +0200 @@ -639,6 +639,8 @@ users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') user_user_group_to_perm = relationship('UserUserGroupToPerm ', cascade='all') + user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm ', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + user = relationship('User') def __unicode__(self): @@ -1617,24 +1619,24 @@ return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return u' %s >' % (self.users_group, self.repository) -#TODO; not sure if this will be ever used class UserGroupUserGroupToPerm(Base, BaseModel): __tablename__ = 'user_group_user_group_to_perm' __table_args__ = ( - UniqueConstraint('user_group_id', 'user_group_id', 'permission_id'), + UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), + CheckConstraint('target_user_group_id != user_group_id'), {'extend_existing': True, 'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'} ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', remote_side=target_user_group_id, primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', remote_side=user_group_id, primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') + target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') + user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') permission = relationship('Permission') @classmethod @@ -1647,7 +1649,7 @@ return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return u' %s >' % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/model/user.py --- a/rhodecode/model/user.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/model/user.py Tue Apr 23 02:18:31 2013 +0200 @@ -39,7 +39,7 @@ from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \ UserToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupMember, \ Notification, RepoGroup, UserRepoGroupToPerm, UserGroupRepoGroupToPerm, \ - UserEmailMap, UserIpMap + UserEmailMap, UserIpMap, UserGroupUserGroupToPerm, UserGroup from rhodecode.lib.exceptions import DefaultUserException, \ UserOwnsReposException from rhodecode.model.meta import Session @@ -570,7 +570,6 @@ user.permissions[GLOBAL].add(perm.permission.permission_name) ## END GLOBAL PERMISSIONS - #====================================================================== # !! PERMISSIONS FOR REPOSITORIES !! #====================================================================== @@ -664,6 +663,28 @@ #====================================================================== # !! PERMISSIONS FOR USER GROUPS !! #====================================================================== + # user group for user group permissions + user_group_user_groups_perms = \ + self.sa.query(UserGroupUserGroupToPerm, Permission, UserGroup)\ + .join((UserGroup, UserGroupUserGroupToPerm.target_user_group_id + == UserGroup.users_group_id))\ + .join((Permission, UserGroupUserGroupToPerm.permission_id + == Permission.permission_id))\ + .join((UserGroupMember, UserGroupUserGroupToPerm.user_group_id + == UserGroupMember.users_group_id))\ + .filter(UserGroupMember.user_id == uid)\ + .all() + + multiple_counter = collections.defaultdict(int) + for perm in user_group_user_groups_perms: + g_k = perm.UserGroupUserGroupToPerm.target_user_group.users_group_name + multiple_counter[g_k] += 1 + p = perm.Permission.permission_name + cur_perm = user.permissions[UK][g_k] + if multiple_counter[g_k] > 1: + p = _choose_perm(p, cur_perm) + user.permissions[UK][g_k] = p + #user explicit permission for user groups user_user_groups_perms = Permission.get_default_user_group_perms(uid) for perm in user_user_groups_perms: diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/model/users_group.py --- a/rhodecode/model/users_group.py Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/model/users_group.py Tue Apr 23 02:18:31 2013 +0200 @@ -29,8 +29,10 @@ from rhodecode.model import BaseModel from rhodecode.model.db import UserGroupMember, UserGroup,\ - UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm -from rhodecode.lib.exceptions import UserGroupsAssignedException + UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm,\ + UserGroupUserGroupToPerm +from rhodecode.lib.exceptions import UserGroupsAssignedException,\ + RepoGroupAssignmentError log = logging.getLogger(__name__) @@ -75,7 +77,7 @@ ) else: self.grant_users_group_permission( - user_group=user_group, group_name=member, perm=perm + target_user_group=user_group, user_group=member, perm=perm ) # set new permissions for member, perm, member_type in perms_new: @@ -85,7 +87,7 @@ ) else: self.grant_users_group_permission( - user_group=user_group, group_name=member, perm=perm + target_user_group=user_group, user_group=member, perm=perm ) def get(self, users_group_id, cache=False): @@ -292,8 +294,50 @@ self.sa.delete(obj) log.debug('Revoked perm on %s on %s' % (user_group, user)) - def grant_users_group_permission(self, user_group, group_name, perm): - raise NotImplementedError() + def grant_users_group_permission(self, target_user_group, user_group, perm): + """ + Grant user group permission for given target_user_group + + :param target_user_group: + :param user_group: + :param perm: + """ + target_user_group = self._get_user_group(target_user_group) + user_group = self._get_user_group(user_group) + permission = self._get_perm(perm) + # forbid assigning same user group to itself + if target_user_group == user_group: + raise RepoGroupAssignmentError('target repo:%s cannot be ' + 'assigned to itself' % target_user_group) - def revoke_users_group_permission(self, user_group, group_name): - raise NotImplementedError() + # check if we have that permission already + obj = self.sa.query(UserGroupUserGroupToPerm)\ + .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\ + .filter(UserGroupUserGroupToPerm.user_group == user_group)\ + .scalar() + if obj is None: + # create new ! + obj = UserGroupUserGroupToPerm() + obj.user_group = user_group + obj.target_user_group = target_user_group + obj.permission = permission + self.sa.add(obj) + log.debug('Granted perm %s to %s on %s' % (perm, target_user_group, user_group)) + + def revoke_users_group_permission(self, target_user_group, user_group): + """ + Revoke user group permission for given target_user_group + + :param target_user_group: + :param user_group: + """ + target_user_group = self._get_user_group(target_user_group) + user_group = self._get_user_group(user_group) + + obj = self.sa.query(UserGroupUserGroupToPerm)\ + .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\ + .filter(UserGroupUserGroupToPerm.user_group == user_group)\ + .scalar() + if obj: + self.sa.delete(obj) + log.debug('Revoked perm on %s on %s' % (target_user_group, user_group)) diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html --- a/rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html Tue Apr 23 02:18:31 2013 +0200 @@ -57,7 +57,8 @@ %endfor -<% + + <% _tmpl = h.literal("""' \ \ \ diff -r a3b1016855f8 -r d9b89874edf9 rhodecode/templates/admin/users_groups/user_group_edit_perms.html --- a/rhodecode/templates/admin/users_groups/user_group_edit_perms.html Tue Apr 23 00:56:04 2013 +0200 +++ b/rhodecode/templates/admin/users_groups/user_group_edit_perms.html Tue Apr 23 02:18:31 2013 +0200 @@ -40,6 +40,24 @@ %endfor + ## USER GROUPS + %for g2p in c.users_group.user_group_user_group_to_perm: + + ${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.none')} + ${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.read')} + ${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.write')} + ${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.admin')} + + ${g2p.user_group.users_group_name} + + + + ${_('revoke')} + + + + %endfor + <% _tmpl = h.literal("""' \ \