160 lines
4.6 KiB
Python
160 lines
4.6 KiB
Python
"""
|
|
DRF Permissions for PX Source User access control.
|
|
|
|
Provides permission classes to restrict API access based on user role:
|
|
- Source users can only access their own data
|
|
- Admins have full access
|
|
"""
|
|
from rest_framework import permissions
|
|
from apps.px_sources.models import SourceUser
|
|
|
|
|
|
class IsSourceUser(permissions.BasePermission):
|
|
"""
|
|
Allow access only to active source users.
|
|
|
|
Use this on views that should ONLY be accessible to source users.
|
|
|
|
Example:
|
|
permission_classes = [IsSourceUser]
|
|
"""
|
|
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
|
|
# Check if user has source user profile
|
|
if not hasattr(request.user, 'source_user_profile'):
|
|
return False
|
|
|
|
# Check if source user is active
|
|
source_user = request.user.source_user_profile
|
|
return source_user.is_active
|
|
|
|
|
|
class IsSourceUserOrAdmin(permissions.BasePermission):
|
|
"""
|
|
Allow access to source users AND admins.
|
|
|
|
Use this on views that should be accessible to:
|
|
- Active source users
|
|
- PX Admins, Hospital Admins, Department Managers
|
|
|
|
Example:
|
|
permission_classes = [IsSourceUserOrAdmin]
|
|
"""
|
|
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
|
|
# Allow admins
|
|
if request.user.is_superuser or request.user.is_px_admin():
|
|
return True
|
|
|
|
# Allow hospital admins
|
|
if request.user.is_hospital_admin():
|
|
return True
|
|
|
|
# Allow active source users
|
|
if hasattr(request.user, 'source_user_profile'):
|
|
source_user = request.user.source_user_profile
|
|
return source_user.is_active
|
|
|
|
return False
|
|
|
|
|
|
class IsSourceUserOwnData(permissions.BasePermission):
|
|
"""
|
|
Object-level permission to ensure source users can only access their own data.
|
|
|
|
Use this on detail views to ensure source users can only view/edit
|
|
complaints and inquiries from their assigned source.
|
|
|
|
Example:
|
|
permission_classes = [IsSourceUserOrAdmin, IsSourceUserOwnData]
|
|
"""
|
|
|
|
def has_object_permission(self, request, view, obj):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
|
|
# Admins can access everything
|
|
if request.user.is_superuser or request.user.is_px_admin():
|
|
return True
|
|
|
|
# Check if user is a source user
|
|
if not hasattr(request.user, 'source_user_profile'):
|
|
return False
|
|
|
|
source_user = request.user.source_user_profile
|
|
|
|
if not source_user.is_active:
|
|
return False
|
|
|
|
# Check if object belongs to user's source
|
|
if hasattr(obj, 'source'):
|
|
return obj.source == source_user.source
|
|
|
|
# If object doesn't have a source field, deny access
|
|
return False
|
|
|
|
|
|
class IsAdminUser(permissions.BasePermission):
|
|
"""
|
|
Allow access only to admin users (not source users).
|
|
|
|
Use this on admin-only API endpoints.
|
|
|
|
Example:
|
|
permission_classes = [IsAdminUser]
|
|
"""
|
|
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
|
|
# Block pure source users
|
|
if _is_pure_source_user(request.user):
|
|
return False
|
|
|
|
# Allow admins
|
|
return request.user.is_superuser or request.user.is_px_admin() or request.user.is_hospital_admin()
|
|
|
|
|
|
class IsPXAdmin(permissions.BasePermission):
|
|
"""
|
|
Allow access only to PX Admins.
|
|
|
|
Use this on PX Admin-only API endpoints.
|
|
"""
|
|
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
|
|
return request.user.is_px_admin()
|
|
|
|
|
|
def _is_pure_source_user(user):
|
|
"""
|
|
Check if user is ONLY a source user with no admin roles.
|
|
"""
|
|
admin_groups = ['PX Admin', 'Hospital Admin', 'Department Manager']
|
|
|
|
# Check if user has any admin roles
|
|
has_admin_role = user.groups.filter(name__in=admin_groups).exists()
|
|
|
|
if has_admin_role:
|
|
return False
|
|
|
|
# Check if user is a source user
|
|
has_source_user_profile = hasattr(user, 'source_user_profile')
|
|
|
|
if has_source_user_profile:
|
|
source_user = user.source_user_profile
|
|
if source_user.is_active:
|
|
return True
|
|
|
|
return False
|