From 188ef0f58f0a6553c5a421edc7d7e5176550c83f Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 28 Jan 2021 23:16:51 +0100 Subject: [PATCH] core: only cache Applications API when no filtering is done --- authentik/core/api/applications.py | 41 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/authentik/core/api/applications.py b/authentik/core/api/applications.py index e487c069b..75b5b85c9 100644 --- a/authentik/core/api/applications.py +++ b/authentik/core/api/applications.py @@ -11,6 +11,7 @@ from rest_framework.response import Response from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet 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.core.api.providers import ProviderSerializer @@ -18,6 +19,8 @@ from authentik.core.models import Application from authentik.events.models import EventAction from authentik.policies.engine import PolicyEngine +LOGGER = get_logger() + def user_app_cache_key(user_pk: str) -> str: """Cache key where application list for user is saved""" @@ -74,23 +77,35 @@ class ApplicationViewSet(ModelViewSet): queryset = backend().filter_queryset(self.request, queryset, self) return queryset + def _get_allowed_applications(self, queryset: QuerySet) -> list[Application]: + applications = [] + for application in queryset: + engine = PolicyEngine(application, self.request.user, self.request) + engine.build() + if engine.passing: + 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) - allowed_applications = cache.get(user_app_cache_key(self.request.user.pk)) - if not allowed_applications: - allowed_applications = [] - for application in queryset: - engine = PolicyEngine(application, self.request.user, self.request) - engine.build() - if engine.passing: - allowed_applications.append(application) - cache.set( - user_app_cache_key(self.request.user.pk), - allowed_applications, - timeout=86400, - ) + + 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( + user_app_cache_key(self.request.user.pk), + allowed_applications, + timeout=86400, + ) serializer = self.get_serializer(allowed_applications, many=True) return self.get_paginated_response(serializer.data)