161 lines
3.8 KiB
Python
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
|