Files
centurion_erp/app/access/middleware/request.py

161 lines
3.8 KiB
Python

import django
from django.contrib.auth.models import Group
from django.utils.deprecation import MiddlewareMixin
from access.models.tenant import Tenant
from access.models.team import Team
from settings.models.app_settings import AppSettings
User = django.contrib.auth.get_user_model()
class RequestTenancy(MiddlewareMixin):
"""Access Middleware
Serves the purpose of adding the users tenancy details to rhe request
object.
"""
def process_request(self, request):
request.app_settings = AppSettings.objects.select_related('global_organization').filter(
owner_organization = None
)[0]
request.tenancy = Tenancy(user = request.user, app_settings = request.app_settings)
class Tenancy:
user: User = None
groups: list([Group]) = None
_app_settings: AppSettings = None
_user_organizations: list([Tenant]) = None
"""Cached User Tenants"""
_user_teams: list([Team]) = None
"""Cached User Teams"""
_user_permissions: list([str]) = None
"""Cached User User Permissions"""
def __init__(self, user: User, app_settings: AppSettings):
self.user = user
self. _app_settings = app_settings
self.groups = user.groups.select_related('team', 'team__organization').prefetch_related('team__permissions__content_type')
self._user_organizations = []
self._user_groups = []
self._user_teams = []
self._user_permissions = []
for group in self.groups:
if group.team not in self._user_teams:
self._user_teams += [ group.team ]
for permission in group.team.permissions.all():
permission_value = str( permission.content_type.app_label + '.' + permission.codename )
if permission_value not in self._user_permissions:
self._user_permissions += [ permission_value ]
if group.team.organization not in self._user_organizations:
self._user_organizations += [ group.team.organization ]
def is_member(self, organization: Tenant) -> bool:
"""Returns true if the current user is a member of the organization
iterates over the user_organizations list and returns true if the user is a member
Returns:
bool: _description_
"""
is_member: bool = False
if organization is None:
return False
if int(organization) in self._user_organizations:
is_member = True
return is_member
def has_organization_permission(self, organization: Tenant, permissions_required: str) -> bool:
""" Check if user has permission within organization.
Args:
organization (int): Tenant to check.
permissions_required (list): if doing object level permissions, pass in required permission.
Returns:
bool: True for yes.
"""
has_permission: bool = False
if type(organization) is not Tenant:
raise TypeError('Tenant must be of type Tenant')
if type(permissions_required) is not str:
raise TypeError('permissions_required must be of type str')
if not organization:
return has_permission
for team in self._user_teams:
if(
team.organization.id == int(organization)
or getattr(self._app_settings.global_organization, 'id', 0) == int(organization)
):
for permission in team.permissions.all():
assembled_permission = str(permission.content_type.app_label) + '.' + str( permission.codename )
if assembled_permission == permissions_required:
has_permission = True
return has_permission