from rest_framework import permissions def user_is_admin(user) -> bool: """Single source of truth for "is this user an administrator?". Any of the three flags grants admin access: the app-specific ``is_admin`` flag, Django's ``is_staff``, or ``is_superuser``. Both the permission classes and the per-view authorization checks use this so the three flags behave identically everywhere. """ return bool( user and user.is_authenticated and ( getattr(user, "is_admin", False) or getattr(user, "is_staff", False) or getattr(user, "is_superuser", False) ) ) class IsAdminOrStaffPermission(permissions.BasePermission): """Admin gate for admin-only endpoints and for views that have no model/queryset of their own (e.g. proxy endpoints). ``IsStaffEditorPermission`` can't be used on model-less views because it derives the required permission from ``view.queryset.model`` (``None`` there); it also requires granular Django model permissions that admin accounts are not necessarily granted. This gate keys off admin status instead. """ message = { "message": "You do not have permission to perform this action.", } def has_permission(self, request, view): return user_is_admin(request.user) class IsStaffEditorPermission(permissions.DjangoModelPermissions): perms_map = { "GET": ["%(app_label)s.view_%(model_name)s"], "OPTIONS": [], "HEAD": [], "POST": ["%(app_label)s.add_%(model_name)s"], "PUT": ["%(app_label)s.change_%(model_name)s"], "PATCH": ["%(app_label)s.change_%(model_name)s"], "DELETE": ["%(app_label)s.delete_%(model_name)s"], } message = { "message": "You do not have permission to perform this action.", } def has_permission(self, request, view): # Ensure the user is authenticated if not request.user.is_authenticated: return False # Get the model name from the view model_name = view.queryset.model._meta.model_name app_label = view.queryset.model._meta.app_label # Check permissions based on the request method perms = self.perms_map.get(request.method, []) perms = [ perm % {"app_label": app_label, "model_name": model_name} for perm in perms ] return request.user.has_perms(perms)