197 lines
4.9 KiB
Python
197 lines
4.9 KiB
Python
from django.contrib.auth.models import Permission, User
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
from access.models.tenant import Tenant
|
|
|
|
|
|
|
|
class CenturionUser(
|
|
User,
|
|
):
|
|
"""Centurion User
|
|
|
|
A Multi-Tenant User wirh permission Checking.
|
|
|
|
ToDo:
|
|
- Add to Roles user field `related_name = roles`
|
|
- Add to Roles group field `related_name = roles`
|
|
# - have group lookup prefetch related roles__permissions
|
|
- have user lookup prefetch related roles__permissions and groups__roles__permissions
|
|
|
|
Args:
|
|
User (Model): Django Base User
|
|
"""
|
|
|
|
_tenancies: list[Tenant] = None
|
|
|
|
_tenancies_int: list[int] = None
|
|
|
|
_permissions: list[Permission] = None
|
|
|
|
_permissions_by_tenancy: dict[ str, list[ Permission ] ] = None
|
|
"""Permissions by Tenancy
|
|
|
|
`{ 'tenancy_{id}': [ Permission ] }`
|
|
"""
|
|
|
|
# EMAIL_FIELD = 'email' # Update contact email field name so it's different to the user model.
|
|
|
|
# REQUIRED_FIELDS = [
|
|
# EMAIL_FIELD,
|
|
# 'f_name',
|
|
# 'l_name',
|
|
# ]
|
|
|
|
class Meta:
|
|
abstract = False
|
|
proxy = True # User will be linked to Employee/Customer entity via related_name from the entity.
|
|
# ToDo: refactory Employee/Customer to inherit from a new model. entity_user
|
|
|
|
verbose_name = 'Centurion User'
|
|
|
|
verbose_name_plural = 'Centurion Users'
|
|
|
|
|
|
|
|
def get_full_name(self) -> str:
|
|
return f'{self.entity_user.f_name} {self.entity_user.l_name}'
|
|
|
|
|
|
|
|
def get_group_permissions(self, tenancy: bool = True) -> dict[ str, list[ Permission ] ] | list[ Permission ]:
|
|
""" Get the Users Permissions
|
|
|
|
Args:
|
|
tenancy (bool, optional): Return permission in list. Defaults to True.
|
|
|
|
Returns:
|
|
dict[ str, list[ Permission ] ]: Permissions listed by tenancy
|
|
list[ Permission ]: All Permissions
|
|
"""
|
|
|
|
for group in self.groups: # pylint: disable=E1133:not-an-iterable
|
|
|
|
for role in group.roles:
|
|
pass
|
|
|
|
# role.get_permissions()
|
|
|
|
|
|
|
|
def get_permissions(self, tenancy: bool = True) -> dict[ str, list[ Permission ] ] | list[ Permission ]:
|
|
""" Get the Users Permissions
|
|
|
|
Args:
|
|
tenancy (bool, optional): Return permission in list. Defaults to True.
|
|
|
|
Returns:
|
|
dict[ str, list[ Permission ] ]: Permissions listed by tenancy
|
|
list[ Permission ]: All Permissions
|
|
"""
|
|
|
|
# also get group permissions. self.get_group_permissions()
|
|
|
|
for role in self.roles:
|
|
pass
|
|
|
|
# role.get_permissions()
|
|
|
|
# also populate `self._tenancies` and `self._tenancies_int`
|
|
|
|
return []
|
|
|
|
|
|
|
|
def get_short_name() -> str:
|
|
return self.entity_user.f_name
|
|
|
|
|
|
|
|
def get_tenancies(self, int_list = False) -> list[ Tenant ] | list[ int ]:
|
|
"""Get the Tenancies the user is in.
|
|
|
|
Args:
|
|
int_list (bool, optional): Return Tenancy list as int values. Defaults to False.
|
|
|
|
Returns:
|
|
list[ Tenant ] | list[ int ]: All Tenancies the user is in.
|
|
"""
|
|
|
|
if self._tenancies is None:
|
|
|
|
if self._permissions is None:
|
|
self.get_permissions
|
|
|
|
tenancies: list = []
|
|
tenancies_int: list = []
|
|
|
|
for role in self.roles:
|
|
|
|
if role.organization in tenancies:
|
|
continue
|
|
|
|
tenancies += [ role.organization ]
|
|
tenancies_int += [ role.organization.id ]
|
|
|
|
self._tenancies = tenancies
|
|
self._tenancies_int = tenancies_int
|
|
|
|
|
|
if as_int_list:
|
|
return self._tenancies_int
|
|
|
|
return self._tenancies
|
|
|
|
|
|
|
|
def has_module_perms(self, app_label): # is this needed?
|
|
|
|
# if has app_label in perms
|
|
|
|
raise PermissionDenied
|
|
|
|
|
|
|
|
def has_perm(self, permission: Permission, obj = None, tenancy: Tenant = None) -> bool:
|
|
|
|
if(
|
|
obj is None
|
|
and tenancy is None
|
|
):
|
|
raise ValueError('Both obj and tenancy cant be None')
|
|
|
|
if tenancy is None:
|
|
tenancy = obj.organization
|
|
|
|
# if self.has_tenancy_permission(perm, tenancy):
|
|
# for tenancy, permissions in self.get_permissions().items()
|
|
|
|
if tenancy is None:
|
|
raise ValueError('tenancy cant be None')
|
|
|
|
permissions = self.get_permissions()
|
|
|
|
if f'tenancy_{tenancy.id}' not in permissions:
|
|
raise PermissionDenied
|
|
|
|
|
|
for tenancy, permissions in self.get_permissions().items():
|
|
|
|
if(
|
|
tenancy == f'tenancy_{tenancy.id}'
|
|
and perm in permissions
|
|
):
|
|
return True
|
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
|
|
|
def has_perms(self, permission_list: list[ Permission ], obj = None, tenancy: Tenant = None):
|
|
|
|
for perm in perm_list:
|
|
|
|
self.has_perm( perm, obj )
|
|
|
|
return True |