Files
octopus/myproject/user_roles/decorators.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

41 lines
1.3 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 functools import wraps
from django.http import HttpResponseForbidden
from django.shortcuts import redirect
from django.contrib import messages
from user_roles.services import RoleService
def role_required(*role_codes):
"""
Декоратор для проверки роли пользователя.
Использование:
@role_required('owner', 'manager')
def my_view(request):
...
"""
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if not request.user.is_authenticated:
return redirect('login')
if RoleService.user_has_role(request.user, *role_codes):
return view_func(request, *args, **kwargs)
messages.error(request, 'У вас нет прав для выполнения этого действия.')
return HttpResponseForbidden('Access denied')
return wrapper
return decorator
def owner_required(view_func):
"""Декоратор для проверки роли Владелец"""
return role_required('owner')(view_func)
def manager_or_owner_required(view_func):
"""Декоратор для проверки роли Менеджер или Владелец"""
return role_required('owner', 'manager')(view_func)