281 lines
8.7 KiB
Python
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
|