Exemple #1
0
def get_permitted_minutes(minutes, request, groupid):
	groupid = int(groupid)
	try:
		group = Group.objects.get(id=groupid)
	except ObjectDoesNotExist:
		raise Http404

	own_group = request.user.is_superuser or group in request.user.groups.all()

	# Prefetch group permissions
	group_checker = ObjectPermissionChecker(group)
	group_checker.prefetch_perms(minutes)

	# Prefetch user permissions
	user_checker = ObjectPermissionChecker(request.user)
	user_checker.prefetch_perms(minutes)

	# Prefetch ip group permissions
	ip_range_group_name = request.user._ip_range_group_name if hasattr(request.user, '_ip_range_group_name') else None
	if ip_range_group_name:
		ip_range_group = Group.objects.get(name=ip_range_group_name)
		ip_range_group_checker = ObjectPermissionChecker(ip_range_group)

	permitted_minutes = []
	for m in minutes:
		# we show all documents for which the requested group has edit permissions
		# e.g. if you request FSR minutes, all minutes for which the FSR group has edit rights will be shown
		if not group_checker.has_perm(m.edit_permission_name, m):
			continue
		# we only show documents for which the user has view permissions
		if not user_checker.has_perm(MinutesDocument.get_view_permission(), m) and (not ip_range_group_name or not ip_range_group_checker.has_perm(MinutesDocument.get_view_permission(), m)):
			continue
		permitted_minutes.append(m)

	return permitted_minutes, own_group
Exemple #2
0
def document_permission_overview(user, document):
	can_edit = user.has_perm(document.edit_permission_name, document)
	if not can_edit:
		return []

	main_groups = [
		settings.ANONYMOUS_GROUP_NAME,
		settings.UNIVERSITY_GROUP_NAME,
		settings.STUDENT_GROUP_NAME,
		settings.STAFF_GROUP_NAME,
	]
	permissions = []
	for group_name in main_groups:
		group = Group.objects.get(name=group_name)
		checker = ObjectPermissionChecker(group)
		checker.prefetch_perms([document])
		if checker.has_perm(document.edit_permission_name, document):
			permissions.append((group.name, "edit"))
		elif checker.has_perm(document.view_permission_name, document):
			permissions.append((group.name, "view"))
		else:
			permissions.append((group.name, "none"))

	for group in Group.objects.exclude(name__in=main_groups):
		checker = ObjectPermissionChecker(group)
		checker.prefetch_perms([document])
		if checker.has_perm(document.edit_permission_name, document):
			permissions.append((group.name, "edit"))
		elif checker.has_perm(document.view_permission_name, document):
			permissions.append((group.name, "view"))

	return permissions
    def bulk_assign_perm(self, perm, user_or_group, queryset):
        """
        Bulk assigns permissions with given ``perm`` for an objects in ``queryset`` and
        ``user_or_group``.
        """

        ctype = get_content_type(queryset.model)
        if not isinstance(perm, Permission):
            permission = Permission.objects.get(content_type=ctype, codename=perm)
        else:
            permission = perm

        checker = ObjectPermissionChecker(user_or_group)
        checker.prefetch_perms(queryset)

        assigned_perms = []
        for instance in queryset:
            if not checker.has_perm(permission.codename, instance):
                kwargs = {'permission': permission, self.user_or_group_field: user_or_group}
                if self.is_generic():
                    kwargs['content_type'] = ctype
                    kwargs['object_pk'] = instance.pk
                else:
                    kwargs['content_object'] = instance
                assigned_perms.append(self.model(**kwargs))
        self.model.objects.bulk_create(assigned_perms)

        return assigned_perms
    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
Exemple #5
0
def terminator_profile_detail(request, username):
    user = get_object_or_404(User, username=username)
    cil_ctype = ContentType.objects.get_for_model(ConceptInLanguage)
    user_comments = Comment.objects.filter(
        user=user,
        content_type=cil_ctype,
        is_public=True,
        is_removed=False,
    ).order_by('-submit_date')
    paginator = Paginator(user_comments, 10)
    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1
    # If page request (9999) is out of range, deliver last page of results.
    try:
        comments = paginator.page(page)
    except (EmptyPage, InvalidPage):
        comments = paginator.page(paginator.num_pages)
    prefetch_related_objects(
        comments.object_list,
        'content_object__concept',
        'content_object__concept__glossary',
    )
    glossary_list = list(Glossary.objects.all())
    user_glossaries = []
    checker = ObjectPermissionChecker(user)
    checker.prefetch_perms(glossary_list)
    for glossary in glossary_list:
        if checker.has_perm('owner', glossary):
            user_glossaries.append({'glossary': glossary, 'role': _(u"owner")})
        elif checker.has_perm('terminologist', glossary):
            user_glossaries.append({
                'glossary': glossary,
                'role': _(u"terminologist")
            })
        elif checker.has_perm('specialist', glossary):
            user_glossaries.append({
                'glossary': glossary,
                'role': _(u"specialist")
            })

    ctypes = ContentType.objects.get_for_models(Translation, Definition,
                                                ExternalResource).values()
    recent_changes = process_recent_changes(
        LogEntry.objects.filter(
            content_type__in=ctypes,
            user=user,
        ).order_by("-action_time")[:10])

    context = {
        'thisuser': user,
        'glossaries': user_glossaries,
        'comments': comments,
        'search_form': SearchForm(),
        'next': request.get_full_path(),
        'recent_changes': recent_changes,
    }
    return render(request, "profiles/profile_detail.html", context)
Exemple #6
0
def document_permission_overview(user, document):
    can_edit = user.has_perm(document.edit_permission_name, document)
    if not can_edit:
        return []

    main_groups = [
        settings.ANONYMOUS_GROUP_NAME,
        settings.UNIVERSITY_GROUP_NAME,
        settings.STUDENT_GROUP_NAME,
        settings.STAFF_GROUP_NAME,
    ]
    permissions = []
    for group_name in main_groups:
        group = Group.objects.get(name=group_name)
        checker = ObjectPermissionChecker(group)
        checker.prefetch_perms([document])
        if checker.has_perm(document.edit_permission_name, document):
            permissions.append((group.name, "edit"))
        elif checker.has_perm(document.view_permission_name, document):
            permissions.append((group.name, "view"))
        else:
            permissions.append((group.name, "none"))

    for group in Group.objects.exclude(name__in=main_groups):
        checker = ObjectPermissionChecker(group)
        checker.prefetch_perms([document])
        if checker.has_perm(document.edit_permission_name, document):
            permissions.append((group.name, "edit"))
        elif checker.has_perm(document.view_permission_name, document):
            permissions.append((group.name, "view"))

    return permissions
Exemple #7
0
    def bulk_assign_perm(self, perm, user_or_group, queryset):
        """
        Bulk assigns permissions with given ``perm`` for an objects in ``queryset`` and
        ``user_or_group``.
        """

        ctype = get_content_type(queryset.model)
        if not isinstance(perm, Permission):
            permission = Permission.objects.get(content_type=ctype, codename=perm)
        else:
            permission = perm

        checker = ObjectPermissionChecker(user_or_group)
        checker.prefetch_perms(queryset)

        assigned_perms = []
        for instance in queryset:
            if not checker.has_perm(permission.codename, instance):
                kwargs = {'permission': permission, self.user_or_group_field: user_or_group}
                if self.is_generic():
                    kwargs['content_type'] = ctype
                    kwargs['object_pk'] = instance.pk
                else:
                    kwargs['content_object'] = instance
                assigned_perms.append(self.model(**kwargs))
        self.model.objects.bulk_create(assigned_perms)

        return assigned_perms
def get_classes(user: "******"):
    """Get the classes whose timetables are allowed to be seen by current user."""
    checker = ObjectPermissionChecker(user)

    classes = (Group.objects.for_current_school_term_or_all().annotate(
        lessons_count=Count("lessons"),
        child_lessons_count=Count("child_groups__lessons"),
    ).filter(
        Q(lessons_count__gt=0, parent_groups=None)
        | Q(child_lessons_count__gt=0, parent_groups=None)).order_by(
            "short_name", "name"))

    if not check_global_permission(user, "chronos.view_all_group_timetables"):
        checker.prefetch_perms(classes)

        wanted_classes = set()

        for _class in classes:
            if checker.has_perm("core.view_group_timetable", _class):
                wanted_classes.add(_class.pk)

        classes = classes.filter(
            Q(pk__in=wanted_classes) | Q(members=user.person)
            | Q(owners=user.person))
        if user.person.primary_group:
            classes = classes.filter(Q(pk=user.person.primary_group.pk))

    return classes
    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
Exemple #10
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
Exemple #11
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
Exemple #12
0
 def get_serializer_context(self):
     context = super().get_serializer_context()
     queryset = self.get_queryset()
     if queryset:
         prefetched_permission_checker = ObjectPermissionChecker(self.request.user)
         prefetched_permission_checker.prefetch_perms(queryset)
         context['prefetched_permission_checker'] = prefetched_permission_checker
     return context
Exemple #13
0
def get_last_minutes_document_for_group(group):
    minutes = MinutesDocument.objects.all().order_by('-date')
    group_checker = ObjectPermissionChecker(group)
    group_checker.prefetch_perms(minutes)

    for m in minutes:
        if group_checker.has_perm(m.edit_permission_name, m):
            return m

    return None
Exemple #14
0
def get_last_minutes_document_for_group(group):
	minutes = MinutesDocument.objects.all().order_by('-date')
	group_checker = ObjectPermissionChecker(group)
	group_checker.prefetch_perms(minutes)

	for m in minutes:
		if group_checker.has_perm(m.edit_permission_name, m):
			return m

	return None
Exemple #15
0
 def get_queryset_for_customer(self):
     created_time = self.request.query_params.get('created_time', None)
     if created_time:
         self.kwargs['created_time__contains'] = created_time
     queryset = Order.objects.filter(**self.kwargs)
     checker = ObjectPermissionChecker(self.request.user)
     checker.prefetch_perms(queryset)
     return [
         query for query in queryset
         if checker.has_perm('app.view_order', query)
     ]
Exemple #16
0
class UnitAuthorizationFormSet(forms.BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)
        self.permission_checker = ObjectPermissionChecker(kwargs['instance'])
        self.permission_checker.prefetch_perms(
            Unit.objects.filter(authorizations__authorized=kwargs['instance']))

    def get_form_kwargs(self, index):
        kwargs = super().get_form_kwargs(index)
        kwargs['permission_checker'] = self.permission_checker
        kwargs['request'] = self.request
        return kwargs
Exemple #17
0
    def _preload_permissions(self):
        units = set()
        resource_groups = set()
        checker = ObjectPermissionChecker(self.request.user)
        for res in self._page:
            units.add(res.unit)
            for g in res.groups.all():
                resource_groups.add(g)
            res._permission_checker = checker

        if units:
            checker.prefetch_perms(units)
        if resource_groups:
            checker.prefetch_perms(resource_groups)
Exemple #18
0
    def _preload_permissions(self):
        units = set()
        resource_groups = set()
        checker = ObjectPermissionChecker(self.request.user)
        for res in self._page:
            units.add(res.unit)
            for g in res.groups.all():
                resource_groups.add(g)
            res._permission_checker = checker

        if units:
            checker.prefetch_perms(units)
        if resource_groups:
            checker.prefetch_perms(resource_groups)
Exemple #19
0
def create_permission_checker(model_or_manager, user):
    """
    Create an :class:`ObjectPermissionChecker` for optimal permission checking
    of related objects.

    http://django-guardian.readthedocs.io/en/stable/userguide/performance.html
    """
    model, manager = model_and_manager(model_or_manager)
    checker = ObjectPermissionChecker(user)
    try:
        checker.prefetch_perms(manager)
    except UnboundLocalError:
        logger.exception(
            "https://github.com/django-guardian/django-guardian/issues/519")
    return checker
Exemple #20
0
    def __init__(self, request: HttpRequest, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Disable non-editable fields
        person_fields = set([field.name for field in Person.syncable_fields()
                             ]).intersection(set(self.fields))

        if self.instance:
            checker = ObjectPermissionChecker(request.user)
            checker.prefetch_perms([self.instance])

            for field in person_fields:
                if not checker.has_perm(f"core.change_person_field_{field}",
                                        self.instance):
                    self.fields[field].disabled = True
    def test_prefetch_group_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            new_group = Group.objects.create(name='new-group')
            assign_perm("change_group", new_group, self.group)
            assign_perm("change_group", new_group, new_group)
            checker = ObjectPermissionChecker(new_group)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms([self.group, new_group]))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), 2)

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", new_group)
            self.assertEqual(len(connection.queries), query_count)

        finally:
            settings.DEBUG = False
Exemple #22
0
    def test_prefetch_group_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            new_group = Group.objects.create(name='new-group')
            assign_perm("change_group", new_group, self.group)
            assign_perm("change_group", new_group, new_group)
            checker = ObjectPermissionChecker(new_group)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms([self.group, new_group]))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), 2)

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", new_group)
            self.assertEqual(len(connection.queries), query_count)

        finally:
            settings.DEBUG = False
Exemple #23
0
    def test_checker(self):
        GroupObjectPermission.objects.assign_perm("delete_contenttype", self.group,
                                                          self.ctype)

        checker = ObjectPermissionChecker(self.user)
        checker.prefetch_perms(Group.objects.all())
                
        template = ''.join((
            '{% load guardian_tags %}',
            '{% get_obj_perms group for contenttype as "obj_perms" checker %}',
            '{{ obj_perms|join:" " }}',
        ))
        context = {'group': self.group, 'contenttype': self.ctype, 'checker': checker}
        output = render(template, context)

        self.assertEqual(output, 'delete_contenttype')
Exemple #24
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
Exemple #25
0
def list(request, groupid):
    groupid = int(groupid)
    try:
        group = Group.objects.get(id=groupid)
    except ObjectDoesNotExist:
        raise Http404
    result = {}

    own_group = request.user.is_superuser or group in request.user.groups.all()
    minutes = MinutesDocument.objects.all().prefetch_related(
        'labels').order_by('-date')
    # Prefetch group permissions
    group_checker = ObjectPermissionChecker(group)
    group_checker.prefetch_perms(minutes)

    # Prefetch user permissions
    user_checker = ObjectPermissionChecker(request.user)
    user_checker.prefetch_perms(minutes)

    # Prefetch ip group permissions
    ip_range_group_name = request.user._ip_range_group_name if hasattr(
        request.user, '_ip_range_group_name') else None
    if ip_range_group_name:
        ip_range_group = Group.objects.get(name=ip_range_group_name)
        ip_range_group_checker = ObjectPermissionChecker(ip_range_group)

    for m in minutes:
        # we show all documents for which the requested group has edit permissions
        # e.g. if you request FSR minutes, all minutes for which the FSR group has edit rights will be shown
        if not group_checker.has_perm(m.edit_permission_name, m):
            continue
        # we only show documents for which the user has view permissions
        if not user_checker.has_perm(
                MinutesDocument.get_view_permission(),
                m) and (not ip_range_group_name
                        or not ip_range_group_checker.has_perm(
                            MinutesDocument.get_view_permission(), m)):
            continue
        if m.date.year not in result:
            result[m.date.year] = []
        result[m.date.year].append(m)
    return render(
        request, "minutes_list.html", {
            'minutes_list': sorted(result.items(), reverse=True),
            'own_group': own_group
        })
def get_rooms(user: "******"):
    """Get the rooms whose timetables are allowed to be seen by current user."""
    checker = ObjectPermissionChecker(user)

    rooms = (Room.objects.annotate(
        lessons_count=Count("lesson_periods")).filter(
            lessons_count__gt=0).order_by("short_name", "name"))

    if not check_global_permission(user, "chronos.view_all_room_timetables"):
        checker.prefetch_perms(rooms)

        wanted_rooms = set()

        for room in rooms:
            if checker.has_perm("chronos.view_room_timetable", room):
                wanted_rooms.add(room.pk)

        rooms = rooms.filter(Q(pk__in=wanted_rooms))

    return rooms
Exemple #27
0
def user_dashboard(request):
    joe = User.objects.get(username='******')
    post = Post.objects.get(id=1)
    # print(joe.has_perm('post_add', post))
    assign_perm('post_add', joe, post)
    projects = get_objects_for_user(request.user, 'ecommer.post_add')

    from guardian.core import ObjectPermissionChecker
    joe = User.objects.get(username='******')
    projects = Post.objects.all()
    checker = ObjectPermissionChecker(joe)
    # Prefetch the permissions
    checker.prefetch_perms(projects)
    for project in projects:
        # No additional lookups needed to check permissions
        print(checker.has_perm('post_add', project))



    return render(request, 'ecommer/user_dashboard.html', {'projects': projects})
def get_teachers(user: "******"):
    """Get the teachers whose timetables are allowed to be seen by current user."""
    checker = ObjectPermissionChecker(user)

    teachers = (Person.objects.annotate(
        lessons_count=Count("lessons_as_teacher")).filter(
            lessons_count__gt=0).order_by("short_name", "last_name"))

    if not check_global_permission(user, "chronos.view_all_person_timetables"):
        checker.prefetch_perms(teachers)

        wanted_teachers = set()

        for teacher in teachers:
            if checker.has_perm("core.view_person_timetable", teacher):
                wanted_teachers.add(teacher.pk)

        teachers = teachers.filter(
            Q(pk=user.person.pk) | Q(pk__in=wanted_teachers))

    return teachers
Exemple #29
0
def list(request, groupid):
	groupid = int(groupid)
	try:
		group = Group.objects.get(id=groupid)
	except ObjectDoesNotExist:
		raise Http404
	result = {}

	own_group = request.user.is_superuser or group in request.user.groups.all()
	minutes = MinutesDocument.objects.all().prefetch_related('labels').order_by('-date')
	# Prefetch group permissions
	group_checker = ObjectPermissionChecker(group)
	group_checker.prefetch_perms(minutes)

	# Prefetch user permissions
	user_checker = ObjectPermissionChecker(request.user)
	user_checker.prefetch_perms(minutes)

	# Prefetch ip group permissions
	ip_range_group_name = request.user._ip_range_group_name if hasattr(request.user, '_ip_range_group_name') else None
	if ip_range_group_name:
		ip_range_group = Group.objects.get(name=ip_range_group_name)
		ip_range_group_checker = ObjectPermissionChecker(ip_range_group)

	for m in minutes:
		# we show all documents for which the requested group has edit permissions
		# e.g. if you request FSR minutes, all minutes for which the FSR group has edit rights will be shown
		if not group_checker.has_perm(m.edit_permission_name, m):
			continue
		# we only show documents for which the user has view permissions
		if not user_checker.has_perm(MinutesDocument.get_view_permission(), m) and (not ip_range_group_name or not ip_range_group_checker.has_perm(MinutesDocument.get_view_permission(), m)):
			continue
		if m.date.year not in result:
			result[m.date.year] = []
		result[m.date.year].append(m)
	return render(request, "minutes_list.html", {
		'minutes_list': sorted(result.items(), reverse=True),
		'own_group': own_group
	})
Exemple #30
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)
    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()

        checker = ObjectPermissionChecker(user_or_group=self.request.user)
        for qs in [
                Archive.objects.only("pk").all(),
                ReaderStudy.objects.only("pk").all(),
                Challenge.objects.only("pk").all(),
                Algorithm.objects.only("pk").all(),
                ExternalChallenge.objects.only("pk").all(),
        ]:
            # Perms can only be prefetched for sets of the same objects
            checker.prefetch_perms(objects=qs)

        context.update({
            "checker":
            checker,
            "num_citations":
            self.get_queryset().exclude(
                referenced_by_count__isnull=True).aggregate(
                    Sum("referenced_by_count"))["referenced_by_count__sum"],
        })
        return context
Exemple #32
0
def get_permissions(user_or_group: Union[User, Group], object_list: QuerySet) -> List[ObjectPermission]:

    permissions = []

    perm_checker = ObjectPermissionChecker(user_or_group)
    perm_checker.prefetch_perms(object_list)

    opts = object_list.model._meta

    perm_view = get_permission_codename('view', opts)
    perm_change = get_permission_codename('change', opts)
    perm_delete = get_permission_codename('delete', opts)

    for obj in object_list:
        permissions.append(
            ObjectPermission(
                obj=obj,
                can_view=perm_checker.has_perm(perm_view, obj),
                can_change=perm_checker.has_perm(perm_change, obj),
                can_delete=perm_checker.has_perm(perm_delete, obj),
            )
        )

    return permissions
    def test_prefetch_group_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group1 = Group.objects.create(name='group1')
            group2 = Group.objects.create(name='group2')
            assign_perm("change_group", group1, self.group)
            assign_perm("change_group", group1, group1)
            checker = ObjectPermissionChecker(group1)

            # Prefetch permissions
            prefetched_objects = [self.group, group1, group2]
            self.assertTrue(checker.prefetch_perms(prefetched_objects))

            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(
                len(checker._obj_perms_cache),
                len(prefetched_objects)
            )

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", group1)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            # Even though User doesn't have perms on Group2, we still should
            #  not hit DB
            self.assertFalse(checker.has_perm("change_group", group2))
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
Exemple #34
0
    def test_prefetch_group_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group1 = Group.objects.create(name='group1')
            group2 = Group.objects.create(name='group2')
            assign_perm("change_group", group1, self.group)
            assign_perm("change_group", group1, group1)
            checker = ObjectPermissionChecker(group1)

            # Prefetch permissions
            prefetched_objects = [self.group, group1, group2]
            self.assertTrue(checker.prefetch_perms(prefetched_objects))

            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(
                len(checker._obj_perms_cache),
                len(prefetched_objects)
            )

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", group1)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            # Even though User doesn't have perms on Group2, we still should
            #  not hit DB
            self.assertFalse(checker.has_perm("change_group", group2))
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
Exemple #35
0
    def test_prefetch_group_perms_direct_rel(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group = Group.objects.create(name='new-group')
            projects = \
                [Project.objects.create(name='Project%s' % i)
                    for i in range(3)]
            assign_perm("change_project", group, projects[0])
            assign_perm("change_project", group, projects[1])

            checker = ObjectPermissionChecker(group)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms(projects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), len(projects))

            # Checking shouldn't spawn any queries
            checker.has_perm("change_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any
            #  queries
            checker.has_perm("change_project", projects[1])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            # Even though User doesn't have perms on projects[2], we still
            #  should not hit DB
            self.assertFalse(checker.has_perm("change_project", projects[2]))
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
    def test_prefetch_group_perms_direct_rel(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group = Group.objects.create(name='new-group')
            projects = \
                [Project.objects.create(name='Project%s' % i)
                    for i in range(3)]
            assign_perm("change_project", group, projects[0])
            assign_perm("change_project", group, projects[1])

            checker = ObjectPermissionChecker(group)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms(projects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), len(projects))

            # Checking shouldn't spawn any queries
            checker.has_perm("change_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any
            #  queries
            checker.has_perm("change_project", projects[1])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            # Even though User doesn't have perms on projects[2], we still
            #  should not hit DB
            self.assertFalse(checker.has_perm("change_project", projects[2]))
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
    def test_prefetch_superuser_perms_direct_rel(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            user = User.objects.create(username='******',
                                       is_active=True,
                                       is_superuser=True)
            projects = \
                [Project.objects.create(name='Project%s' % i)
                    for i in range(2)]
            for project in projects:
                assign_perm("change_project", user, project)
            checker = ObjectPermissionChecker(user)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms(projects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), 2)

            # Checking shouldn't spawn any queries
            checker.has_perm("change_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any
            #  queries
            checker.has_perm("change_project", projects[1])
            self.assertEqual(len(connection.queries), query_count)

        finally:
            settings.DEBUG = False
Exemple #38
0
    def test_prefetch_superuser_perms_direct_rel(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            user = User.objects.create(
                username='******', is_active=True, is_superuser=True)
            projects = \
                [Project.objects.create(name='Project%s' % i)
                    for i in range(2)]
            for project in projects:
                assign_perm("change_project", user, project)
            checker = ObjectPermissionChecker(user)

            # Prefetch permissions
            self.assertTrue(checker.prefetch_perms(projects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(len(checker._obj_perms_cache), 2)

            # Checking shouldn't spawn any queries
            checker.has_perm("change_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_project", projects[0])
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any
            #  queries
            checker.has_perm("change_project", projects[1])
            self.assertEqual(len(connection.queries), query_count)

        finally:
            settings.DEBUG = False
    def test_prefetch_superuser_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group1 = Group.objects.create(name='group1')
            user = User.objects.create(username='******',
                                       is_superuser=True, is_active=True)
            assign_perm("change_group", user, self.group)
            checker = ObjectPermissionChecker(user)

            # Prefetch permissions
            prefetched_objects = [self.group, group1]
            self.assertTrue(checker.prefetch_perms(prefetched_objects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(
                len(checker._obj_perms_cache),
                len(prefetched_objects)
            )

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", group1)
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
Exemple #40
0
    def test_prefetch_superuser_perms(self):
        settings.DEBUG = True
        try:
            from django.db import connection

            ContentType.objects.clear_cache()
            group1 = Group.objects.create(name='group1')
            user = User.objects.create(username='******',
                                       is_superuser=True, is_active=True)
            assign_perm("change_group", user, self.group)
            checker = ObjectPermissionChecker(user)

            # Prefetch permissions
            prefetched_objects = [self.group, group1]
            self.assertTrue(checker.prefetch_perms(prefetched_objects))
            query_count = len(connection.queries)

            # Checking cache is filled
            self.assertEqual(
                len(checker._obj_perms_cache),
                len(prefetched_objects)
            )

            # Checking shouldn't spawn any queries
            checker.has_perm("change_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for other permission but for Group object again
            # shouldn't spawn any query too
            checker.has_perm("delete_group", self.group)
            self.assertEqual(len(connection.queries), query_count)

            # Checking for same model but other instance shouldn't spawn any queries
            checker.has_perm("change_group", group1)
            self.assertEqual(len(connection.queries), query_count)
        finally:
            settings.DEBUG = False
Exemple #41
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}
    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