feat: implement role-based permissions for product views

- Add view mixins (RoleRequiredMixin, OwnerRequiredMixin, ManagerOwnerRequiredMixin) to user_roles/mixins.py
- Replace PermissionRequiredMixin with ManagerOwnerRequiredMixin in all product views
- Remove permission_required attributes from view classes
- Owner and Manager roles now grant access without Django model permissions

This allows owners to access all product functionality through their custom role,
without needing to be superusers or have explicit Django permissions.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-01 22:44:36 +03:00
parent 52baf4295f
commit ffc3b0c42d
5 changed files with 65 additions and 33 deletions

View File

@@ -1,4 +1,5 @@
from django.contrib import admin
from django.contrib.auth.mixins import AccessMixin
from django.core.exceptions import PermissionDenied
from user_roles.services import RoleService
@@ -92,3 +93,44 @@ class OwnerOnlyAdminMixin(RoleBasedAdminMixin):
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']