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/audit/api.py

71 lines
2.3 KiB
Python
Raw Normal View History

2019-10-28 13:44:46 +00:00
"""Audit API Views"""
2020-12-01 21:16:50 +00:00
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
2020-12-01 21:16:50 +00:00
from passbook.audit.models import Event, EventAction
class EventSerializer(ModelSerializer):
2019-10-28 13:44:46 +00:00
"""Event Serializer"""
class Meta:
model = Event
2019-12-31 11:51:16 +00:00
fields = [
"pk",
"user",
"action",
"app",
"context",
2020-02-28 10:48:55 +00:00
"client_ip",
2019-12-31 11:51:16 +00:00
"created",
]
2020-12-01 21:16:50 +00:00
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):
2019-10-28 13:44:46 +00:00
"""Event Read-Only Viewset"""
queryset = Event.objects.all()
serializer_class = EventSerializer
2020-12-01 21:16:50 +00:00
@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]
)