diff options
author | Marcin Kuzminski <marcin@python-works.com> | 2012-08-10 03:09:36 +0200 |
---|---|---|
committer | Marcin Kuzminski <marcin@python-works.com> | 2012-08-10 03:09:36 +0200 |
commit | 4090ecefa2696d0e3a9108a6b07f9171dea28748 (patch) | |
tree | 26c52c451d4a6fb7c5a6220ea8017b9900ae6761 /rhodecode/model | |
parent | 10dd3ab1f4aa4d2555884fb86c0c8fa5487b6d67 (diff) |
RhodeCode now has a option to explicitly set forking permissions. ref #508
- changed the way permissons on users groups behave. Now explicit set on user
is more important than permission set on users group
--HG--
branch : beta
Diffstat (limited to 'rhodecode/model')
-rwxr-xr-x | rhodecode/model/db.py | 22 | ||||
-rw-r--r-- | rhodecode/model/forms.py | 4 | ||||
-rw-r--r-- | rhodecode/model/permission.py | 9 | ||||
-rw-r--r-- | rhodecode/model/user.py | 139 | ||||
-rw-r--r-- | rhodecode/model/users_group.py | 4 |
5 files changed, 111 insertions, 67 deletions
diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py index f7610925..c5fea82e 100755 --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -294,6 +294,7 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) + inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) user_log = relationship('UserLog', cascade='all') user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') @@ -504,6 +505,7 @@ class UsersGroup(Base, BaseModel): users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) + inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined") users_group_to_perm = relationship('UsersGroupToPerm', cascade='all') @@ -1084,6 +1086,8 @@ class Permission(Base, BaseModel): ('hg.admin', _('RhodeCode Administrator')), ('hg.create.none', _('Repository creation disabled')), ('hg.create.repository', _('Repository creation enabled')), + ('hg.fork.none', _('Repository forking disabled')), + ('hg.fork.repository', _('Repository forking enabled')), ('hg.register.none', _('Register disabled')), ('hg.register.manual_activate', _('Register new user with RhodeCode ' 'with manual activation')), @@ -1092,6 +1096,24 @@ class Permission(Base, BaseModel): 'with auto activation')), ] + # defines which permissions are more important higher the more important + PERM_WEIGHTS = { + 'repository.none': 0, + 'repository.read': 1, + 'repository.write': 3, + 'repository.admin': 4, + + 'group.none': 0, + 'group.read': 1, + 'group.write': 3, + 'group.admin': 4, + + 'hg.fork.none': 0, + 'hg.fork.repository': 1, + 'hg.create.none': 0, + 'hg.create.repository':1 + } + permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) permission_name = Column("permission_name", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) permission_longname = Column("permission_longname", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py index 3af20c2d..01c8401b 100644 --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -274,7 +274,8 @@ def ApplicationUiSettingsForm(): return _ApplicationUiSettingsForm -def DefaultPermissionsForm(perms_choices, register_choices, create_choices): +def DefaultPermissionsForm(perms_choices, register_choices, create_choices, + fork_choices): class _DefaultPermissionsForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True @@ -283,6 +284,7 @@ def DefaultPermissionsForm(perms_choices, register_choices, create_choices): default_perm = v.OneOf(perms_choices) default_register = v.OneOf(register_choices) default_create = v.OneOf(create_choices) + default_fork = v.OneOf(fork_choices) return _DefaultPermissionsForm diff --git a/rhodecode/model/permission.py b/rhodecode/model/permission.py index 3467c852..2d67c8c9 100644 --- a/rhodecode/model/permission.py +++ b/rhodecode/model/permission.py @@ -77,8 +77,8 @@ class PermissionModel(BaseModel): form_result['perm_user_name']).scalar() u2p = self.sa.query(UserToPerm).filter(UserToPerm.user == perm_user).all() - if len(u2p) != 3: - raise Exception('Defined: %s should be 3 permissions for default' + if len(u2p) != 4: + raise Exception('Defined: %s should be 4 permissions for default' ' user. This should not happen please verify' ' your database' % len(u2p)) @@ -100,6 +100,11 @@ class PermissionModel(BaseModel): form_result['default_create']) self.sa.add(p) + elif p.permission.permission_name.startswith('hg.fork.'): + p.permission = self.get_permission_by_name( + form_result['default_fork']) + self.sa.add(p) + _def_name = form_result['default_perm'].split('repository.')[-1] #stage 2 update all default permissions for repos if checked if form_result['overwrite_default'] == True: diff --git a/rhodecode/model/user.py b/rhodecode/model/user.py index 8b5e3297..bc23c817 100644 --- a/rhodecode/model/user.py +++ b/rhodecode/model/user.py @@ -25,7 +25,7 @@ import logging import traceback - +import itertools from pylons import url from pylons.i18n.translation import _ @@ -45,17 +45,7 @@ from rhodecode.lib.exceptions import DefaultUserException, \ log = logging.getLogger(__name__) - -PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, -} +PERM_WEIGHTS = Permission.PERM_WEIGHTS class UserModel(BaseModel): @@ -432,11 +422,11 @@ class UserModel(BaseModel): return user #================================================================== - # set default permissions first for repositories and groups + # SET DEFAULTS GLOBAL, REPOS, REPOS GROUPS #================================================================== uid = user.user_id - # default global permissions + # default global permissions taken fron the default user default_global_perms = self.sa.query(UserToPerm)\ .filter(UserToPerm.user_id == default_user_id) @@ -464,59 +454,70 @@ class UserModel(BaseModel): p = perm.Permission.permission_name user.permissions[GK][rg_k] = p - #================================================================== - # overwrite defaults with user permissions if any found - #================================================================== + #====================================================================== + # !! OVERRIDE GLOBALS !! with user permissions if any found + #====================================================================== + # those can be configured from groups or users explicitly + _configurable = set(['hg.fork.none', 'hg.fork.repository', + 'hg.create.none', 'hg.create.repository']) - # user global permissions + # USER GROUPS comes first + # users group global permissions + user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\ + .options(joinedload(UsersGroupToPerm.permission))\ + .join((UsersGroupMember, UsersGroupToPerm.users_group_id == + UsersGroupMember.users_group_id))\ + .filter(UsersGroupMember.user_id == uid)\ + .order_by(UsersGroupToPerm.users_group_id)\ + .all() + #need to group here by groups since user can be in more than one group + _grouped = [[x, list(y)] for x, y in + itertools.groupby(user_perms_from_users_groups, + lambda x:x.users_group)] + for gr, perms in _grouped: + # since user can be in multiple groups iterate over them and + # select the lowest permissions first (more explicit) + ##TODO: do this^^ + if not gr.inherit_default_permissions: + # NEED TO IGNORE all configurable permissions and + # replace them with explicitly set + user.permissions[GLOBAL] = user.permissions[GLOBAL]\ + .difference(_configurable) + for perm in perms: + user.permissions[GLOBAL].add(perm.permission.permission_name) + + # user specific global permissions user_perms = self.sa.query(UserToPerm)\ .options(joinedload(UserToPerm.permission))\ .filter(UserToPerm.user_id == uid).all() - for perm in user_perms: - user.permissions[GLOBAL].add(perm.permission.permission_name) + if not user.inherit_default_permissions: + # NEED TO IGNORE all configurable permissions and + # replace them with explicitly set + user.permissions[GLOBAL] = user.permissions[GLOBAL]\ + .difference(_configurable) - # user explicit permissions for repositories - user_repo_perms = \ - self.sa.query(UserRepoToPerm, Permission, Repository)\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .filter(UserRepoToPerm.user_id == uid)\ - .all() + for perm in user_perms: + user.permissions[GLOBAL].add(perm.permission.permission_name) - for perm in user_repo_perms: - # set admin if owner - r_k = perm.UserRepoToPerm.repository.repo_name - if perm.Repository.user_id == uid: - p = 'repository.admin' - else: - p = perm.Permission.permission_name - user.permissions[RK][r_k] = p - - # USER GROUP - #================================================================== + #====================================================================== + # !! REPO PERMISSIONS !! + #====================================================================== + #====================================================================== # check if user is part of user groups for this repository and - # fill in (or replace with higher) permissions - #================================================================== - - # users group global - user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\ - .options(joinedload(UsersGroupToPerm.permission))\ - .join((UsersGroupMember, UsersGroupToPerm.users_group_id == - UsersGroupMember.users_group_id))\ - .filter(UsersGroupMember.user_id == uid).all() - - for perm in user_perms_from_users_groups: - user.permissions[GLOBAL].add(perm.permission.permission_name) - + # fill in (or NOT replace with higher `or 1` permissions + #====================================================================== # users group for repositories permissions user_repo_perms_from_users_groups = \ self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\ - .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\ - .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\ - .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\ - .filter(UsersGroupMember.user_id == uid)\ - .all() + .join((Repository, UsersGroupRepoToPerm.repository_id == + Repository.repo_id))\ + .join((Permission, UsersGroupRepoToPerm.permission_id == + Permission.permission_id))\ + .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == + UsersGroupMember.users_group_id))\ + .filter(UsersGroupMember.user_id == uid)\ + .all() for perm in user_repo_perms_from_users_groups: r_k = perm.UsersGroupRepoToPerm.repository.repo_name @@ -524,9 +525,28 @@ class UserModel(BaseModel): cur_perm = user.permissions[RK][r_k] # overwrite permission only if it's greater than permission # given from other sources - if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: + if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm] or 1: # disable check user.permissions[RK][r_k] = p + # user explicit permissions for repositories + user_repo_perms = \ + self.sa.query(UserRepoToPerm, Permission, Repository)\ + .join((Repository, UserRepoToPerm.repository_id == + Repository.repo_id))\ + .join((Permission, UserRepoToPerm.permission_id == + Permission.permission_id))\ + .filter(UserRepoToPerm.user_id == uid)\ + .all() + + for perm in user_repo_perms: + # set admin if owner + r_k = perm.UserRepoToPerm.repository.repo_name + if perm.Repository.user_id == uid: + p = 'repository.admin' + else: + p = perm.Permission.permission_name + user.permissions[RK][r_k] = p + # REPO GROUP #================================================================== # get access for this user for repos group and override defaults @@ -574,10 +594,7 @@ class UserModel(BaseModel): return user def has_perm(self, user, perm): - if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class ' - 'got %s instead' % type(perm)) - + perm = self._get_perm(perm) user = self._get_user(user) return UserToPerm.query().filter(UserToPerm.user == user)\ diff --git a/rhodecode/model/users_group.py b/rhodecode/model/users_group.py index c9452200..f2c777f7 100644 --- a/rhodecode/model/users_group.py +++ b/rhodecode/model/users_group.py @@ -165,10 +165,8 @@ class UsersGroupModel(BaseModel): .filter(UsersGroupToPerm.permission == perm).scalar() is not None def grant_perm(self, users_group, perm): - if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') - users_group = self.__get_users_group(users_group) + perm = self._get_perm(perm) # if this permission is already granted skip it _perm = UsersGroupToPerm.query()\ |