from functools import wraps from django.core.exceptions import PermissionDenied from django.shortcuts import render from . import models from django.db.models import Q # import logging # logger = logging.getLogger(__name__) # class CustomPermissionRequiredMixin: # resource = None # action = None # def has_custom_permission(self, user, resource, action): # if not self.resource or not self.action: # raise AttributeError("Resource and action attributes must be defined in the view") # # if not request.user.is_authenticated: # # return self.handle_no_permission() # if user.is_superuser: # will chagne to principal type for admin # return True # permission_query = Q( # principal_group__role__app_resource_action__app_resource__name=resource, # principal_group__role__app_resource_action__app_action__name=action # ) # return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists() # def dispatch(self, request, *args, **kwargs): # if not self.has_custom_permission(request.user, self.resource, self.action): # # logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}") # raise PermissionDenied("You do not have permission to access this resource.") # return super().dispatch(request, *args, **kwargs) # @classmethod # def as_decorator(cls, resource, action): # def decorator(view_func): # @wraps(view_func) # def _wrapped_view(request, *args, **kwargs): # instance = cls() # instance.resource = resource # instance.action = action # if not instance.has_custom_permission(request.user, instance.resource, instance.action): # raise PermissionDenied("You do not have permission to access this resource.") # return view_func(request, *args, **kwargs) # return _wrapped_view # return decorator class ResourcePermissionRequiredMixin: resource = None def has_resource_permission(self, user, resource): # if not self.resource or resource: # raise AttributeError("Resource attributes must be defined in the view") # if not request.user.is_authenticated: # return self.handle_no_permission() if user.is_superuser: # will chagne to principal type for admin return True permission_query = Q( principal_resource__name=resource, ) return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists() def dispatch(self, request, *args, **kwargs): if not self.has_resource_permission(request.user, self.resource): # logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}") return render(request, "module_iam/permission_denied.html") return super().dispatch(request, *args, **kwargs) @classmethod def as_decorator(cls, resource): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): instance = cls() instance.resource = resource if not instance.has_resource_permission(request.user, instance.resource): return render(request, "module_iam/permission_denied.html") return view_func(request, *args, **kwargs) return _wrapped_view return decorator