refactor(access): Use exceptions for permission flow as required

ref: #442 #456
This commit is contained in:
2024-12-28 17:33:11 +09:30
parent fbaf8770df
commit a07dee370c
3 changed files with 65 additions and 7 deletions

View File

@ -213,6 +213,10 @@ class OrganizationMixin:
view_action = 'view'
elif self.action is None:
return False
if view_action is None:

View File

@ -73,11 +73,35 @@ class OrganizationPermissionMixin(
def has_permission(self, request, view):
""" Check if user has the required permission
Permission flow is as follows:
- Un-authenticated users. Access Denied
- Authenticated user whom make a request using wrong method. Access
Denied
- Authenticated user who is not in same organization as object. Access
Denied
- Authenticated user who is in same organization as object, however is
missing the correct permission. Access Denied
Depending upon user type, they will recieve different feedback. In order
they are:
- Non-authenticated users will **always** recieve HTTP/401
- Authenticated users who use an unsupported method, HTTP/405
- Authenticated users missing the correct permission recieve HTTP/403
Args:
request (object): The HTTP Request Object
view (_type_): The View/Viewset Object the request was made to
Raises:
PermissionDenied: User does not have the required permission.
NotAuthenticated: User is not logged into Centurion.
ValueError: Could not determin the view action.
Returns:
@ -87,20 +111,35 @@ class OrganizationPermissionMixin(
if request.user.is_anonymous:
return False
raise centurion_exceptions.NotAuthenticated()
try:
view.get_user_organizations( request.user )
has_permission_required: bool = False
user_permissions = getattr(view, '_user_permissions', None)
permission_required = view.get_permission_required()
has_permission_required: bool = permission_required in getattr(view, '_user_permissions', [])
if not has_permission_required and not request.user.is_superuser:
if permission_required and user_permissions:
# No permission_required couldnt get permissions
# No user_permissions, user missing the required permission
return False
has_permission_required: bool = permission_required in user_permissions
if request.method not in view.allowed_methods:
raise centurion_exceptions.MethodNotAllowed(method = request.method)
elif not has_permission_required and not request.user.is_superuser:
raise centurion_exceptions.PermissionDenied()
obj_organization: Organization = view.get_obj_organization(
@ -196,13 +235,23 @@ class OrganizationPermissionMixin(
except ValueError as e:
# ToDo: This exception could be used in traces as it provides
# information as to dodgy requests
# information as to dodgy requests. This exception is raised
# when the method does not match the view action.
print(traceback.format_exc())
except centurion_exceptions.ObjectDoesNotExist as e:
# This exception genrally means that the user is not in the same
# organization as the object as objects are filtered to users
# organizations ONLY.
pass
except Exception as e:
except centurion_exceptions.PermissionDenied as e:
# This Exception will be raised after this function has returned
# False.
print(traceback.format_exc())
pass
return False