def fill_perms(self, user): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that are granted to groups :param user: user instance to fill his perms """ RK = 'repositories' GK = 'repositories_groups' GLOBAL = 'global' user.permissions[RK] = {} user.permissions[GK] = {} user.permissions[GLOBAL] = set() #====================================================================== # fetch default permissions #====================================================================== default_user = User.get_by_username('default', cache=True) default_user_id = default_user.user_id default_repo_perms = Permission.get_default_perms(default_user_id) default_repo_groups_perms = Permission.get_default_group_perms(default_user_id) if user.is_admin: #================================================================== # admin user have all default rights for repositories # and groups set to admin #================================================================== user.permissions[GLOBAL].add('hg.admin') # repositories for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name p = 'repository.admin' user.permissions[RK][r_k] = p # repositories groups for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = 'group.admin' user.permissions[GK][rg_k] = p return user #================================================================== # SET DEFAULTS GLOBAL, REPOS, REPOS GROUPS #================================================================== uid = user.user_id # default global permissions taken fron the default user default_global_perms = self.sa.query(UserToPerm)\ .filter(UserToPerm.user_id == default_user_id) for perm in default_global_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) # defaults for repositories, taken from default user for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name if perm.Repository.private and not (perm.Repository.user_id == uid): # disable defaults for private repos, p = 'repository.none' elif perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' else: p = perm.Permission.permission_name user.permissions[RK][r_k] = p # defaults for repositories groups taken from default user permission # on given group for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name user.permissions[GK][rg_k] = p #====================================================================== # !! 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 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() 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) for perm in user_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) #====================================================================== # !! REPO PERMISSIONS !! #====================================================================== #====================================================================== # check if user is part of user groups for this repository and # 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() for perm in user_repo_perms_from_users_groups: r_k = perm.UsersGroupRepoToPerm.repository.repo_name p = perm.Permission.permission_name cur_perm = user.permissions[RK][r_k] # overwrite permission only if it's greater than permission # given from other sources - disabled with `or 1` now if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm] or 1: # disable check if perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' 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 #================================================================== # user explicit permissions for repository user_repo_groups_perms = \ self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ .filter(UserRepoGroupToPerm.user_id == uid)\ .all() for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][rg_k] if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm] or 1: # disable check user.permissions[GK][rg_k] = p # REPO GROUP + USER GROUP #================================================================== # check if user is part of user groups for this repo group and # fill in (or replace with higher) permissions #================================================================== # users group for repositories permissions user_repo_group_perms_from_users_groups = \ self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\ .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\ .filter(UsersGroupMember.user_id == uid)\ .all() for perm in user_repo_group_perms_from_users_groups: g_k = perm.UsersGroupRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][g_k] # overwrite permission only if it's greater than permission # given from other sources if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm] or 1: # disable check user.permissions[GK][g_k] = p return user
def fill_perms(self, user, explicit=True, algo='higherwin'): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that are granted to groups :param user: user instance to fill his perms :param explicit: In case there are permissions both for user and a group that user is part of, explicit flag will defiine if user will explicitly override permissions from group, if it's False it will make decision based on the algo :param algo: algorithm to decide what permission should be choose if it's multiple defined, eg user in two different groups. It also decides if explicit flag is turned off how to specify the permission for case when user is in a group + have defined separate permission """ RK = 'repositories' GK = 'repositories_groups' GLOBAL = 'global' user.permissions[RK] = {} user.permissions[GK] = {} user.permissions[GLOBAL] = set() def _choose_perm(new_perm, cur_perm): new_perm_val = PERM_WEIGHTS[new_perm] cur_perm_val = PERM_WEIGHTS[cur_perm] if algo == 'higherwin': if new_perm_val > cur_perm_val: return new_perm return cur_perm elif algo == 'lowerwin': if new_perm_val < cur_perm_val: return new_perm return cur_perm #====================================================================== # fetch default permissions #====================================================================== default_user = User.get_by_username('default', cache=True) default_user_id = default_user.user_id default_repo_perms = Permission.get_default_perms(default_user_id) default_repo_groups_perms = Permission.get_default_group_perms( default_user_id) if user.is_admin: #================================================================== # admin user have all default rights for repositories # and groups set to admin #================================================================== user.permissions[GLOBAL].add('hg.admin') # repositories for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name p = 'repository.admin' user.permissions[RK][r_k] = p # repository groups for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = 'group.admin' user.permissions[GK][rg_k] = p return user #================================================================== # SET DEFAULTS GLOBAL, REPOS, REPOSITORY GROUPS #================================================================== uid = user.user_id # default global permissions taken fron the default user default_global_perms = self.sa.query(UserToPerm)\ .filter(UserToPerm.user_id == default_user_id) for perm in default_global_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) # defaults for repositories, taken from default user for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name if perm.Repository.private and not (perm.Repository.user_id == uid): # disable defaults for private repos, p = 'repository.none' elif perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' else: p = perm.Permission.permission_name user.permissions[RK][r_k] = p # defaults for repository groups taken from default user permission # on given group for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name user.permissions[GK][rg_k] = p #====================================================================== # !! 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 GROUPS comes first # user group global permissions user_perms_from_users_groups = self.sa.query(UserGroupToPerm)\ .options(joinedload(UserGroupToPerm.permission))\ .join((UserGroupMember, UserGroupToPerm.users_group_id == UserGroupMember.users_group_id))\ .filter(UserGroupMember.user_id == uid)\ .order_by(UserGroupToPerm.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() 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) for perm in user_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) #====================================================================== # !! PERMISSIONS FOR REPOSITORIES !! #====================================================================== #====================================================================== # check if user is part of user groups for this repository and # fill in his permission from it. _choose_perm decides of which # permission should be selected based on selected method #====================================================================== # user group for repositories permissions user_repo_perms_from_users_groups = \ self.sa.query(UserGroupRepoToPerm, Permission, Repository,)\ .join((Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id))\ .join((Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id))\ .join((UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id))\ .filter(UserGroupMember.user_id == uid)\ .all() multiple_counter = collections.defaultdict(int) for perm in user_repo_perms_from_users_groups: r_k = perm.UserGroupRepoToPerm.repository.repo_name multiple_counter[r_k] += 1 p = perm.Permission.permission_name cur_perm = user.permissions[RK][r_k] if perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' else: if multiple_counter[r_k] > 1: p = _choose_perm(p, cur_perm) user.permissions[RK][r_k] = p # user explicit permissions for repositories, overrides any specified # by the group permission 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: r_k = perm.UserRepoToPerm.repository.repo_name cur_perm = user.permissions[RK][r_k] # set admin if owner if perm.Repository.user_id == uid: p = 'repository.admin' else: p = perm.Permission.permission_name if not explicit: p = _choose_perm(p, cur_perm) user.permissions[RK][r_k] = p #====================================================================== # !! PERMISSIONS FOR REPOSITORY GROUPS !! #====================================================================== #====================================================================== # check if user is part of user groups for this repository groups and # fill in his permission from it. _choose_perm decides of which # permission should be selected based on selected method #====================================================================== # user group for repo groups permissions user_repo_group_perms_from_users_groups = \ self.sa.query(UserGroupRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id))\ .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id))\ .filter(UserGroupMember.user_id == uid)\ .all() multiple_counter = collections.defaultdict(int) for perm in user_repo_group_perms_from_users_groups: g_k = perm.UserGroupRepoGroupToPerm.group.group_name multiple_counter[g_k] += 1 p = perm.Permission.permission_name cur_perm = user.permissions[GK][g_k] if multiple_counter[g_k] > 1: p = _choose_perm(p, cur_perm) user.permissions[GK][g_k] = p # user explicit permissions for repository groups user_repo_groups_perms = \ self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ .filter(UserRepoGroupToPerm.user_id == uid)\ .all() for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][rg_k] if not explicit: p = _choose_perm(p, cur_perm) user.permissions[GK][rg_k] = p return user
def fill_perms(self, user): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that are granted to groups :param user: user instance to fill his perms """ RK = 'repositories' GK = 'repositories_groups' GLOBAL = 'global' user.permissions[RK] = {} user.permissions[GK] = {} user.permissions[GLOBAL] = set() #====================================================================== # fetch default permissions #====================================================================== default_user = User.get_by_username('default', cache=True) default_user_id = default_user.user_id default_repo_perms = Permission.get_default_perms(default_user_id) default_repo_groups_perms = Permission.get_default_group_perms(default_user_id) if user.is_admin: #================================================================== # admin user have all default rights for repositories # and groups set to admin #================================================================== user.permissions[GLOBAL].add('hg.admin') # repositories for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name p = 'repository.admin' user.permissions[RK][r_k] = p # repositories groups for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = 'group.admin' user.permissions[GK][rg_k] = p return user #================================================================== # set default permissions first for repositories and groups #================================================================== uid = user.user_id # default global permissions default_global_perms = self.sa.query(UserToPerm)\ .filter(UserToPerm.user_id == default_user_id) for perm in default_global_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) # defaults for repositories, taken from default user for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name if perm.Repository.private and not (perm.Repository.user_id == uid): # disable defaults for private repos, p = 'repository.none' elif perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' else: p = perm.Permission.permission_name user.permissions[RK][r_k] = p # defaults for repositories groups taken from default user permission # on given group for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name user.permissions[GK][rg_k] = p #================================================================== # overwrite defaults with user permissions if any found #================================================================== # user 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) # 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 # USER GROUP #================================================================== # 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) # 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() for perm in user_repo_perms_from_users_groups: r_k = perm.UsersGroupRepoToPerm.repository.repo_name p = perm.Permission.permission_name 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]: user.permissions[RK][r_k] = p # REPO GROUP #================================================================== # get access for this user for repos group and override defaults #================================================================== # user explicit permissions for repository user_repo_groups_perms = \ self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ .filter(UserRepoGroupToPerm.user_id == uid)\ .all() for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][rg_k] if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: user.permissions[GK][rg_k] = p # REPO GROUP + USER GROUP #================================================================== # check if user is part of user groups for this repo group and # fill in (or replace with higher) permissions #================================================================== # users group for repositories permissions user_repo_group_perms_from_users_groups = \ self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\ .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\ .filter(UsersGroupMember.user_id == uid)\ .all() for perm in user_repo_group_perms_from_users_groups: g_k = perm.UsersGroupRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][g_k] # overwrite permission only if it's greater than permission # given from other sources if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: user.permissions[GK][g_k] = p return user
def fill_perms(self, user, explicit=True, algo="higherwin"): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that are granted to groups :param user: user instance to fill his perms :param explicit: In case there are permissions both for user and a group that user is part of, explicit flag will defiine if user will explicitly override permissions from group, if it's False it will make decision based on the algo :param algo: algorithm to decide what permission should be choose if it's multiple defined, eg user in two different groups. It also decides if explicit flag is turned off how to specify the permission for case when user is in a group + have defined separate permission """ RK = "repositories" GK = "repositories_groups" UK = "user_groups" GLOBAL = "global" user.permissions[RK] = {} user.permissions[GK] = {} user.permissions[UK] = {} user.permissions[GLOBAL] = set() def _choose_perm(new_perm, cur_perm): new_perm_val = PERM_WEIGHTS[new_perm] cur_perm_val = PERM_WEIGHTS[cur_perm] if algo == "higherwin": if new_perm_val > cur_perm_val: return new_perm return cur_perm elif algo == "lowerwin": if new_perm_val < cur_perm_val: return new_perm return cur_perm # ====================================================================== # fetch default permissions # ====================================================================== default_user = User.get_by_username("default", cache=True) default_user_id = default_user.user_id default_repo_perms = Permission.get_default_perms(default_user_id) default_repo_groups_perms = Permission.get_default_group_perms(default_user_id) default_user_group_perms = Permission.get_default_user_group_perms(default_user_id) if user.is_admin: # ================================================================== # admin user have all default rights for repositories # and groups set to admin # ================================================================== user.permissions[GLOBAL].add("hg.admin") # repositories for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name p = "repository.admin" user.permissions[RK][r_k] = p # repository groups for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = "group.admin" user.permissions[GK][rg_k] = p # user groups for perm in default_user_group_perms: u_k = perm.UserUserGroupToPerm.user_group.users_group_name p = "usergroup.admin" user.permissions[UK][u_k] = p return user # ================================================================== # SET DEFAULTS GLOBAL, REPOS, REPOSITORY GROUPS # ================================================================== uid = user.user_id # default global permissions taken fron the default user default_global_perms = self.sa.query(UserToPerm).filter(UserToPerm.user_id == default_user_id) for perm in default_global_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) # defaults for repositories, taken from default user for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name if perm.Repository.private and not (perm.Repository.user_id == uid): # disable defaults for private repos, p = "repository.none" elif perm.Repository.user_id == uid: # set admin if owner p = "repository.admin" else: p = perm.Permission.permission_name user.permissions[RK][r_k] = p # defaults for repository groups taken from default user permission # on given group for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name user.permissions[GK][rg_k] = p # defaults for user groups taken from default user permission # on given user group for perm in default_user_group_perms: u_k = perm.UserUserGroupToPerm.user_group.users_group_name p = perm.Permission.permission_name user.permissions[UK][u_k] = p # ====================================================================== # !! 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", "hg.usergroup.create.false", "hg.usergroup.create.true", ] ) # USER GROUPS comes first # user group global permissions user_perms_from_users_groups = ( self.sa.query(UserGroupToPerm) .options(joinedload(UserGroupToPerm.permission)) .join((UserGroupMember, UserGroupToPerm.users_group_id == UserGroupMember.users_group_id)) .filter(UserGroupMember.user_id == uid) .order_by(UserGroupToPerm.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() ) 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) for perm in user_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) ## END GLOBAL PERMISSIONS # ====================================================================== # !! PERMISSIONS FOR REPOSITORIES !! # ====================================================================== # ====================================================================== # check if user is part of user groups for this repository and # fill in his permission from it. _choose_perm decides of which # permission should be selected based on selected method # ====================================================================== # user group for repositories permissions user_repo_perms_from_users_groups = ( self.sa.query(UserGroupRepoToPerm, Permission, Repository) .join((Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id)) .join((Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id)) .join((UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id)) .filter(UserGroupMember.user_id == uid) .all() ) multiple_counter = collections.defaultdict(int) for perm in user_repo_perms_from_users_groups: r_k = perm.UserGroupRepoToPerm.repository.repo_name multiple_counter[r_k] += 1 p = perm.Permission.permission_name cur_perm = user.permissions[RK][r_k] if perm.Repository.user_id == uid: # set admin if owner p = "repository.admin" else: if multiple_counter[r_k] > 1: p = _choose_perm(p, cur_perm) user.permissions[RK][r_k] = p # user explicit permissions for repositories, overrides any specified # by the group permission user_repo_perms = Permission.get_default_perms(uid) for perm in user_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name cur_perm = user.permissions[RK][r_k] # set admin if owner if perm.Repository.user_id == uid: p = "repository.admin" else: p = perm.Permission.permission_name if not explicit: p = _choose_perm(p, cur_perm) user.permissions[RK][r_k] = p # ====================================================================== # !! PERMISSIONS FOR REPOSITORY GROUPS !! # ====================================================================== # ====================================================================== # check if user is part of user groups for this repository groups and # fill in his permission from it. _choose_perm decides of which # permission should be selected based on selected method # ====================================================================== # user group for repo groups permissions user_repo_group_perms_from_users_groups = ( self.sa.query(UserGroupRepoGroupToPerm, Permission, RepoGroup) .join((RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)) .join((Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id)) .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id)) .filter(UserGroupMember.user_id == uid) .all() ) multiple_counter = collections.defaultdict(int) for perm in user_repo_group_perms_from_users_groups: g_k = perm.UserGroupRepoGroupToPerm.group.group_name multiple_counter[g_k] += 1 p = perm.Permission.permission_name cur_perm = user.permissions[GK][g_k] if multiple_counter[g_k] > 1: p = _choose_perm(p, cur_perm) user.permissions[GK][g_k] = p # user explicit permissions for repository groups user_repo_groups_perms = Permission.get_default_group_perms(uid) for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][rg_k] if not explicit: p = _choose_perm(p, cur_perm) user.permissions[GK][rg_k] = p # ====================================================================== # !! 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: u_k = perm.UserUserGroupToPerm.user_group.users_group_name p = perm.Permission.permission_name cur_perm = user.permissions[UK][u_k] if not explicit: p = _choose_perm(p, cur_perm) user.permissions[UK][u_k] = p return user
def fill_perms(self, user): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that are granted to groups :param user: user instance to fill his perms """ RK = 'repositories' GK = 'repositories_groups' GLOBAL = 'global' user.permissions[RK] = {} user.permissions[GK] = {} user.permissions[GLOBAL] = set() #====================================================================== # fetch default permissions #====================================================================== default_user = User.get_by_username('default', cache=True) default_user_id = default_user.user_id default_repo_perms = Permission.get_default_perms(default_user_id) default_repo_groups_perms = Permission.get_default_group_perms( default_user_id) if user.is_admin: #================================================================== # admin user have all default rights for repositories # and groups set to admin #================================================================== user.permissions[GLOBAL].add('hg.admin') # repositories for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name p = 'repository.admin' user.permissions[RK][r_k] = p # repositories groups for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = 'group.admin' user.permissions[GK][rg_k] = p return user #================================================================== # set default permissions first for repositories and groups #================================================================== uid = user.user_id # default global permissions default_global_perms = self.sa.query(UserToPerm)\ .filter(UserToPerm.user_id == default_user_id) for perm in default_global_perms: user.permissions[GLOBAL].add(perm.permission.permission_name) # defaults for repositories, taken from default user for perm in default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name if perm.Repository.private and not (perm.Repository.user_id == uid): # disable defaults for private repos, p = 'repository.none' elif perm.Repository.user_id == uid: # set admin if owner p = 'repository.admin' else: p = perm.Permission.permission_name user.permissions[RK][r_k] = p # defaults for repositories groups taken from default user permission # on given group for perm in default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name user.permissions[GK][rg_k] = p #================================================================== # overwrite defaults with user permissions if any found #================================================================== # user 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) # 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 # USER GROUP #================================================================== # 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) # 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() for perm in user_repo_perms_from_users_groups: r_k = perm.UsersGroupRepoToPerm.repository.repo_name p = perm.Permission.permission_name 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]: user.permissions[RK][r_k] = p # REPO GROUP #================================================================== # get access for this user for repos group and override defaults #================================================================== # user explicit permissions for repository user_repo_groups_perms = \ self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ .filter(UserRepoGroupToPerm.user_id == uid)\ .all() for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][rg_k] if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: user.permissions[GK][rg_k] = p # REPO GROUP + USER GROUP #================================================================== # check if user is part of user groups for this repo group and # fill in (or replace with higher) permissions #================================================================== # users group for repositories permissions user_repo_group_perms_from_users_groups = \ self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\ .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\ .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\ .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\ .filter(UsersGroupMember.user_id == uid)\ .all() for perm in user_repo_group_perms_from_users_groups: g_k = perm.UsersGroupRepoGroupToPerm.group.group_name p = perm.Permission.permission_name cur_perm = user.permissions[GK][g_k] # overwrite permission only if it's greater than permission # given from other sources if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: user.permissions[GK][g_k] = p return user