237 lines
6.8 KiB
Python
237 lines
6.8 KiB
Python
"""
|
|
Role-based access control decorators for PX360.
|
|
|
|
Provides decorators to restrict views based on user roles:
|
|
- PX Admin
|
|
- Hospital Admin
|
|
- Department Manager
|
|
- PX Coordinator
|
|
- Source User
|
|
"""
|
|
from functools import wraps
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.shortcuts import redirect
|
|
from django.contrib import messages
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
def px_admin_required(view_func):
|
|
"""
|
|
Decorator to restrict access to PX Admins only.
|
|
|
|
Example:
|
|
@px_admin_required
|
|
def system_settings(request):
|
|
# Only PX Admins can access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if not request.user.is_px_admin():
|
|
messages.error(
|
|
request,
|
|
_("Access denied. PX Admin privileges required.")
|
|
)
|
|
return redirect('analytics:command_center')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def hospital_admin_required(view_func):
|
|
"""
|
|
Decorator to restrict access to Hospital Admins and PX Admins.
|
|
|
|
Example:
|
|
@hospital_admin_required
|
|
def hospital_settings(request):
|
|
# Only Hospital Admins and PX Admins can access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
|
|
messages.error(
|
|
request,
|
|
_("Access denied. Hospital Admin privileges required.")
|
|
)
|
|
return redirect('analytics:command_center')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def admin_required(view_func):
|
|
"""
|
|
Decorator to restrict access to any Admin (PX, Hospital, or Dept Manager).
|
|
|
|
Example:
|
|
@admin_required
|
|
def management_view(request):
|
|
# Any admin can access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if not (request.user.is_px_admin() or
|
|
request.user.is_hospital_admin() or
|
|
request.user.is_department_manager()):
|
|
messages.error(
|
|
request,
|
|
_("Access denied. Admin privileges required.")
|
|
)
|
|
return redirect('analytics:command_center')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def px_coordinator_required(view_func):
|
|
"""
|
|
Decorator to restrict access to PX Coordinators and above.
|
|
|
|
Allows: PX Admin, Hospital Admin, Department Manager, PX Coordinator
|
|
|
|
Example:
|
|
@px_coordinator_required
|
|
def complaint_management(request):
|
|
# Coordinators and admins can access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
user = request.user
|
|
if not (user.is_px_admin() or
|
|
user.is_hospital_admin() or
|
|
user.is_department_manager() or
|
|
user.has_role('PX Coordinator')):
|
|
messages.error(
|
|
request,
|
|
_("Access denied. PX Coordinator privileges required.")
|
|
)
|
|
return redirect('analytics:command_center')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def staff_required(view_func):
|
|
"""
|
|
Decorator to restrict access to Hospital Staff (not Source Users).
|
|
|
|
Allows all authenticated users except Source Users.
|
|
|
|
Example:
|
|
@staff_required
|
|
def internal_tool(request):
|
|
# Any hospital staff can access, but not source users
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if request.user.is_source_user():
|
|
messages.error(
|
|
request,
|
|
_("Access denied. This page is not available for source users.")
|
|
)
|
|
return redirect('px_sources:source_user_dashboard')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def source_user_required(view_func):
|
|
"""
|
|
Decorator to restrict access to Source Users only.
|
|
|
|
Example:
|
|
@source_user_required
|
|
def source_user_dashboard(request):
|
|
# Only source users can access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if not request.user.is_source_user():
|
|
raise PermissionDenied(
|
|
_("Access denied. Source user privileges required.")
|
|
)
|
|
|
|
# Get source user profile
|
|
profile = request.user.get_source_user_profile_active()
|
|
if not profile:
|
|
messages.error(
|
|
request,
|
|
_("Your source user account is inactive. Please contact your administrator.")
|
|
)
|
|
return redirect('accounts:login')
|
|
|
|
# Store in request for easy access
|
|
request.source_user = profile
|
|
request.source = profile.source
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def block_source_user(view_func):
|
|
"""
|
|
Decorator to BLOCK source users from accessing admin/staff pages.
|
|
Redirects source users to their dashboard instead.
|
|
|
|
Example:
|
|
@block_source_user
|
|
def staff_management(request):
|
|
# Source users CANNOT access this
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
if request.user.is_source_user():
|
|
# Silently redirect to source user dashboard
|
|
return redirect('px_sources:source_user_dashboard')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
return _wrapped_view
|
|
|
|
|
|
def source_user_or_admin(view_func):
|
|
"""
|
|
Decorator that allows both source users AND admins.
|
|
|
|
Example:
|
|
@source_user_or_admin
|
|
def complaint_detail(request, pk):
|
|
# Both source users and admins can view
|
|
"""
|
|
@wraps(view_func)
|
|
@login_required
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
user = request.user
|
|
|
|
# Allow admins
|
|
if (user.is_px_admin() or
|
|
user.is_hospital_admin() or
|
|
user.is_department_manager()):
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
# Allow active source users
|
|
if user.is_source_user():
|
|
profile = user.get_source_user_profile_active()
|
|
if profile:
|
|
request.source_user = profile
|
|
request.source = profile.source
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
raise PermissionDenied(_("Access denied."))
|
|
|
|
return _wrapped_view
|