Skip to content
Snippets Groups Projects
Commit fc9e81c1 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Merge branch '293-add-helper-function-to-filter-a-queryset-by-a-rule' into 'master'

Resolve "Add helper function to filter a queryset by a rule"

Closes #293

See merge request AlekSIS/official/AlekSIS!318
parents cd111f33 4cbdb5f9
No related branches found
No related tags found
1 merge request!318Resolve "Add helper function to filter a queryset by a rule"
Pipeline #3323 failed
......@@ -9,7 +9,7 @@ from typing import Any, Callable, Optional, Sequence, Union
from uuid import uuid4
from django.conf import settings
from django.db.models import Model
from django.db.models import Model, QuerySet
from django.http import HttpRequest
from django.shortcuts import get_object_or_404
from django.utils import timezone
......@@ -17,6 +17,8 @@ from django.utils.functional import lazy
from django_global_request.middleware import get_request
from cache_memoize import cache_memoize
from aleksis.core.util import messages
......@@ -357,3 +359,20 @@ def handle_uploaded_file(f, filename: str):
with open(filename, "wb+") as destination:
for chunk in f.chunks():
destination.write(chunk)
@cache_memoize(3600)
def queryset_rules_filter(
obj: Union[HttpRequest, Model], queryset: QuerySet, perm: str
) -> QuerySet:
"""Filter queryset by user and permission."""
wanted_objects = set()
if isinstance(obj, HttpRequest) and hasattr(obj, "user"):
obj = obj.user
for item in queryset:
if obj.has_perm(perm, item):
wanted_objects.add(item.pk)
return queryset.filter(pk__in=wanted_objects)
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.db.models import Model
from django.http import HttpRequest
......@@ -8,7 +9,7 @@ from guardian.shortcuts import get_objects_for_user
from rules import predicate
from ..models import Group
from .core_helpers import get_site_preferences
from .core_helpers import get_site_preferences, queryset_rules_filter
from .core_helpers import has_person as has_person_helper
......@@ -57,15 +58,17 @@ def has_any_object(perm: str, klass):
"""Check if has any object.
Build predicate which checks whether a user has access
to objects with the provided permission.
to objects with the provided permission or rule.
"""
name = f"has_any_object:{perm}"
@predicate(name)
def fn(user: User) -> bool:
objs = get_objects_for_user(user, perm, klass)
return len(objs) > 0
ct_perm = ContentType.objects.get(app_label=perm.split('.', 1)[0], permission__codename=perm.split('.', 1)[1])
if ct_perm and ct_perm.model_class() == klass:
return get_objects_for_user(user, perm, klass).exists()
else:
return queryset_rules_filter(user, klass.objects.all(), perm).exists()
return fn
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment