Пример #1
0
    def test_copyannotations_command_adds_permissions(self, annotation_set):
        user_from = annotation_set.grader
        user_to = UserFactory()

        call_command(
            "copyannotations",
            user_from.username,
            user_to.username,
            stdout=None,  # suppress output
        )

        checker = ObjectPermissionChecker(user_to)

        for model, _ in self.annotations:
            model_instance = model.objects.get(grader=user_to)
            children = []
            if model == PolygonAnnotationSet:
                children = model_instance.singlepolygonannotation_set.all()
            if model == LandmarkAnnotationSet:
                children = model_instance.singlelandmarkannotation_set.all()

            perms = checker.get_perms(model_instance)
            for permission_type in model._meta.default_permissions:
                assert f"{permission_type}_{model._meta.model_name}" in perms

            if children:
                checker.prefetch_perms(children)
            for child in children:
                perms = checker.get_perms(child)
                child_model_name = children.first()._meta.model_name
                for permission_type in child._meta.default_permissions:
                    assert f"{permission_type}_{child_model_name}" in perms
Пример #2
0
    def test_copyannotations_command_doesnt_add_permissions(
            self, annotation_set):
        user_from = annotation_set.grader
        user_to = UserFactory()

        call_command(
            "copyannotations",
            user_from.username,
            user_to.username,
            add_permissions=False,
            stdout=None,  # suppress output
        )

        checker = ObjectPermissionChecker(user_to)

        for model, _ in self.annotations:
            model_instance = model.objects.get(grader=user_to)
            children = []
            if model == PolygonAnnotationSet:
                children = model_instance.singlepolygonannotation_set.all()
            if model == LandmarkAnnotationSet:
                children = model_instance.singlelandmarkannotation_set.all()

            perms = checker.get_perms(model_instance)
            assert len(perms) == 0

            if children:
                checker.prefetch_perms(children)
            for child in children:
                perms = checker.get_perms(child)
                assert len(perms) == 0
Пример #3
0
    def test_get_perms(self):
        group = Group.objects.create(name='group')
        obj1 = ContentType.objects.create(model='foo',
                                          app_label='guardian-tests')
        obj2 = ContentType.objects.create(model='bar',
                                          app_label='guardian-tests')

        assign_perms = {
            group: ('change_group', 'delete_group'),
            obj1: ('change_contenttype', 'delete_contenttype'),
            obj2: ('delete_contenttype', ),
        }

        check = ObjectPermissionChecker(self.user)

        for obj, perms in assign_perms.items():
            for perm in perms:
                UserObjectPermission.objects.assign_perm(perm, self.user, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))

        check = ObjectPermissionChecker(self.group)

        for obj, perms in assign_perms.items():
            for perm in perms:
                GroupObjectPermission.objects.assign_perm(
                    perm, self.group, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))
Пример #4
0
    def test_get_perms(self):
        group = Group.objects.create(name='group')
        obj1 = ContentType.objects.create(name='ct1', model='foo',
            app_label='guardian-tests')
        obj2 = ContentType.objects.create(name='ct2', model='bar',
            app_label='guardian-tests')

        assign_perms = {
            group: ('change_group', 'delete_group'),
            obj1: ('change_contenttype', 'delete_contenttype'),
            obj2: ('delete_contenttype',),
        }

        check = ObjectPermissionChecker(self.user)

        for obj, perms in assign_perms.items():
            for perm in perms:
                UserObjectPermission.objects.assign_perm(perm, self.user, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))

        check = ObjectPermissionChecker(self.group)

        for obj, perms in assign_perms.items():
            for perm in perms:
                GroupObjectPermission.objects.assign_perm(perm, self.group, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))
Пример #5
0
    def test_copyannotations_command_doesnt_add_permissions(
        self, AnnotationSet
    ):
        user_from = AnnotationSet.grader
        user_to = UserFactory()

        call_command(
            "copyannotations",
            user_from.username,
            user_to.username,
            add_permissions=False,
            stdout=None,  # suppress output
        )

        checker = ObjectPermissionChecker(user_to)

        for model, _ in self.annotations:
            model_instance = model.objects.get(grader=user_to)
            children = []
            if model == PolygonAnnotationSet:
                children = model_instance.singlepolygonannotation_set.all()
            if model == LandmarkAnnotationSet:
                children = model_instance.singlelandmarkannotation_set.all()

            perms = checker.get_perms(model_instance)
            assert len(perms) == 0

            if children:
                checker.prefetch_perms(children)
            for child in children:
                perms = checker.get_perms(child)
                assert len(perms) == 0
Пример #6
0
    def test_copyannotations_command_adds_permissions(self, AnnotationSet):
        user_from = AnnotationSet.grader
        user_to = UserFactory()

        call_command(
            "copyannotations",
            user_from.username,
            user_to.username,
            stdout=None,  # suppress output
        )

        checker = ObjectPermissionChecker(user_to)

        for model, _ in self.annotations:
            model_instance = model.objects.get(grader=user_to)
            children = []
            if model == PolygonAnnotationSet:
                children = model_instance.singlepolygonannotation_set.all()
            if model == LandmarkAnnotationSet:
                children = model_instance.singlelandmarkannotation_set.all()

            perms = checker.get_perms(model_instance)
            for permission_type in model._meta.default_permissions:
                assert f"{permission_type}_{model._meta.model_name}" in perms

            if children:
                checker.prefetch_perms(children)
            for child in children:
                perms = checker.get_perms(child)
                child_model_name = children.first()._meta.model_name
                for permission_type in child._meta.default_permissions:
                    assert f"{permission_type}_{child_model_name}" in perms
Пример #7
0
 def test_roles_init_new_repo_2(self):
     """
     Groups and permissions created by the repo creations
     """
     repo = Repository.objects.create(
         name=self.repo_name,
         description=self.repo_desc,
         created_by=self.user
     )
     admin = Group.objects.get(name=self.group_admin)
     curator = Group.objects.get(name=self.group_curator)
     author = Group.objects.get(name=self.group_author)
     checker_admin = ObjectPermissionChecker(admin)
     self.assertListEqual(
         sorted(checker_admin.get_perms(repo)),
         sorted(RepoPermission.administrator_permissions())
     )
     checker_curator = ObjectPermissionChecker(curator)
     self.assertListEqual(
         sorted(checker_curator.get_perms(repo)),
         sorted(RepoPermission.curator_permissions())
     )
     checker_author = ObjectPermissionChecker(author)
     self.assertListEqual(
         sorted(checker_author.get_perms(repo)),
         sorted(RepoPermission.author_permissions())
     )
Пример #8
0
    def render(self, context):
        for_whom = self.for_whom.resolve(context)
        if isinstance(for_whom, get_user_model()):
            self.user = for_whom
            self.group = None
        elif isinstance(for_whom, AnonymousUser):
            self.user = get_user_model().get_anonymous()
            self.group = None
        elif isinstance(for_whom, Group):
            self.user = None
            self.group = for_whom
        elif isinstance(for_whom, Organization):
            self.user = None
            self.group = for_whom
        else:
            raise NotUserNorGroup("User or Group instance required (got %s)" %
                                  for_whom.__class__)
        obj = self.obj.resolve(context)
        if not obj:
            return ''

        check = ObjectPermissionChecker(for_whom)
        perms = check.get_perms(
            obj, include_group_perms=self.include_group_permissions)

        context[self.context_var] = perms
        return ''
Пример #9
0
def get_perms(user_or_group, obj, field="codename"):
    """
    Returns permissions for given user/group and object pair, as list of
    strings.
    """
    check = ObjectPermissionChecker(user_or_group)
    return check.get_perms(obj, values_field=field)
Пример #10
0
    def test_setannotationpermissions_sets_correct_permissions(
        self, AnnotationSet
    ):
        admins_group = Group.objects.get(
            name=settings.RETINA_ADMINS_GROUP_NAME
        )
        graders_group = Group.objects.get(
            name=settings.RETINA_GRADERS_GROUP_NAME
        )
        AnnotationSet.grader.groups.add(graders_group)
        call_command("setannotationpermissions")

        checker = ObjectPermissionChecker(AnnotationSet.grader)
        group_perms = Permission.objects.filter(
            group=admins_group
        ).values_list("codename", flat=True)

        for annotation_model in ANNOTATION_MODELS:
            annotation_codename = annotation_model._meta.model_name
            for annotation in annotation_model.objects.all():
                perms = checker.get_perms(annotation)
                for permission_type in annotation._meta.default_permissions:
                    assert f"{permission_type}_{annotation_codename}" in perms

                for permission_type in annotation._meta.default_permissions:
                    assert (
                        f"{permission_type}_{annotation_codename}"
                        in group_perms
                    )
Пример #11
0
    def render(self, context):
        for_whom = self.for_whom.resolve(context)
        if isinstance(for_whom, get_user_model()):
            self.user = for_whom
            self.group = None
        elif isinstance(for_whom, AnonymousUser):
            self.user = get_user_model().get_anonymous()
            self.group = None
        elif isinstance(for_whom, Group):
            self.user = None
            self.group = for_whom
        elif isinstance(for_whom, Organization):
            self.user = None
            self.group = for_whom
        else:
            raise NotUserNorGroup("User or Group instance required (got %s)"
                                  % for_whom.__class__)
        obj = self.obj.resolve(context)
        if not obj:
            return ''

        check = ObjectPermissionChecker(for_whom)
        perms = check.get_perms(obj, include_group_perms=self.include_group_permissions)

        context[self.context_var] = perms
        return ''
def get_perms(user_or_group, obj):
    """
    Returns permissions for given user/group and object pair, as list of
    strings.
    """
    check = ObjectPermissionChecker(user_or_group)
    return check.get_perms(obj)
Пример #13
0
def get_perms(user_or_group, obj):
    """
    Returns permissions for given user/group and object pair, as list of
    strings.
    """
    check = ObjectPermissionChecker(user_or_group)
    return check.get_perms(obj)
Пример #14
0
    def get_context_data(self, **kwargs):

        data = super().get_context_data(**kwargs)

        checker = ObjectPermissionChecker(self.request.user)
        component_perms = checker.get_perms(self.object)
        environment_perms = checker.get_perms(self.environment)

        data.update({
            'current_environment': self.environment,
            'settings': self.settings_dict,
            'component_perms': component_perms,
            'environment_perms': environment_perms,
        })

        return data
Пример #15
0
    def get_context_data(self, **kwargs):

        data = super().get_context_data(**kwargs)

        component = self.object  # type: Component
        environment = get_object_or_404(
            klass=self.request.view_environments,
            alias=self.kwargs['environment']
        )

        settings_dict = security.cleanse(
            data=get_settings(
                environment=environment,
                component=component,
            ),
            hidden=settings.SECURE_KEYS,
        )

        settings_dict = dictutil.flatten(settings_dict)
        settings_dict = inject_settings(
            environment=environment,
            data=settings_dict,
            components=self.request.components,
            strict=False
        )

        form = ComponentSettingsForm(
            component=component,
            environment=environment,
            initial={
                'settings': settings_dict
            }
        )

        checker = ObjectPermissionChecker(self.request.user)
        component_perms = checker.get_perms(component)
        environment_perms = checker.get_perms(environment)

        data.update({
            'current_environment': environment,
            'settings': settings_dict,
            'form': form,
            'component_perms': component_perms,
            'environment_perms': environment_perms
        })

        return data
Пример #16
0
 def test_superuser(self):
     user = User.objects.create(username='******', is_superuser=True)
     check = ObjectPermissionChecker(user)
     ctype = ContentType.objects.get_for_model(self.ctype)
     perms = sorted(
         chain(*Permission.objects.filter(
             content_type=ctype).values_list('codename')))
     self.assertEqual(perms, check.get_perms(self.ctype))
     for perm in perms:
         self.assertTrue(check.has_perm(perm, self.ctype))
Пример #17
0
 def test_superuser(self):
     user = User.objects.create(username='******', is_superuser=True)
     check = ObjectPermissionChecker(user)
     ctype = ContentType.objects.get_for_model(self.ctype)
     perms = sorted(chain(*Permission.objects
         .filter(content_type=ctype)
         .values_list('codename')))
     self.assertEqual(perms, check.get_perms(self.ctype))
     for perm in perms:
         self.assertTrue(check.has_perm(perm, self.ctype))
Пример #18
0
    def get_all_permissions(self, user_obj, obj=None):
        """
        Returns a set of permission strings that the given ``user_obj`` has for ``obj``
        """
        # check if user_obj and object are supported
        support, user_obj = check_support(user_obj, obj)
        if not support:
            return set()

        check = ObjectPermissionChecker(user_obj)
        return check.get_perms(obj)
Пример #19
0
 def test_not_active_superuser(self):
     user = User.objects.create(username='******',
         is_superuser=True, is_active=False)
     check = ObjectPermissionChecker(user)
     ctype = ContentType.objects.get_for_model(self.flatpage)
     perms = sorted(chain(*Permission.objects
         .filter(content_type=ctype)
         .values_list('codename')))
     self.assertEqual(check.get_perms(self.flatpage), [])
     for perm in perms:
         self.assertFalse(check.has_perm(perm, self.flatpage))
Пример #20
0
    def get_all_permissions(self, user_obj, obj=None):
        """
        Returns a set of permission strings that the given ``user_obj`` has for ``obj``
        """
        # check if user_obj and object are supported
        support, user_obj = check_support(user_obj, obj)
        if not support:
            return set()

        check = ObjectPermissionChecker(user_obj)
        return check.get_perms(obj)
Пример #21
0
    def test_get_perms(self):
        group = Group.objects.create(name='group')
        key1 = Keycard.objects.create(key='key1')
        key2 = Keycard.objects.create(key='key2')

        assign_perms = {
            group: ('change_group', 'delete_group'),
            key1: ('change_keycard', 'can_use_keycard', 'can_suspend_keycard'),
            key2: ('delete_keycard', 'can_suspend_keycard'),
        }

        check = ObjectPermissionChecker(self.user)

        for obj, perms in assign_perms.items():
            for perm in perms:
                UserObjectPermission.objects.assign(perm, self.user, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))

        check = ObjectPermissionChecker(self.group)

        for obj, perms in assign_perms.items():
            for perm in perms:
                GroupObjectPermission.objects.assign(perm, self.group, obj)
            self.assertEqual(sorted(perms), sorted(check.get_perms(obj)))
Пример #22
0
    def get_user_perms(self, user, object_list):

        checker = ObjectPermissionChecker(user)
        checker.prefetch_perms(object_list)

        perms = []

        for obj in object_list:
            perms.extend([
                ':'.join([
                    perm,
                    str(obj.pk)
                ])
                for perm in checker.get_perms(obj)
            ])

        return perms
Пример #23
0
def get_perms(user_or_group, obj, direct_perms_only=False):
    """
    Returns permissions for given user/group and object pair, as list of
    strings.

    :param user_or_group: instance of ``User``, ``AnonymousUser`` or ``Group``;
      passing any other object would raise
      ``guardian.exceptions.NotUserNorGroup`` exception

    :param obj: persisted Django's ``Model`` instance

    :param direct_perms_only: If set to ``True`` and ``user_or_group`` is a
       ``User`` instance, result would contain only permissions assigned
       directly to the user for the given ``obj``, not those coming via user's
       superuser status or group memberships.
    """
    check = ObjectPermissionChecker(user_or_group, direct_perms_only)
    return check.get_perms(obj)
Пример #24
0
    def render(self, context):
        for_whom = self.for_whom.resolve(context)
        if isinstance(for_whom, User):
            self.user = for_whom
            self.group = None
        elif isinstance(for_whom, AnonymousUser):
            self.user = User.get_anonymous()
            self.group = None
        elif isinstance(for_whom, Group):
            self.user = None
            self.group = for_whom
        else:
            raise NotUserNorGroup("User or Group instance required (got %s)"
                % for_whom.__class__)
        obj = self.obj.resolve(context)

        check = ObjectPermissionChecker(for_whom)
        perms = check.get_perms(obj)

        context[self.context_var] = perms
        return ''
Пример #25
0
    def render(self, context):
        for_whom = self.for_whom.resolve(context)
        if isinstance(for_whom, User):
            self.user = for_whom
            self.group = None
        elif isinstance(for_whom, AnonymousUser):
            self.user = User.get_anonymous()
            self.group = None
        elif isinstance(for_whom, Group):
            self.user = None
            self.group = for_whom
        else:
            raise NotUserNorGroup("User or Group instance required (got %s)" %
                                  for_whom.__class__)
        obj = self.obj.resolve(context)

        check = ObjectPermissionChecker(for_whom)
        perms = check.get_perms(obj)

        context[self.context_var] = perms
        return ''
Пример #26
0
    def list(self, request, *args, **kwargs):
        # Copy-paste of old implementation
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)

        # Add user permissions

        perms_checker = ObjectPermissionChecker(request.user)
        perms_checker.prefetch_perms(queryset)

        response_data = serializer.data

        for idx, obj in enumerate(queryset):
            response_data[idx]['permissions'] = perms_checker.get_perms(obj)

        return Response(response_data)
Пример #27
0
    def test_setannotationpermissions_removes_correct_permissions(
            self, AnnotationSet):
        admins_group = Group.objects.get(
            name=settings.RETINA_ADMINS_GROUP_NAME)
        graders_group = Group.objects.get(
            name=settings.RETINA_GRADERS_GROUP_NAME)
        AnnotationSet.grader.groups.add(graders_group)
        call_command("setannotationpermissions")

        call_command("setannotationpermissions", remove=True)

        checker = ObjectPermissionChecker(AnnotationSet.grader)
        group_perms = Permission.objects.filter(
            group=admins_group,
            content_type__app_label="annotations").values_list("codename",
                                                               flat=True)
        assert len(group_perms) == 0

        for annotation_model in ANNOTATION_MODELS:
            for annotation in annotation_model.objects.all():
                perms = checker.get_perms(annotation)
                assert len(perms) == 0
Пример #28
0
    def render(self, context):
        for_whom = self.for_whom.resolve(context)
        if isinstance(for_whom, get_user_model()):
            self.user = for_whom
            self.group = None
        elif isinstance(for_whom, AnonymousUser):
            self.user = get_user_model().get_anonymous()
            self.group = None
        elif isinstance(for_whom, Group):
            self.user = None
            self.group = for_whom
        else:
            raise NotUserNorGroup("User or Group instance required (got %s)"
                % for_whom.__class__)
        obj = self.obj.resolve(context)

        check = ObjectPermissionChecker(for_whom)
        perms = check.get_perms(obj)
        perms += [ap.split('.')[1] for ap in list(get_uog_permissions(self.user, obj))]

        context[self.context_var] = perms
        return ''
Пример #29
0
    def test_setannotationpermissions_sets_correct_permissions(
            self, AnnotationSet):
        admins_group = Group.objects.get(
            name=settings.RETINA_ADMINS_GROUP_NAME)
        graders_group = Group.objects.get(
            name=settings.RETINA_GRADERS_GROUP_NAME)
        AnnotationSet.grader.groups.add(graders_group)
        call_command("setannotationpermissions")

        checker = ObjectPermissionChecker(AnnotationSet.grader)
        group_perms = Permission.objects.filter(
            group=admins_group).values_list("codename", flat=True)

        for annotation_model in ANNOTATION_MODELS:
            annotation_codename = annotation_model._meta.model_name
            for annotation in annotation_model.objects.all():
                perms = checker.get_perms(annotation)
                for permission_type in annotation._meta.default_permissions:
                    assert f"{permission_type}_{annotation_codename}" in perms

                for permission_type in annotation._meta.default_permissions:
                    assert (f"{permission_type}_{annotation_codename}"
                            in group_perms)
Пример #30
0
    def test_setannotationpermissions_removes_correct_permissions(
        self, AnnotationSet
    ):
        admins_group = Group.objects.get(
            name=settings.RETINA_ADMINS_GROUP_NAME
        )
        graders_group = Group.objects.get(
            name=settings.RETINA_GRADERS_GROUP_NAME
        )
        AnnotationSet.grader.groups.add(graders_group)
        call_command("setannotationpermissions")

        call_command("setannotationpermissions", remove=True)

        checker = ObjectPermissionChecker(AnnotationSet.grader)
        group_perms = Permission.objects.filter(
            group=admins_group, content_type__app_label="annotations"
        ).values_list("codename", flat=True)
        assert len(group_perms) == 0

        for annotation_model in ANNOTATION_MODELS:
            for annotation in annotation_model.objects.all():
                perms = checker.get_perms(annotation)
                assert len(perms) == 0
Пример #31
0
def sync_config_entity_group_permissions(obj,
                                         config_entity_groups,
                                         permission_lookup,
                                         permission_key_class=PermissionKey,
                                         **kwargs):
    """
        Syncs ConfigEntity Group permissions for a ConfigEntity or DbEntity
        All superior Groups will also receive permissions. Superior groups to a ConfigEntity Group
        are the ConfigEntity Group of the parent ConfigEntity (if one exists) and the global Group
        to which the ConfigEntity Group corresponds. For instance, for a Project ConfigEntity Group,
        the superiors are the parent Region ConfigEntity Group and the UserGroupKey.MANAGER group (the
        global Group used for Projects)
    :param obj: A ConfigEntity or DbEntity
    :param config_entity_groups: ConfigEntity Groups
    :param permission_lookup, a mapping of user groups to PermissionKeys. When giving permission to
    a ConfigEntity group, this lookup will be consulted. The user group that closest matches the
    ConfigEntity group will be used. Only a direct match or global version will be accepted. For instance
    if the ConfigEntity group is a User ConfigEntity group, then group in the permission_lookup must
    be the same group or the global UserGroupKey.USER group
    :param permission_key_class: Default PermissionKey. Specify a PermissionKey subclass when the obj class
    defines extra permissions. (This is only needed to resolve keys that map to multiple permissions)
    :param kwargs:
    :return:
    """
    def _resolve_permission(group, permission_lookup):
        """
            Matches the group to a key in the permission_lookup.
            The group name and it's immediate superiors will be checked for a match,
            but only superiors that are global Groups. It's unlikely that we'd
            have a permission_lookup specific to a ConfigEntity Group. They will normally
            contain only global groups (UserGroupKey.SUPERADMIN, UserGroupKey.USER, etc)
        :param group: The group to test
        :param permission_lookup: keyed by group names, valued by a PermissionKey strings
        :return:
        """

        # Get the global superior, which exists except for ADMIN
        global_superior = GroupHierarchy.objects.get(
            group=group).superiors.get(
                name__in=UserGroupKey.GLOBAL
            ) if group.name != UserGroupKey.SUPERADMIN else None
        # See if we have a permission matching the group or global superior
        for check_group in [group
                            ] + ([global_superior] if global_superior else []):
            if permission_lookup.get(check_group.name):
                return permission_lookup[check_group.name]
        # No match, no problem. Recurse on the next Global group or its subordinate
        subordinates = filter(
            lambda subordinate: subordinate.group.name in UserGroupKey.GLOBAL,
            (group if group.name in UserGroupKey.GLOBAL else
             global_superior).subordinates.all())
        if len(subordinates) == 1:
            return _resolve_permission(subordinates[0].group,
                                       permission_lookup)
        else:
            raise Exception(
                "For group {group_name} no permission in permission_lookup matches: {permission_lookup} \
                and not exactly one global subordinate exists: {subordinates}".
                format(group_name=group.name,
                       permission_lookup=permission_lookup,
                       subordinates=subordinates))

    # Sync ConfigEntity groups permissions
    # Give full permission to the ConfigEntity Group(s) to access this object
    # TODO this might change in the future if we define subordinate ConfigEntity Groups on the object
    config_entity_group_permissions = map_to_dict(
        lambda group:
        [group.name, _resolve_permission(group, permission_lookup)],
        config_entity_groups)
    obj.sync_permissions(
        additional_permissions=config_entity_group_permissions,
        permission_key_class=permission_key_class,
        superior_permission_lookup=permission_lookup)

    # TODO this is for debugging/logging. It can be commented out
    for group_name, permission_key in config_entity_group_permissions.items():
        logger.info(
            "User Publishing. For %s %s gave %s permission(s) to ConfigEntity UserGroup: %s"
            % (obj.__class__.__name__, obj.name, permission_key, group_name))
        for class_permission_key in permission_key_class.permission_keys(
                permission_key, obj.__class__):
            perm_checker = ObjectPermissionChecker(
                Group.objects.get(name=group_name))
            assert perm_checker.has_perm(class_permission_key, obj), \
                "No permission for Group %s, Permission %s, ConfigEntity %s. It has permissions %s" % \
                (group_name, class_permission_key, obj.name, perm_checker.get_perms(obj))

    return config_entity_group_permissions
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        profile_user = context["object"].user
        profile_groups = profile_user.groups.all()

        organizations = Organization.objects.filter(
            Q(members_group__in=profile_groups)
            | Q(editors_group__in=profile_groups)).distinct()

        archives = (get_objects_for_user(
            user=self.request.user,
            perms="view_archive",
            klass=Archive,
            use_groups=True,
        ).filter(
            Q(editors_group__in=profile_groups)
            | Q(uploaders_group__in=profile_groups)
            | Q(users_group__in=profile_groups)).distinct())
        reader_studies = (get_objects_for_user(
            user=self.request.user,
            perms="view_readerstudy",
            klass=ReaderStudy,
            use_groups=True,
        ).filter(
            Q(editors_group__in=profile_groups)
            | Q(readers_group__in=profile_groups)).distinct())
        challenges = Challenge.objects.filter(
            Q(admins_group__in=profile_groups)
            | Q(participants_group__in=profile_groups),
            hidden=False,
        ).distinct()
        algorithms = (get_objects_for_user(
            user=self.request.user,
            perms="view_algorithm",
            klass=Algorithm,
            use_groups=True,
        ).filter(
            Q(editors_group__in=profile_groups)
            | Q(users_group__in=profile_groups)).distinct())

        checker = ObjectPermissionChecker(user_or_group=profile_user)
        for qs in [
                archives,
                reader_studies,
                challenges,
                algorithms,
        ]:
            # Perms can only be prefetched for sets of the same objects
            checker.prefetch_perms(objects=qs)

        object_list = [
            *archives,
            *reader_studies,
            *challenges,
            *algorithms,
        ]

        role = {}
        for obj in object_list:
            obj_perms = checker.get_perms(obj)
            if f"change_{obj._meta.model_name}" in obj_perms:
                role[obj] = "editor"
            elif f"view_{obj._meta.model_name}" in obj_perms:
                role[obj] = "user"
            else:
                role[obj] = "participant"

        context.update({
            "object_list":
            object_list,
            "object_role":
            role,
            "num_submissions":
            Submission.objects.filter(creator=profile_user).count(),
            "num_algorithms_run":
            Job.objects.filter(creator=profile_user).count(),
            "organizations":
            organizations,
        })

        return context
Пример #33
0
 def test_anonymous_user(self):
     user = AnonymousUser()
     check = ObjectPermissionChecker(user)
     # assert anonymous user has no object permissions at all for obj
     self.assertTrue([] == list(check.get_perms(self.ctype)))
Пример #34
0
def get_all_permissions(user, object_list):
    checker = ObjectPermissionChecker(user)
    checker.prefetch_perms(object_list)
    return {obj.pk: checker.get_perms(obj) for obj in object_list}
Пример #35
0
 def test_anonymous_user(self):
     user = AnonymousUser()
     check = ObjectPermissionChecker(user)
     # assert anonymous user has no object permissions at all for obj
     self.assertTrue( [] == list(check.get_perms(self.ctype)) )
Пример #36
0
def sync_config_entity_group_permissions(obj, config_entity_groups, permission_lookup, permission_key_class=PermissionKey, **kwargs):
    """
        Syncs ConfigEntity Group permissions for a ConfigEntity or DbEntity
        All superior Groups will also receive permissions. Superior groups to a ConfigEntity Group
        are the ConfigEntity Group of the parent ConfigEntity (if one exists) and the global Group
        to which the ConfigEntity Group corresponds. For instance, for a Project ConfigEntity Group,
        the superiors are the parent Region ConfigEntity Group and the UserGroupKey.MANAGER group (the
        global Group used for Projects)
    :param obj: A ConfigEntity or DbEntity
    :param config_entity_groups: ConfigEntity Groups
    :param permission_lookup, a mapping of user groups to PermissionKeys. When giving permission to
    a ConfigEntity group, this lookup will be consulted. The user group that closest matches the
    ConfigEntity group will be used. Only a direct match or global version will be accepted. For instance
    if the ConfigEntity group is a User ConfigEntity group, then group in the permission_lookup must
    be the same group or the global UserGroupKey.USER group
    :param permission_key_class: Default PermissionKey. Specify a PermissionKey subclass when the obj class
    defines extra permissions. (This is only needed to resolve keys that map to multiple permissions)
    :param kwargs:
    :return:
    """

    def _resolve_permission(group, permission_lookup):
        """
            Matches the group to a key in the permission_lookup.
            The group name and it's immediate superiors will be checked for a match,
            but only superiors that are global Groups. It's unlikely that we'd
            have a permission_lookup specific to a ConfigEntity Group. They will normally
            contain only global groups (UserGroupKey.SUPERADMIN, UserGroupKey.USER, etc)
        :param group: The group to test
        :param permission_lookup: keyed by group names, valued by a PermissionKey strings
        :return:
        """

        # Get the global superior, which exists except for ADMIN
        global_superior = GroupHierarchy.objects.get(group=group).superiors.get(
            name__in=UserGroupKey.GLOBAL
        ) if group.name != UserGroupKey.SUPERADMIN else None
        # See if we have a permission matching the group or global superior
        for check_group in [group] + ([global_superior] if global_superior else []):
            if permission_lookup.get(check_group.name):
                return permission_lookup[check_group.name]
        # No match, no problem. Recurse on the next Global group or its subordinate
        subordinates = filter(
            lambda subordinate: subordinate.group.name in UserGroupKey.GLOBAL,
            (group if group.name in UserGroupKey.GLOBAL else global_superior).subordinates.all())
        if len(subordinates) == 1:
            return _resolve_permission(subordinates[0].group, permission_lookup)
        else:
            raise Exception(
                "For group {group_name} no permission in permission_lookup matches: {permission_lookup} \
                and not exactly one global subordinate exists: {subordinates}".format(
                    group_name=group.name,
                    permission_lookup=permission_lookup,
                    subordinates=subordinates
                )
            )

    # Sync ConfigEntity groups permissions
    # Give full permission to the ConfigEntity Group(s) to access this object
    # TODO this might change in the future if we define subordinate ConfigEntity Groups on the object
    config_entity_group_permissions = map_to_dict(
        lambda group: [group.name, _resolve_permission(group, permission_lookup)],
        config_entity_groups)
    obj.sync_permissions(
        additional_permissions=config_entity_group_permissions,
        permission_key_class=permission_key_class,
        superior_permission_lookup=permission_lookup
    )

    # TODO this is for debugging/logging. It can be commented out
    for group_name, permission_key in config_entity_group_permissions.items():
        logger.info("User Publishing. For %s %s gave %s permission(s) to ConfigEntity UserGroup: %s" %
                    (obj.__class__.__name__, obj.name, permission_key, group_name))
        for class_permission_key in permission_key_class.permission_keys(permission_key, obj.__class__):
            perm_checker = ObjectPermissionChecker(Group.objects.get(name=group_name))
            assert perm_checker.has_perm(class_permission_key, obj), \
                "No permission for Group %s, Permission %s, ConfigEntity %s. It has permissions %s" % \
                (group_name, class_permission_key, obj.name, perm_checker.get_perms(obj))

    return config_entity_group_permissions
Пример #37
0
class SlugObjectsMixin:
    """
    A mixin to get objects from url slugs.
    Also adds breadcrumbs based on the objects we have and the view we are in.
    """
    def setup(self, *args, **kwargs):
        # super setup() so we have self.request available
        super().setup(*args, **kwargs)

        # add a checker we can use to cache permissions for objects
        self.checker = ObjectPermissionChecker(self.request.user)

        # start out with an almost empty context_data dict
        self.context_data = {"checker": self.checker}

        # do we have a team?
        if "team_slug" in kwargs:
            self.team = get_object_or_404(Team, slug=kwargs["team_slug"])
            self.checker.prefetch_perms([self.team])
            if not self.checker.has_perm("team.view_team", self.team):
                raise PermissionDenied
            self.url_namespace_prefixes = ["team"]
            self.add_breadcrumbs(self.team)
            self.url_kwargs = {"team_slug": self.team.slug}
            self.object_kwargs = {"team": self.team}
            self.context_data["team"] = self.team
            self.context_data["team_perms"] = self.checker.get_perms(self.team)
            self.gfk_object = self.team

            # do we have a context?
            if "context_slug" in kwargs:
                self.context = get_object_or_404(
                    Context, team=self.team, slug=self.kwargs["context_slug"])
                self.checker.prefetch_perms([self.context])
                if not self.checker.has_perm("context.view_context",
                                             self.context):
                    raise PermissionDenied
                self.url_namespace_prefixes.append("context")
                self.add_breadcrumbs(self.context)
                self.url_kwargs["context_slug"] = self.context.slug
                self.context_data["context"] = self.context
                self.context_data["context_perms"] = self.checker.get_perms(
                    self.context)
                self.gfk_object = self.context

            # do we have a category?
            if "category_slug" in kwargs:
                self.category = get_object_or_404(
                    Category,
                    team=self.team,
                    slug=self.kwargs["category_slug"])
                self.checker.prefetch_perms([self.category])
                if not self.checker.has_perm("category.view_category",
                                             self.category):
                    raise PermissionDenied
                self.url_namespace_prefixes.append("category")
                self.add_breadcrumbs(self.category)
                self.url_kwargs["category_slug"] = self.category.slug
                self.context_data["category"] = self.category
                self.context_data["category_perms"] = self.checker.get_perms(
                    self.category)
                self.gfk_object = self.category

                # do we have a fact?
                if "fact_slug" in kwargs:
                    self.fact = get_object_or_404(
                        Fact,
                        category=self.category,
                        slug=self.kwargs["fact_slug"])
                    self.checker.prefetch_perms([self.fact])
                    if not self.checker.has_perm("fact.view_fact", self.fact):
                        raise PermissionDenied
                    self.url_namespace_prefixes.append("fact")
                    self.add_breadcrumbs(self.fact)
                    self.context_data["fact"] = self.fact
                    self.context_data["fact_perms"] = self.checker.get_perms(
                        self.fact)
                    self.gfk_object = self.fact

                # do we have a rating?
                elif "rating_slug" in kwargs:
                    self.rating = get_object_or_404(
                        Rating,
                        category=self.category,
                        slug=self.kwargs["rating_slug"])
                    self.checker.prefetch_perms([self.rating])
                    if not self.checker.has_perm("rating.view_rating",
                                                 self.rating):
                        raise PermissionDenied
                    self.url_namespace_prefixes.append("rating")
                    self.add_breadcrumbs(self.rating)
                    self.context_data["rating"] = self.rating
                    self.context_data["rating_perms"] = self.checker.get_perms(
                        self.rating)
                    self.gfk_object = self.rating

                # do we have an item?
                elif "item_slug" in kwargs:
                    self.item = get_object_or_404(
                        Item,
                        category=self.category,
                        slug=self.kwargs["item_slug"])
                    self.checker.prefetch_perms([self.item])
                    if not self.checker.has_perm("item.view_item", self.item):
                        raise PermissionDenied
                    self.url_namespace_prefixes.append("item")
                    self.add_breadcrumbs(self.item)
                    self.url_kwargs["item_slug"] = self.item.slug
                    self.context_data["item"] = self.item
                    self.context_data["item_perms"] = self.checker.get_perms(
                        self.item)
                    self.gfk_object = self.item

                    # do we have a review?
                    if "review_uuid" in kwargs:
                        self.review = get_object_or_404(
                            Review,
                            item=self.item,
                            uuid=self.kwargs["review_uuid"])
                        self.checker.prefetch_perms([self.review])
                        if not self.checker.has_perm("review.view_review",
                                                     self.review):
                            raise PermissionDenied
                        self.url_namespace_prefixes.append("review")
                        self.add_breadcrumbs(self.review)
                        self.url_kwargs["review_uuid"] = self.review.uuid
                        self.context_data["review"] = self.review
                        self.context_data[
                            "review_perms"] = self.checker.get_perms(
                                self.review)
                        self.gfk_object = self.review

                        # do we have a vote?
                        if "vote_uuid" in kwargs:
                            # get the vote
                            self.vote = get_object_or_404(
                                Vote,
                                review=self.review,
                                uuid=self.kwargs["vote_uuid"])
                            self.checker.prefetch_perms([self.vote])
                            if not self.checker.has_perm(
                                    "vote.view_vote", self.vote):
                                raise PermissionDenied
                            self.url_namespace_prefixes.append("vote")
                            self.add_breadcrumbs(self.vote)
                            self.url_kwargs["vote_uuid"] = self.vote.uuid
                            self.context_data["vote"] = self.vote
                            self.context_data[
                                "vote_perms"] = self.checker.get_perms(
                                    self.vote)
                            self.gfk_object = self.vote

            # do we have a forum?
            if "forum_slug" in kwargs:
                self.forum = get_object_or_404(Forum,
                                               team=self.team,
                                               slug=self.kwargs["forum_slug"])
                self.checker.prefetch_perms([self.forum])
                if not self.checker.has_perm("forum.view_forum", self.forum):
                    raise PermissionDenied
                self.url_namespace_prefixes.append("forum")
                self.add_breadcrumbs(self.forum)
                self.url_kwargs["forum_slug"] = self.forum.slug
                self.context_data["forum"] = self.forum
                self.context_data["forum_perms"] = self.checker.get_perms(
                    self.forum)
                self.gfk_object = self.forum

                # do we have a thread?
                if "thread_slug" in kwargs:
                    self.thread = get_object_or_404(
                        Thread,
                        forum=self.forum,
                        slug=self.kwargs["thread_slug"])
                    self.checker.prefetch_perms([self.thread])
                    if not self.checker.has_perm("thread.view_thread",
                                                 self.thread):
                        raise PermissionDenied
                    self.url_namespace_prefixes.append("thread")
                    self.add_breadcrumbs(self.thread)
                    self.url_kwargs["thread_slug"] = self.thread.slug
                    self.context_data["thread"] = self.thread
                    self.context_data["thread_perms"] = self.checker.get_perms(
                        self.thread)
                    self.gfk_object = self.thread

        # do we have a comment? (GFK object outside normal hierachy)
        if "comment_uuid" in kwargs:
            self.comment = get_object_or_404(
                Comment,
                uuid=self.kwargs["comment_uuid"],
                object_id=self.gfk_object.pk,
                content_type=ContentType.objects.get_for_model(
                    self.gfk_object),
            )
            self.checker.prefetch_perms([self.comment])
            if not self.checker.has_perm("comment.view_comment", self.comment):
                raise PermissionDenied
            self.url_namespace_prefixes.append("comment")
            self.add_breadcrumbs(self.comment)
            self.url_kwargs["comment_uuid"] = self.comment.uuid
            self.context_data["comment"] = self.comment
            self.context_data["comment_perms"] = self.checker.get_perms(
                self.comment)
            self.gfk_object = self.comment

        # do we have an attachment? (GFK object outside normal hierachy)
        if "attachment_uuid" in kwargs:
            self.attachment = get_object_or_404(
                Attachment,
                uuid=self.kwargs["attachment_uuid"],
                object_id=self.gfk_object.pk,
                content_type=ContentType.objects.get_for_model(
                    self.gfk_object),
            )
            self.checker.prefetch_perms([self.attachment])
            if not self.checker.has_perm("attachment.view_attachment",
                                         self.attachment):
                raise PermissionDenied
            self.url_namespace_prefixes.append("attachment")
            self.add_breadcrumbs(self.attachment)
            self.url_kwargs["attachment_uuid"] = self.attachment.uuid
            self.context_data["attachment"] = self.attachment
            self.context_data["attachment_perms"] = self.checker.get_perms(
                self.attachment)
            self.gfk_object = self.attachment

        # do we have an event? (GFK object outside normal hierachy)
        if "event_uuid" in kwargs:
            self.event = get_object_or_404(
                Event,
                uuid=self.kwargs["event_uuid"],
                object_id=self.gfk_object.pk,
                content_type=ContentType.objects.get_for_model(
                    self.gfk_object),
            )
            self.checker.prefetch_perms([self.event])
            if not self.checker.has_perm("event.view_event", self.event):
                raise PermissionDenied
            self.url_namespace_prefixes.append("event")
            self.add_breadcrumbs(self.event)
            self.url_kwargs["event_uuid"] = self.event.uuid
            self.context_data["event"] = self.event
            self.context_data["event_perms"] = self.checker.get_perms(
                self.event)

        # finally add any missing action breadcrumbs,
        # but if this is a CreateView add a link to the ListView first
        if self.request.resolver_match.url_name == "create":
            self.add_listview_breadcrumb()
        # add action breadcrumb
        self.add_action_breadcrumb()

    def get_context_data(self, **kwargs):
        """
        Add Team and related objects and permissions to context
        """
        context = super().get_context_data(**kwargs)
        context.update(self.context_data)
        return context