core: only cache Applications API when no filtering is done
This commit is contained in:
parent
5ef4354723
commit
188ef0f58f
|
@ -11,6 +11,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
from rest_framework_guardian.filters import ObjectPermissionsFilter
|
from rest_framework_guardian.filters import ObjectPermissionsFilter
|
||||||
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.admin.api.metrics import get_events_per_1h
|
from authentik.admin.api.metrics import get_events_per_1h
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
from authentik.core.api.providers import ProviderSerializer
|
||||||
|
@ -18,6 +19,8 @@ from authentik.core.models import Application
|
||||||
from authentik.events.models import EventAction
|
from authentik.events.models import EventAction
|
||||||
from authentik.policies.engine import PolicyEngine
|
from authentik.policies.engine import PolicyEngine
|
||||||
|
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
def user_app_cache_key(user_pk: str) -> str:
|
def user_app_cache_key(user_pk: str) -> str:
|
||||||
"""Cache key where application list for user is saved"""
|
"""Cache key where application list for user is saved"""
|
||||||
|
@ -74,18 +77,30 @@ class ApplicationViewSet(ModelViewSet):
|
||||||
queryset = backend().filter_queryset(self.request, queryset, self)
|
queryset = backend().filter_queryset(self.request, queryset, self)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def list(self, request: Request) -> Response:
|
def _get_allowed_applications(self, queryset: QuerySet) -> list[Application]:
|
||||||
"""Custom list method that checks Policy based access instead of guardian"""
|
applications = []
|
||||||
queryset = self._filter_queryset_for_list(self.get_queryset())
|
|
||||||
self.paginate_queryset(queryset)
|
|
||||||
allowed_applications = cache.get(user_app_cache_key(self.request.user.pk))
|
|
||||||
if not allowed_applications:
|
|
||||||
allowed_applications = []
|
|
||||||
for application in queryset:
|
for application in queryset:
|
||||||
engine = PolicyEngine(application, self.request.user, self.request)
|
engine = PolicyEngine(application, self.request.user, self.request)
|
||||||
engine.build()
|
engine.build()
|
||||||
if engine.passing:
|
if engine.passing:
|
||||||
allowed_applications.append(application)
|
applications.append(application)
|
||||||
|
return applications
|
||||||
|
|
||||||
|
def list(self, request: Request) -> Response:
|
||||||
|
"""Custom list method that checks Policy based access instead of guardian"""
|
||||||
|
queryset = self._filter_queryset_for_list(self.get_queryset())
|
||||||
|
self.paginate_queryset(queryset)
|
||||||
|
|
||||||
|
should_cache = "search" not in request.GET
|
||||||
|
|
||||||
|
allowed_applications = []
|
||||||
|
if not should_cache:
|
||||||
|
allowed_applications = self._get_allowed_applications(queryset)
|
||||||
|
if should_cache:
|
||||||
|
LOGGER.debug("Caching allowed application list")
|
||||||
|
allowed_applications = cache.get(user_app_cache_key(self.request.user.pk))
|
||||||
|
if not allowed_applications:
|
||||||
|
allowed_applications = self._get_allowed_applications(queryset)
|
||||||
cache.set(
|
cache.set(
|
||||||
user_app_cache_key(self.request.user.pk),
|
user_app_cache_key(self.request.user.pk),
|
||||||
allowed_applications,
|
allowed_applications,
|
||||||
|
|
Reference in New Issue