This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/admin/views/overview.py

104 lines
4.2 KiB
Python
Raw Normal View History

"""passbook administration overview"""
from typing import Union
2020-10-03 22:28:58 +00:00
from django.conf import settings
from django.contrib.messages.views import SuccessMessageMixin
from django.core.cache import cache
2020-10-05 20:09:57 +00:00
from django.db.models import Count
from django.db.models.fields.json import KeyTextTransform
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import FormView, TemplateView
from packaging.version import LegacyVersion, Version, parse
from structlog import get_logger
2018-11-11 12:41:48 +00:00
2019-10-07 14:33:48 +00:00
from passbook import __version__
from passbook.admin.forms.overview import FlowCacheClearForm, PolicyCacheClearForm
2018-11-16 08:10:35 +00:00
from passbook.admin.mixins import AdminRequiredMixin
from passbook.admin.tasks import VERSION_CACHE_KEY, update_latest_version
2020-10-05 20:09:57 +00:00
from passbook.audit.models import Event, EventAction
from passbook.core.models import Provider, User
from passbook.policies.models import Policy
2018-11-11 12:41:48 +00:00
LOGGER = get_logger()
2020-06-30 08:23:39 +00:00
2018-11-16 08:10:35 +00:00
class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
"""Overview View"""
2018-11-11 12:41:48 +00:00
2019-12-31 11:51:16 +00:00
template_name = "administration/overview.html"
2018-11-11 12:41:48 +00:00
def get_latest_version(self) -> Union[LegacyVersion, Version]:
"""Get latest version from cache"""
version_in_cache = cache.get(VERSION_CACHE_KEY)
if not version_in_cache:
2020-10-03 22:28:58 +00:00
if not settings.DEBUG:
update_latest_version.delay()
return parse(__version__)
return parse(version_in_cache)
2020-10-05 20:09:57 +00:00
def get_most_used_applications(self):
"""Get Most used applications, total login counts and unique users that have used them."""
return (
Event.objects.filter(action=EventAction.AUTHORIZE_APPLICATION)
.exclude(context__authorized_application=None)
.annotate(application=KeyTextTransform("authorized_application", "context"))
.annotate(user_pk=KeyTextTransform("pk", "user"))
.values("application")
.annotate(total_logins=Count("application"))
.annotate(unique_users=Count("user_pk", distinct=True))
.values("unique_users", "application", "total_logins")
.order_by("-total_logins")[:15]
)
2018-11-11 12:41:48 +00:00
def get_context_data(self, **kwargs):
2019-12-31 11:51:16 +00:00
kwargs["policy_count"] = len(Policy.objects.all())
2020-09-14 21:35:01 +00:00
kwargs["user_count"] = len(User.objects.all()) - 1 # Remove anonymous user
kwargs["provider_count"] = len(Provider.objects.all())
2020-06-30 08:23:39 +00:00
kwargs["version"] = parse(__version__)
kwargs["version_latest"] = self.get_latest_version()
2020-10-05 20:09:57 +00:00
kwargs["most_used_applications"] = self.get_most_used_applications()
kwargs["providers_without_application"] = Provider.objects.filter(
application=None
)
kwargs["policies_without_binding"] = len(
Policy.objects.filter(bindings__isnull=True, promptstage__isnull=True)
2019-12-31 11:51:16 +00:00
)
kwargs["cached_policies"] = len(cache.keys("policy_*"))
2020-07-07 11:13:15 +00:00
kwargs["cached_flows"] = len(cache.keys("flow_*"))
2018-11-11 12:41:48 +00:00
return super().get_context_data(**kwargs)
class PolicyCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
"""View to clear Policy cache"""
form_class = PolicyCacheClearForm
template_name = "generic/form_non_model.html"
success_url = reverse_lazy("passbook_admin:overview")
success_message = _("Successfully cleared Policy cache")
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
keys = cache.keys("policy_*")
cache.delete_many(keys)
LOGGER.debug("Cleared Policy cache", keys=len(keys))
return super().post(request, *args, **kwargs)
class FlowCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
"""View to clear Flow cache"""
form_class = FlowCacheClearForm
template_name = "generic/form_non_model.html"
success_url = reverse_lazy("passbook_admin:overview")
success_message = _("Successfully cleared Flow cache")
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
keys = cache.keys("flow_*")
cache.delete_many(keys)
LOGGER.debug("Cleared flow cache", keys=len(keys))
return super().post(request, *args, **kwargs)