164 lines
5.8 KiB
Python
164 lines
5.8 KiB
Python
from functools import wraps
|
|
from datetime import date
|
|
from django.shortcuts import redirect, get_object_or_404
|
|
from django.http import HttpResponseNotFound, HttpResponseForbidden
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib.auth.mixins import AccessMixin
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.contrib import messages
|
|
|
|
def job_not_expired(view_func):
|
|
@wraps(view_func)
|
|
def _wrapped_view(request, job_id, *args, **kwargs):
|
|
|
|
from .models import JobPosting
|
|
job = get_object_or_404(JobPosting, pk=job_id)
|
|
|
|
if job.expiration_date and job.application_deadline< date.today():
|
|
return redirect('expired_job_page')
|
|
|
|
return view_func(request, job_id, *args, **kwargs)
|
|
return _wrapped_view
|
|
|
|
|
|
def user_type_required(allowed_types=None, login_url=None):
|
|
"""
|
|
Decorator to restrict view access based on user type.
|
|
|
|
Args:
|
|
allowed_types (list): List of allowed user types ['staff', 'agency', 'candidate']
|
|
login_url (str): URL to redirect to if user is not authenticated
|
|
"""
|
|
if allowed_types is None:
|
|
allowed_types = ['staff']
|
|
|
|
def decorator(view_func):
|
|
@wraps(view_func)
|
|
@login_required(login_url=login_url)
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
user = request.user
|
|
|
|
# Check if user has user_type attribute
|
|
if not hasattr(user, 'user_type') or not user.user_type:
|
|
messages.error(request, "User type not specified. Please contact administrator.")
|
|
return redirect('portal_login')
|
|
|
|
# Check if user type is allowed
|
|
if user.user_type not in allowed_types:
|
|
# Log unauthorized access attempt
|
|
messages.error(
|
|
request,
|
|
f"Access denied. This page is restricted to {', '.join(allowed_types)} users."
|
|
)
|
|
|
|
# Redirect based on user type
|
|
if user.user_type == 'agency':
|
|
return redirect('agency_portal_dashboard')
|
|
elif user.user_type == 'candidate':
|
|
return redirect('candidate_portal_dashboard')
|
|
else:
|
|
return redirect('dashboard')
|
|
|
|
return view_func(request, *args, **kwargs)
|
|
return _wrapped_view
|
|
return decorator
|
|
|
|
|
|
class UserTypeRequiredMixin(AccessMixin):
|
|
"""
|
|
Mixin for class-based views to restrict access based on user type.
|
|
"""
|
|
allowed_user_types = ['staff'] # Default to staff only
|
|
login_url = '/login/'
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if not request.user.is_authenticated:
|
|
return self.handle_no_permission()
|
|
|
|
# Check if user has user_type attribute
|
|
if not hasattr(request.user, 'user_type') or not request.user.user_type:
|
|
messages.error(request, "User type not specified. Please contact administrator.")
|
|
return redirect('portal_login')
|
|
|
|
# Check if user type is allowed
|
|
if request.user.user_type not in self.allowed_user_types:
|
|
# Log unauthorized access attempt
|
|
messages.error(
|
|
request,
|
|
f"Access denied. This page is restricted to {', '.join(self.allowed_user_types)} users."
|
|
)
|
|
|
|
# Redirect based on user type
|
|
if request.user.user_type == 'agency':
|
|
return redirect('agency_portal_dashboard')
|
|
elif request.user.user_type == 'candidate':
|
|
return redirect('candidate_portal_dashboard')
|
|
else:
|
|
return redirect('dashboard')
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def handle_no_permission(self):
|
|
if self.request.user.is_authenticated:
|
|
# User is authenticated but doesn't have permission
|
|
messages.error(
|
|
self.request,
|
|
f"Access denied. This page is restricted to {', '.join(self.allowed_user_types)} users."
|
|
)
|
|
return redirect('dashboard')
|
|
else:
|
|
# User is not authenticated
|
|
return super().handle_no_permission()
|
|
|
|
|
|
class StaffRequiredMixin(UserTypeRequiredMixin):
|
|
"""Mixin to restrict access to staff users only."""
|
|
allowed_user_types = ['staff']
|
|
|
|
|
|
class AgencyRequiredMixin(UserTypeRequiredMixin):
|
|
"""Mixin to restrict access to agency users only."""
|
|
allowed_user_types = ['agency']
|
|
login_url = '/portal/login/'
|
|
|
|
|
|
class CandidateRequiredMixin(UserTypeRequiredMixin):
|
|
"""Mixin to restrict access to candidate users only."""
|
|
allowed_user_types = ['candidate']
|
|
login_url = '/portal/login/'
|
|
|
|
|
|
class StaffOrAgencyRequiredMixin(UserTypeRequiredMixin):
|
|
"""Mixin to restrict access to staff and agency users."""
|
|
allowed_user_types = ['staff', 'agency']
|
|
|
|
|
|
class StaffOrCandidateRequiredMixin(UserTypeRequiredMixin):
|
|
"""Mixin to restrict access to staff and candidate users."""
|
|
allowed_user_types = ['staff', 'candidate']
|
|
|
|
|
|
def agency_user_required(view_func):
|
|
"""Decorator to restrict view to agency users only."""
|
|
return user_type_required(['agency'], login_url='/portal/login/')(view_func)
|
|
|
|
|
|
def candidate_user_required(view_func):
|
|
"""Decorator to restrict view to candidate users only."""
|
|
return user_type_required(['candidate'], login_url='/portal/login/')(view_func)
|
|
|
|
|
|
def staff_user_required(view_func):
|
|
"""Decorator to restrict view to staff users only."""
|
|
return user_type_required(['staff'])(view_func)
|
|
|
|
|
|
def staff_or_agency_required(view_func):
|
|
"""Decorator to restrict view to staff and agency users."""
|
|
return user_type_required(['staff', 'agency'], login_url='/portal/login/')(view_func)
|
|
|
|
|
|
def staff_or_candidate_required(view_func):
|
|
"""Decorator to restrict view to staff and candidate users."""
|
|
return user_type_required(['staff', 'candidate'], login_url='/portal/login/')(view_func)
|