Files
centurion_erp/app/access/mixin.py
Jon 857aa7af72 feat(tenancy): Add is_ global field
Allow global item creation where all can access if they have the correct permission

!1
2024-05-14 01:40:31 +09:30

148 lines
4.0 KiB
Python

from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Group
from django.core.exceptions import PermissionDenied
from django.utils.functional import cached_property
from .models import Team
class OrganizationMixin():
"""Base Organization class"""
request = None
user_groups = []
def object_organization(self) -> int:
if 'access.models.Organization' in str(type(self.get_object())):
id = self.get_object().id
else:
id = self.get_object().organization.id
if self.get_object().is_global:
id = 0
return id
def is_member(self, organization: int) -> 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 = False
if organization in self.user_organizations():
return True
return is_member
def get_permission_required(self):
"""
Override of 'PermissionRequiredMixin' method so that this mixin can obtain the required permission.
"""
if self.permission_required is None:
raise ImproperlyConfigured(
f"{self.__class__.__name__} is missing the "
f"permission_required attribute. Define "
f"{self.__class__.__name__}.permission_required, or override "
f"{self.__class__.__name__}.get_permission_required()."
)
if isinstance(self.permission_required, str):
perms = (self.permission_required,)
else:
perms = self.permission_required
return perms
@cached_property
def is_manager(self) -> bool:
""" Returns true if the current user is a member of the organization"""
is_manager = False
return is_manager
def user_organizations(self) -> list():
"""Current Users organizations
Fetches the Organizations the user is apart of.
Get All groups the user is part of, fetch the associated team,
iterate over the results adding the organization ID to a list to be returned.
Args:
request (_type_): Current http request
Returns:
_type_: _description_
"""
user_organizations = []
teams = Team.objects
for group in self.request.user.groups.all():
team = teams.get(pk=group.id)
self.user_groups = self.user_groups + [group.id]
user_organizations = user_organizations + [team.organization.id]
return user_organizations
# ToDo: Ensure that the group has access to item
def has_permission(self) -> bool:
has_permission = False
if self.is_member(self.object_organization()) or self.object_organization() == 0:
groups = Group.objects.filter(pk__in=self.user_groups)
for group in groups:
team = Team.objects.filter(pk=group.id)
team = team.values('organization_id').get()
for permission in group.permissions.values('content_type__app_label', 'codename').all():
assembled_permission = str(permission["content_type__app_label"]) + '.' + str(permission["codename"])
if assembled_permission in self.get_permission_required()[0] and (team['organization_id'] == self.object_organization() or self.object_organization() == 0):
return True
return has_permission
class OrganizationPermission(OrganizationMixin):
"""checking organization membership"""
def dispatch(self, request, *args, **kwargs):
self.request = request
if hasattr(self, 'get_object'):
if not self.has_permission() and not request.user.is_superuser:
raise PermissionDenied('You are not part of this organization')
return super().dispatch(self.request, *args, **kwargs)