refactor(access): Object permission checking moved to has_object_permission function

ref: #442 #454
This commit is contained in:
2024-12-26 00:49:40 +09:30
parent f2181b018d
commit 4be1e97cbe
2 changed files with 85 additions and 28 deletions

View File

@ -123,6 +123,36 @@ class OrganizationMixin:
def get_permission_organizations(self, permission: str ) -> list([ int ]):
"""Return Organization(s) the permission belongs to
Searches the users organizations for the required permission, if found
the organization is added to the list to return.
Args:
permission (str): Permission to search users organizations for
Returns:
Organizations (list): All Organizations where the permission was found.
"""
_permission_organizations: list = []
for team in self.get_user_teams( self.request.user ):
for team_permission in team.permissions.all():
permission_value = str( team_permission.content_type.app_label + '.' + team_permission.codename )
if permission_value == permission:
_permission_organizations += [ team.organization.id ]
return _permission_organizations
def get_permission_required(self) -> str:
""" Get / Generate Permission Required

View File

@ -39,6 +39,37 @@ class OrganizationPermissionMixin(
"""
_is_tenancy_model: bool = None
def is_tenancy_model(self, view) -> bool:
"""Determin if the Model is a `Tenancy` Model
Will look at the model defined within the view unless a parent
model is found. If the latter is true, the parent_model will be used to
determin if the model is a `Tenancy` model
Args:
view (object): The View the HTTP request was mad to
Returns:
True (bool): Model is a Tenancy Model.
False (bool): Model is not a Tenancy model.
"""
if not self._is_tenancy_model:
if hasattr(view, 'model'):
self._is_tenancy_model = issubclass(view.model, TenancyObject)
if view.get_parent_model():
self._is_tenancy_model = issubclass(view.get_parent_model(), TenancyObject)
return self._is_tenancy_model
def has_permission(self, request, view):
""" Check if user has the required permission
@ -67,6 +98,7 @@ class OrganizationPermissionMixin(
request = request
)
view_action: str = None
if(
view.action == 'create'
@ -84,18 +116,10 @@ class OrganizationPermissionMixin(
view_action = 'change'
obj_organization = view.get_obj_organization(
obj = view.get_object()
)
elif view.action == 'destroy':
view_action = 'delete'
obj_organization = view.get_obj_organization(
obj = view.get_object()
)
elif (
view.action == 'list'
):
@ -106,10 +130,6 @@ class OrganizationPermissionMixin(
view_action = 'view'
obj_organization = view.get_obj_organization(
obj = view.get_object()
)
elif view.action == 'metadata':
return True
@ -127,27 +147,21 @@ class OrganizationPermissionMixin(
has_permission_required = view.get_permission_required() in getattr(view, '_user_permissions', [])
return True
elif(
obj_organization is not None
and is_tenancy_model
):
if has_permission_required is True:
if view.has_organization_permission(
organization = obj_organization.id,
permissions_required = [ self.permission_required ]
):
if obj_organization is None:
return True
elif(
self.permission_required in getattr(view, '_user_permissions', [])
and view.action == 'list'
):
elif obj_organization is not None:
return True
if view.has_organization_permission(
organization = obj_organization.id,
permissions_required = [ view.get_permission_required() ]
):
return True
except ValueError:
@ -172,7 +186,20 @@ class OrganizationPermissionMixin(
return False
if getattr(view.get_obj_organization( obj = obj ), 'id', 'no-org-found') in view._user_organizations:
object_organization: int = getattr(view.get_obj_organization( obj = obj ), 'id', None)
if object_organization:
if(
object_organization
in view.get_permission_organizations( view.get_permission_required() )
):
return True
elif not self.is_tenancy_model( view ):
return True