37769-vm/core/permissions.py
2026-02-01 21:17:19 +00:00

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