HH/apps/accounts/permissions.py
2026-01-06 13:36:43 +03:00

281 lines
8.7 KiB
Python

"""
Accounts permissions - RBAC permission classes
"""
from rest_framework import permissions
class IsPXAdmin(permissions.BasePermission):
"""
Permission class to check if user is PX Admin.
PX Admins have full system access.
"""
message = "You must be a PX Admin to perform this action."
def has_permission(self, request, view):
return request.user and request.user.is_authenticated and request.user.is_px_admin()
class IsHospitalAdmin(permissions.BasePermission):
"""
Permission class to check if user is Hospital Admin.
Hospital Admins have access to their hospital's data.
"""
message = "You must be a Hospital Admin to perform this action."
def has_permission(self, request, view):
return request.user and request.user.is_authenticated and request.user.is_hospital_admin()
class IsDepartmentManager(permissions.BasePermission):
"""
Permission class to check if user is Department Manager.
Department Managers have access to their department's data.
"""
message = "You must be a Department Manager to perform this action."
def has_permission(self, request, view):
return request.user and request.user.is_authenticated and request.user.is_department_manager()
class IsPXAdminOrHospitalAdmin(permissions.BasePermission):
"""
Permission class for PX Admin or Hospital Admin.
"""
message = "You must be a PX Admin or Hospital Admin to perform this action."
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
return request.user.is_px_admin() or request.user.is_hospital_admin()
class IsPXAdminOrReadOnly(permissions.BasePermission):
"""
Permission class that allows PX Admins full access,
but only read access for others.
"""
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
# Read permissions for any authenticated user
if request.method in permissions.SAFE_METHODS:
return True
# Write permissions only for PX Admins
return request.user.is_px_admin()
class IsOwnerOrPXAdmin(permissions.BasePermission):
"""
Permission class that allows users to access their own data,
or PX Admins to access any data.
"""
def has_object_permission(self, request, view, obj):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins can access anything
if request.user.is_px_admin():
return True
# Users can access their own data
if hasattr(obj, 'user'):
return obj.user == request.user
return obj == request.user
class HasRolePermission(permissions.BasePermission):
"""
Permission class that checks if user has specific role.
Usage: Set required_roles on the view.
"""
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
required_roles = getattr(view, 'required_roles', [])
if not required_roles:
return True
user_roles = request.user.get_role_names()
return any(role in user_roles for role in required_roles)
class CanAccessHospitalData(permissions.BasePermission):
"""
Permission class that checks if user can access hospital data.
- PX Admins can access all hospitals
- Hospital Admins can access their own hospital
- Department Managers can access their hospital
"""
def has_object_permission(self, request, view, obj):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins can access all
if request.user.is_px_admin():
return True
# Get hospital from object
hospital = None
if hasattr(obj, 'hospital'):
hospital = obj.hospital
elif obj.__class__.__name__ == 'Hospital':
hospital = obj
if not hospital:
return False
# Check if user belongs to this hospital
return request.user.hospital == hospital
class CanAccessDepartmentData(permissions.BasePermission):
"""
Permission class that checks if user can access department data.
- PX Admins can access all departments
- Hospital Admins can access departments in their hospital
- Department Managers can access their own department
"""
def has_object_permission(self, request, view, obj):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins can access all
if request.user.is_px_admin():
return True
# Get department from object
department = None
if hasattr(obj, 'department'):
department = obj.department
elif obj.__class__.__name__ == 'Department':
department = obj
if not department:
return False
# Hospital Admins can access departments in their hospital
if request.user.is_hospital_admin() and request.user.hospital == department.hospital:
return True
# Department Managers can access their own department
if request.user.is_department_manager() and request.user.department == department:
return True
return False
# ==================== Onboarding Permissions ====================
class IsProvisionalUser(permissions.BasePermission):
"""
Permission class to check if user is provisional (in onboarding).
"""
message = "You must be a provisional user to access this resource."
def has_permission(self, request, view):
return (
request.user and
request.user.is_authenticated and
request.user.is_provisional and
not request.user.acknowledgement_completed
)
class CanViewOnboarding(permissions.BasePermission):
"""
Permission class for viewing onboarding content.
- Provisional users can view their own onboarding
- PX Admins can view all onboarding data
"""
message = "You do not have permission to view onboarding data."
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
# Provisional users can view their own
if request.user.is_provisional:
return True
# PX Admins can view all
if request.user.is_px_admin():
return True
return False
class CanManageOnboarding(permissions.BasePermission):
"""
Permission class for managing onboarding.
- PX Admins have full access
- Hospital Admins can manage onboarding for their hospital
"""
message = "You must be a PX Admin or Hospital Admin to manage onboarding."
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins have full access
if request.user.is_px_admin():
return True
# Hospital Admins can manage their hospital
if request.user.is_hospital_admin():
return True
return False
class IsOnboardingOwnerOrAdmin(permissions.BasePermission):
"""
Permission class for onboarding object access.
- Users can access their own onboarding data
- PX Admins can access all
"""
def has_object_permission(self, request, view, obj):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins can access all
if request.user.is_px_admin():
return True
# Users can access their own data
if hasattr(obj, 'user'):
return obj.user == request.user
return obj == request.user
class CanManageAcknowledgementContent(permissions.BasePermission):
"""
Permission class for managing acknowledgement content and checklist items.
Only PX Admins can manage these.
"""
message = "Only PX Admins can manage acknowledgement content."
def has_permission(self, request, view):
if not (request.user and request.user.is_authenticated):
return False
# PX Admins can manage content
if request.user.is_px_admin():
return True
# Read-only for others
if request.method in permissions.SAFE_METHODS:
return True
return False