Files
octopus/myproject/user_roles/mixins.py
Andrey Smakotin f4e7ad0aac feat: implement user roles system with tenant isolation
Добавлена система ролей пользователей для управления доступом в multi-tenant приложении.

Новые роли:
- Владелец (Owner): полный доступ, управление пользователями
- Менеджер (Manager): управление заказами, клиентами, товарами, складом
- Флорист (Florist): работа с заказами и складскими операциями
- Курьер (Courier): роль создана, права будут определены позже

Архитектура:
- Роли автоматически изолируются по тенантам через django-tenants (TENANT_APPS)
- Не требуется FK на Client/Tenant - изоляция через PostgreSQL schemas
- Роли автоматически создаются при создании нового тенанта

Компоненты:
- user_roles/models.py: модели Role и UserRole
- user_roles/services.py: RoleService для управления ролями
- user_roles/decorators.py: @role_required, @owner_required
- user_roles/mixins.py: RoleBasedAdminMixin, OwnerOnlyAdminMixin
- user_roles/admin.py: админка для управления ролями
- user_roles/management/commands/init_roles.py: команда для инициализации

Изменения:
- accounts/models.py: добавлены helper методы (is_owner, has_role, etc)
- settings.py: добавлен user_roles в TENANT_APPS
- tenants/admin.py: автосоздание ролей при создании тенанта

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 18:06:47 +03:00

75 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.contrib import admin
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
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
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
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
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
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']