2019-10-28 13:44:46 +00:00
|
|
|
"""Application API Views"""
|
2020-10-07 17:57:45 +00:00
|
|
|
from django.db.models import QuerySet
|
2020-11-27 17:37:45 +00:00
|
|
|
from rest_framework.decorators import action
|
2020-11-30 11:33:09 +00:00
|
|
|
from rest_framework.fields import SerializerMethodField
|
2020-10-07 17:57:45 +00:00
|
|
|
from rest_framework.request import Request
|
|
|
|
from rest_framework.response import Response
|
2019-10-28 13:27:43 +00:00
|
|
|
from rest_framework.serializers import ModelSerializer
|
|
|
|
from rest_framework.viewsets import ModelViewSet
|
2020-10-07 17:57:45 +00:00
|
|
|
from rest_framework_guardian.filters import ObjectPermissionsFilter
|
2019-10-28 13:27:43 +00:00
|
|
|
|
2020-11-27 17:37:45 +00:00
|
|
|
from passbook.admin.api.overview_metrics import get_events_per_1h
|
|
|
|
from passbook.audit.models import EventAction
|
2019-10-28 13:27:43 +00:00
|
|
|
from passbook.core.models import Application
|
2020-10-07 17:57:45 +00:00
|
|
|
from passbook.policies.engine import PolicyEngine
|
2019-10-28 13:27:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ApplicationSerializer(ModelSerializer):
|
2019-10-28 13:44:46 +00:00
|
|
|
"""Application Serializer"""
|
2019-10-28 13:27:43 +00:00
|
|
|
|
2020-11-30 11:33:09 +00:00
|
|
|
launch_url = SerializerMethodField()
|
|
|
|
|
|
|
|
def get_launch_url(self, instance: Application) -> str:
|
|
|
|
"""Get generated launch URL"""
|
|
|
|
return instance.get_launch_url() or ""
|
|
|
|
|
2019-10-28 13:27:43 +00:00
|
|
|
class Meta:
|
|
|
|
|
|
|
|
model = Application
|
2019-12-31 11:51:16 +00:00
|
|
|
fields = [
|
|
|
|
"pk",
|
|
|
|
"name",
|
|
|
|
"slug",
|
|
|
|
"provider",
|
2020-11-30 11:33:09 +00:00
|
|
|
"launch_url",
|
2020-02-20 12:45:22 +00:00
|
|
|
"meta_launch_url",
|
2020-11-23 19:50:19 +00:00
|
|
|
"meta_icon",
|
2020-02-20 12:45:22 +00:00
|
|
|
"meta_description",
|
|
|
|
"meta_publisher",
|
2019-12-31 11:51:16 +00:00
|
|
|
"policies",
|
|
|
|
]
|
2019-10-28 13:27:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ApplicationViewSet(ModelViewSet):
|
2019-10-28 13:44:46 +00:00
|
|
|
"""Application Viewset"""
|
2019-10-28 13:27:43 +00:00
|
|
|
|
|
|
|
queryset = Application.objects.all()
|
|
|
|
serializer_class = ApplicationSerializer
|
2020-10-07 17:57:45 +00:00
|
|
|
lookup_field = "slug"
|
|
|
|
|
|
|
|
def _filter_queryset_for_list(self, queryset: QuerySet) -> QuerySet:
|
|
|
|
"""Custom filter_queryset method which ignores guardian, but still supports sorting"""
|
|
|
|
for backend in list(self.filter_backends):
|
|
|
|
if backend == ObjectPermissionsFilter:
|
|
|
|
continue
|
|
|
|
queryset = backend().filter_queryset(self.request, queryset, self)
|
|
|
|
return queryset
|
|
|
|
|
2020-11-30 11:33:09 +00:00
|
|
|
def list(self, request: Request) -> Response:
|
2020-10-07 17:57:45 +00:00
|
|
|
"""Custom list method that checks Policy based access instead of guardian"""
|
|
|
|
queryset = self._filter_queryset_for_list(self.get_queryset())
|
2020-11-26 11:51:52 +00:00
|
|
|
self.paginate_queryset(queryset)
|
2020-10-07 17:57:45 +00:00
|
|
|
allowed_applications = []
|
|
|
|
for application in queryset.order_by("name"):
|
|
|
|
engine = PolicyEngine(application, self.request.user, self.request)
|
|
|
|
engine.build()
|
|
|
|
if engine.passing:
|
|
|
|
allowed_applications.append(application)
|
|
|
|
serializer = self.get_serializer(allowed_applications, many=True)
|
2020-11-26 11:51:52 +00:00
|
|
|
return self.get_paginated_response(serializer.data)
|
2020-11-27 17:37:45 +00:00
|
|
|
|
|
|
|
@action(detail=True)
|
|
|
|
def metrics(self, request: Request, slug: str):
|
2020-11-27 17:42:22 +00:00
|
|
|
"""Metrics for application logins"""
|
2020-11-27 17:37:45 +00:00
|
|
|
# TODO: Check app read and audit read perms
|
|
|
|
app = Application.objects.get(slug=slug)
|
|
|
|
return Response(
|
|
|
|
get_events_per_1h(
|
|
|
|
action=EventAction.AUTHORIZE_APPLICATION,
|
|
|
|
context__authorized_application__pk=app.pk.hex,
|
|
|
|
)
|
|
|
|
)
|