api: move events to Audit API
This commit is contained in:
parent
8c8ff4643a
commit
b218ded241
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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]
|
||||||
|
)
|
||||||
|
|
Reference in New Issue