Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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