api: move events to Audit API

This commit is contained in:
Jens Langhammer 2020-12-01 22:16:50 +01:00
parent 8c8ff4643a
commit b218ded241
3 changed files with 44 additions and 22 deletions

View File

@ -1,6 +1,5 @@
"""passbook administration overview""" """passbook administration overview"""
from django.core.cache import cache from django.core.cache import cache
from django.http import response
from drf_yasg2.utils import swagger_auto_schema from drf_yasg2.utils import swagger_auto_schema
from rest_framework.fields import SerializerMethodField from rest_framework.fields import SerializerMethodField
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
@ -61,7 +60,7 @@ class AdministrationOverviewSerializer(Serializer):
"""Get cached flow count""" """Get cached flow count"""
return len(cache.keys("flow_*")) return len(cache.keys("flow_*"))
def create(self, request: Request) -> response: def create(self, request: Request) -> Response:
raise NotImplementedError raise NotImplementedError
def update(self, request: Request) -> Response: def update(self, request: Request) -> Response:

View File

@ -4,8 +4,6 @@ from typing import Union
from django.conf import settings from django.conf import settings
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.core.cache import cache from django.core.cache import cache
from django.db.models import Count
from django.db.models.fields.json import KeyTextTransform
from django.http.request import HttpRequest from django.http.request import HttpRequest
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -18,7 +16,6 @@ from passbook import __version__
from passbook.admin.forms.overview import FlowCacheClearForm, PolicyCacheClearForm from passbook.admin.forms.overview import FlowCacheClearForm, PolicyCacheClearForm
from passbook.admin.mixins import AdminRequiredMixin from passbook.admin.mixins import AdminRequiredMixin
from passbook.admin.tasks import VERSION_CACHE_KEY, update_latest_version from passbook.admin.tasks import VERSION_CACHE_KEY, update_latest_version
from passbook.audit.models import Event, EventAction
from passbook.core.models import Provider, User from passbook.core.models import Provider, User
from passbook.policies.models import Policy from passbook.policies.models import Policy
@ -39,27 +36,12 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
return parse(__version__) return parse(__version__)
return parse(version_in_cache) return parse(version_in_cache)
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]
)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs["policy_count"] = len(Policy.objects.all()) kwargs["policy_count"] = len(Policy.objects.all())
kwargs["user_count"] = len(User.objects.all()) - 1 # Remove anonymous user kwargs["user_count"] = len(User.objects.all()) - 1 # Remove anonymous user
kwargs["provider_count"] = len(Provider.objects.all()) kwargs["provider_count"] = len(Provider.objects.all())
kwargs["version"] = parse(__version__) kwargs["version"] = parse(__version__)
kwargs["version_latest"] = self.get_latest_version() kwargs["version_latest"] = self.get_latest_version()
kwargs["most_used_applications"] = self.get_most_used_applications()
kwargs["providers_without_application"] = Provider.objects.filter( kwargs["providers_without_application"] = Provider.objects.filter(
application=None application=None
) )

View File

@ -1,8 +1,15 @@
"""Audit API Views""" """Audit API Views"""
from rest_framework.serializers import ModelSerializer from django.db.models.aggregates import Count
from django.db.models.fields.json import KeyTextTransform
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.fields import DictField, IntegerField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, Serializer
from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet
from passbook.audit.models import Event from passbook.audit.models import Event, EventAction
class EventSerializer(ModelSerializer): class EventSerializer(ModelSerializer):
@ -22,8 +29,42 @@ class EventSerializer(ModelSerializer):
] ]
class EventTopPerUserSerialier(Serializer):
"""Response object of Event's top_per_user"""
application = DictField()
counted_events = IntegerField()
unique_users = IntegerField()
def create(self, request: Request) -> Response:
raise NotImplementedError
def update(self, request: Request) -> Response:
raise NotImplementedError
class EventViewSet(ReadOnlyModelViewSet): class EventViewSet(ReadOnlyModelViewSet):
"""Event Read-Only Viewset""" """Event Read-Only Viewset"""
queryset = Event.objects.all() queryset = Event.objects.all()
serializer_class = EventSerializer serializer_class = EventSerializer
@swagger_auto_schema(
method="GET", responses={200: EventTopPerUserSerialier(many=True)}
)
@action(detail=False, methods=["GET"])
def top_per_user(self, request: Request):
"""Get the top_n events grouped by user count"""
filtered_action = request.query_params.get("filter_action", EventAction.LOGIN)
top_n = request.query_params.get("top_n", 15)
return Response(
Event.objects.filter(action=filtered_action)
.exclude(context__authorized_application=None)
.annotate(application=KeyTextTransform("authorized_application", "context"))
.annotate(user_pk=KeyTextTransform("pk", "user"))
.values("application")
.annotate(counted_events=Count("application"))
.annotate(unique_users=Count("user_pk", distinct=True))
.values("unique_users", "application", "counted_events")
.order_by("-counted_events")[:top_n]
)