from django.contrib import admin from django.contrib.auth.mixins import AccessMixin from django.core.exceptions import PermissionDenied from user_roles.services import RoleService class RoleBasedAdminMixin: """ Миксин для ModelAdmin с проверкой ролей. Использование: class MyAdmin(RoleBasedAdminMixin, admin.ModelAdmin): required_roles = ['owner', 'manager'] """ required_roles = [] # Роли, которые имеют доступ def has_module_permission(self, request): """Проверка доступа к модулю""" if not super().has_module_permission(request): return False # Superuser имеет полный доступ if request.user.is_superuser: return True if not self.required_roles: return True # Нет ограничений return RoleService.user_has_role(request.user, *self.required_roles) def has_view_permission(self, request, obj=None): """Проверка доступа на просмотр""" if not super().has_view_permission(request, obj): return False # Superuser имеет полный доступ if request.user.is_superuser: return True if not self.required_roles: return True return RoleService.user_has_role(request.user, *self.required_roles) def has_add_permission(self, request): """Проверка доступа на добавление""" if not super().has_add_permission(request): return False # Superuser имеет полный доступ if request.user.is_superuser: return True if not self.required_roles: return True return RoleService.user_has_role(request.user, *self.required_roles) def has_change_permission(self, request, obj=None): """Проверка доступа на изменение""" if not super().has_change_permission(request, obj): return False # Superuser имеет полный доступ if request.user.is_superuser: return True if not self.required_roles: return True return RoleService.user_has_role(request.user, *self.required_roles) def has_delete_permission(self, request, obj=None): """Проверка доступа на удаление""" if not super().has_delete_permission(request, obj): return False # Superuser имеет полный доступ if request.user.is_superuser: return True if not self.required_roles: return True return RoleService.user_has_role(request.user, *self.required_roles) class OwnerOnlyAdminMixin(RoleBasedAdminMixin): """Миксин для админки, доступной только владельцу""" required_roles = ['owner'] class ManagerOwnerAdminMixin(RoleBasedAdminMixin): """Миксин для админки, доступной менеджеру и владельцу""" required_roles = ['owner', 'manager'] # Миксины для обычных views (не админки) class RoleRequiredMixin(AccessMixin): """ Миксин для проверки ролей в обычных CBV. Использование: class MyView(RoleRequiredMixin, ListView): required_roles = ['owner', 'manager'] """ required_roles = [] # Список ролей, которым разрешен доступ def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: return self.handle_no_permission() # Superuser имеет полный доступ if request.user.is_superuser: return super().dispatch(request, *args, **kwargs) # Если роли не указаны, доступ разрешен всем аутентифицированным if not self.required_roles: return super().dispatch(request, *args, **kwargs) # Проверяем роль пользователя if not RoleService.user_has_role(request.user, *self.required_roles): raise PermissionDenied("У вас нет прав для доступа к этой странице") return super().dispatch(request, *args, **kwargs) class OwnerRequiredMixin(RoleRequiredMixin): """Миксин для view, доступного только владельцу""" required_roles = ['owner'] class ManagerOwnerRequiredMixin(RoleRequiredMixin): """Миксин для view, доступного менеджеру и владельцу""" required_roles = ['owner', 'manager']