feat(permissions): centralize workspace role capability checks

This commit is contained in:
2026-04-25 18:48:50 +03:30
parent 5f9d413a57
commit f960ca8221
14 changed files with 925 additions and 222 deletions

View File

@@ -1,6 +1,12 @@
from rest_framework import permissions
from apps.projects.models import ProjectMembership
from rest_framework import permissions
from apps.projects.models import ProjectMembership
from apps.workspaces.services import (
PROJECTS_EDIT,
PROJECTS_VIEW,
PROJECT_MEMBERS_CHANGE_ROLE,
has_project_capability,
)
def get_project_from_obj(obj):
@@ -10,40 +16,44 @@ def get_project_from_obj(obj):
return obj if hasattr(obj, "workspace") else obj.project
class IsProjectMember(permissions.BasePermission):
class IsProjectMember(permissions.BasePermission):
"""
Allows access only to users who have an active membership in the project.
"""
message = "شما عضو این پروژه نیستید."
def has_object_permission(self, request, view, obj):
if not request.user or not request.user.is_authenticated:
return False
project = get_project_from_obj(obj)
return ProjectMembership.objects.filter(
project=project,
user=request.user,
is_active=True,
is_deleted=False
).exists()
class IsProjectManager(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if not request.user or not request.user.is_authenticated:
return False
project = get_project_from_obj(obj)
return has_project_capability(request.user, project, PROJECTS_VIEW)
class IsProjectManager(permissions.BasePermission):
"""
Allows access only to users who are active MANAGERs of the project.
"""
message = "فقط مدیران پروژه مجاز به انجام این عملیات هستند."
def has_object_permission(self, request, view, obj):
if not request.user or not request.user.is_authenticated:
return False
project = get_project_from_obj(obj)
return ProjectMembership.objects.filter(
project=project,
user=request.user,
role=ProjectMembership.Role.MANAGER,
is_active=True,
is_deleted=False
).exists()
def has_object_permission(self, request, view, obj):
if not request.user or not request.user.is_authenticated:
return False
project = get_project_from_obj(obj)
return has_project_capability(request.user, project, PROJECTS_EDIT)
class CanManageProjectMembers(permissions.BasePermission):
message = "Only authorized users can manage project memberships."
def has_object_permission(self, request, view, obj):
if not request.user or not request.user.is_authenticated:
return False
project = get_project_from_obj(obj)
return has_project_capability(
request.user,
project,
PROJECT_MEMBERS_CHANGE_ROLE,
)