Files
goodtimes/accounts/permission.py

112 lines
4.2 KiB
Python

from functools import wraps
from django.core.exceptions import PermissionDenied
from . import models
from django.db.models import Q
from rest_framework import permissions
# 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 IsOwnerOrReadOnly(permissions.BasePermission):
# """
# Custom permission to only allow owners of an object to edit it.
# """
# def has_object_permission(self, request, view, obj):
# # Read permissions are allowed to any request,
# # so we'll always allow GET, HEAD or OPTIONS requests.
# if request.method in permissions.SAFE_METHODS:
# return True
# # Write permissions are only allowed to the owner of the object.
# return obj.created_by == request.user
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}")
raise PermissionDenied(
"You do not have permission to access this resource."
)
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
):
raise PermissionDenied(
"You do not have permission to access this resource."
)
return view_func(request, *args, **kwargs)
return _wrapped_view
return decorator