117 lines
3.6 KiB
Python
117 lines
3.6 KiB
Python
from functools import wraps
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.shortcuts import redirect
|
|
from django.contrib import messages
|
|
from .models import TenantUserRole
|
|
|
|
# Allowed roles for staff/admin actions
|
|
STAFF_ROLES = [
|
|
'admin', 'campaign_manager', 'campaign_staff',
|
|
'system_admin', 'campaign_admin'
|
|
]
|
|
|
|
def get_user_role(user, tenant):
|
|
if user.is_superuser:
|
|
return 'admin'
|
|
role_obj = TenantUserRole.objects.filter(user=user, tenant=tenant).first()
|
|
if role_obj:
|
|
return role_obj.role
|
|
return None
|
|
|
|
def has_role(user, tenant, roles):
|
|
if user.is_superuser:
|
|
return True
|
|
if not tenant:
|
|
return False
|
|
user_role = get_user_role(user, tenant)
|
|
return user_role in roles
|
|
|
|
def is_block_walker(user):
|
|
return user.groups.filter(name='Block Walker').exists()
|
|
|
|
def can_view_voters(user, tenant):
|
|
if user.has_perm("core.view_voter"):
|
|
return True
|
|
if user.is_superuser:
|
|
return True
|
|
# If they can edit, they can view
|
|
if can_edit_voter(user, tenant):
|
|
return True
|
|
# All authenticated users with a tenant role can usually view voters in our app
|
|
# but we should restrict it if they have NO role and NO permission.
|
|
role = get_user_role(user, tenant)
|
|
if role: # Any role (even if not in STAFF_ROLES) allows viewing voters?
|
|
# Block Walkers don't have a TenantUserRole usually, they have a Group.
|
|
return True
|
|
return False
|
|
|
|
def can_view_donations(user, tenant):
|
|
if user.has_perm("core.view_donation"):
|
|
return True
|
|
if user.is_superuser:
|
|
return True
|
|
role = get_user_role(user, tenant)
|
|
if role in STAFF_ROLES:
|
|
return True
|
|
return False
|
|
|
|
def can_edit_voter(user, tenant):
|
|
if user.has_perm("core.change_voter"):
|
|
return True
|
|
if user.is_superuser:
|
|
return True
|
|
role = get_user_role(user, tenant)
|
|
if role in STAFF_ROLES:
|
|
return True
|
|
return False
|
|
|
|
def can_view_volunteers(user, tenant):
|
|
if user.has_perm("core.view_volunteer"):
|
|
return True
|
|
if user.is_superuser:
|
|
return True
|
|
role = get_user_role(user, tenant)
|
|
if role in STAFF_ROLES:
|
|
return True
|
|
return False
|
|
|
|
def can_edit_volunteer(user, tenant):
|
|
if user.has_perm("core.change_volunteer"):
|
|
return True
|
|
if user.is_superuser:
|
|
return True
|
|
role = get_user_role(user, tenant)
|
|
if role in STAFF_ROLES:
|
|
return True
|
|
return False
|
|
|
|
def role_required(roles, permission=None):
|
|
def decorator(view_func):
|
|
@wraps(view_func)
|
|
def _wrapped_view(request, *args, **kwargs):
|
|
from .models import Tenant
|
|
tenant_id = request.session.get('tenant_id')
|
|
if not tenant_id:
|
|
if request.user.is_superuser:
|
|
return view_func(request, *args, **kwargs)
|
|
messages.warning(request, "Please select a campaign first.")
|
|
return redirect('index')
|
|
|
|
tenant = Tenant.objects.filter(id=tenant_id).first()
|
|
if not tenant:
|
|
messages.warning(request, "Campaign not found.")
|
|
return redirect('index')
|
|
|
|
# Check roles first
|
|
if has_role(request.user, tenant, roles):
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
# Check for specific permission if provided
|
|
if permission and request.user.has_perm(permission):
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
messages.error(request, "You do not have permission to perform this action.")
|
|
return redirect('index')
|
|
return _wrapped_view
|
|
return decorator
|