refactor(access): move ability to get required permissions from permissions mixin to organization mixin

ref: #442 #454
This commit is contained in:
2024-12-26 00:33:21 +09:30
parent d39f9ad463
commit f2181b018d
3 changed files with 66 additions and 51 deletions

View File

@ -123,27 +123,67 @@ class OrganizationMixin:
def get_permission_required(self):
"""
Override of 'PermissionRequiredMixin' method so that this mixin can obtain the required permission.
def get_permission_required(self) -> str:
""" Get / Generate Permission Required
If there is a requirement that there be custom/dynamic permissions,
this function can be safely overridden.
Raises:
ValueError: Unable to determin the view action
Returns:
str: Permission in format `<app_name>.<action>_<model_name>`
"""
if not hasattr(self, 'permission_required'):
return []
view_action: str = None
if self.permission_required is None:
raise ImproperlyConfigured(
f"{self.__class__.__name__} is missing the "
f"permission_required attribute. Define "
f"{self.__class__.__name__}.permission_required, or override "
f"{self.__class__.__name__}.get_permission_required()."
)
if isinstance(self.permission_required, str):
perms = (self.permission_required,)
else:
perms = self.permission_required
return perms
if(
self.action == 'create'
or getattr(self.request._stream, 'method', '') == 'POST'
):
view_action = 'add'
elif (
self.action == 'partial_update'
or self.action == 'update'
or getattr(self.request._stream, 'method', '') == 'PATCH'
or getattr(self.request._stream, 'method', '') == 'PUT'
):
view_action = 'change'
elif self.action == 'destroy':
view_action = 'delete'
elif (
self.action == 'list'
):
view_action = 'view'
elif self.action == 'retrieve':
view_action = 'view'
if view_action is None:
raise ValueError('view_action could not be defined.')
permission = self.model._meta.app_label + '.' + view_action + '_' + self.model._meta.model_name
permission_required = permission
self.permission_required = permission_required
return self.permission_required

View File

@ -120,38 +120,12 @@ class OrganizationPermissionMixin(
raise ValueError('view_action could not be defined.')
permission = view.model._meta.app_label + '.' + view_action + '_' + view.model._meta.model_name
has_permission_required: bool = False
self.permission_required = permission
if getattr(view, '_user_permissions', []):
has_permission_required = view.get_permission_required() in getattr(view, '_user_permissions', [])
if hasattr(view, 'get_dynamic_permissions'):
self.permission_required = view.get_dynamic_permissions()
if type(self.permission_required) is list:
if len(list(self.permission_required)) == 1:
self.permission_required = self.permission_required[0] # ToDo: cater for multiple permissions? is it required?
is_tenancy_model = issubclass(view.model, TenancyObject)
if view.get_parent_model():
is_tenancy_model = issubclass(view.get_parent_model(), TenancyObject)
if(
(
self.permission_required in getattr(view, '_user_permissions', [])
and not is_tenancy_model
# and obj_organization is None
and view.action != 'list'
)
or request.user.is_superuser
):
return True

View File

@ -86,7 +86,7 @@ class TicketViewSet(ModelViewSet):
"""
def get_dynamic_permissions(self):
def get_permission_required(self):
organization = None
@ -178,11 +178,12 @@ class TicketViewSet(ModelViewSet):
raise ValueError('unable to determin the action_keyword')
self.permission_required = [
str('core.' + action_keyword + '_ticket_' + self._ticket_type).lower().replace(' ', '_'),
]
self.permission_required = str(
'core.' + action_keyword + '_ticket_' + self._ticket_type).lower().replace(' ', '_'
)
return self.permission_required
return super().get_permission_required()
def get_queryset(self):