77 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """Application API Views"""
 | |
| from django.db.models import QuerySet
 | |
| from rest_framework.decorators import action
 | |
| from rest_framework.request import Request
 | |
| from rest_framework.response import Response
 | |
| from rest_framework.serializers import ModelSerializer
 | |
| from rest_framework.viewsets import ModelViewSet
 | |
| from rest_framework_guardian.filters import ObjectPermissionsFilter
 | |
| 
 | |
| from passbook.admin.api.overview_metrics import get_events_per_1h
 | |
| from passbook.audit.models import EventAction
 | |
| from passbook.core.models import Application
 | |
| from passbook.policies.engine import PolicyEngine
 | |
| 
 | |
| 
 | |
| class ApplicationSerializer(ModelSerializer):
 | |
|     """Application Serializer"""
 | |
| 
 | |
|     class Meta:
 | |
| 
 | |
|         model = Application
 | |
|         fields = [
 | |
|             "pk",
 | |
|             "name",
 | |
|             "slug",
 | |
|             "provider",
 | |
|             "meta_launch_url",
 | |
|             "meta_icon",
 | |
|             "meta_description",
 | |
|             "meta_publisher",
 | |
|             "policies",
 | |
|         ]
 | |
| 
 | |
| 
 | |
| class ApplicationViewSet(ModelViewSet):
 | |
|     """Application Viewset"""
 | |
| 
 | |
|     queryset = Application.objects.all()
 | |
|     serializer_class = ApplicationSerializer
 | |
|     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
 | |
| 
 | |
|     def list(self, request: Request, *args, **kwargs) -> Response:
 | |
|         """Custom list method that checks Policy based access instead of guardian"""
 | |
|         if request.user.is_superuser:
 | |
|             # pylint: disable=no-member
 | |
|             return super().list(request, *args, **kwargs)
 | |
|         queryset = self._filter_queryset_for_list(self.get_queryset())
 | |
|         self.paginate_queryset(queryset)
 | |
|         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)
 | |
|         return self.get_paginated_response(serializer.data)
 | |
| 
 | |
|     @action(detail=True)
 | |
|     def metrics(self, request: Request, slug: str):
 | |
|         """Metrics for application logins"""
 | |
|         # 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,
 | |
|             )
 | |
|         )
 | 
