Sep 16 - Optimize code, part 1

This commit is contained in:
2026-09-16 10:52:59 -04:00
parent 4212726611
commit 7626287344
22 changed files with 587 additions and 96 deletions
+57 -1
View File
@@ -16,7 +16,7 @@ from datetime import datetime, date, time, timedelta
from functools import wraps
import qrcode
from flask import session, redirect, flash, request, url_for
from flask import session, redirect, flash, request, url_for, jsonify
from user_agents import parse
from extensions import logger_handler
@@ -323,6 +323,62 @@ def staff_or_admin_required(f):
return decorated_function
# Role sets for areas the sidebar only offers to some roles. Enforced on the
# server so a user cannot reach them by typing the URL (base_authenticated.html
# is the reference for who sees what).
PAYROLL_AREA_ROLES = ('admin', 'payroll', 'accounting') # Time Attendance, Legacy, Employees, Statistics
QR_MANAGEMENT_ROLES = ('admin', 'staff', 'payroll', 'accounting') # create / edit / bulk-import QR codes
def _wants_json_response():
"""API and fetch() callers get JSON errors instead of a redirect to an HTML page."""
return (request.path.startswith('/api/')
or request.headers.get('X-Requested-With') == 'XMLHttpRequest'
or request.accept_mimetypes.best == 'application/json')
def _role_denied_response(allowed_roles):
"""None when the logged-in user's role is allowed; otherwise the response to return."""
if 'user_id' not in session:
if _wants_json_response():
return jsonify({'success': False, 'error': 'Authentication required'}), 401
flash('Please log in to access this page.', 'error')
return redirect(url_for('auth.login'))
role = session.get('role')
if role in allowed_roles:
return None
logger_handler.logger.warning(
f"Access denied: user {session.get('username')} (role {role}) -> {request.endpoint}"
)
if _wants_json_response():
return jsonify({'success': False, 'error': 'Access denied'}), 403
flash('You do not have permission to access that page.', 'error')
return redirect(url_for('dashboard.dashboard'))
def roles_required(*allowed_roles):
"""Decorator: the user must be logged in with one of allowed_roles."""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
denied = _role_denied_response(allowed_roles)
if denied is not None:
return denied
return f(*args, **kwargs)
return decorated_function
return decorator
def restrict_blueprint_to_roles(blueprint, allowed_roles):
"""Apply the role check to every route of a blueprint (one line per module)."""
@blueprint.before_request
def _enforce_blueprint_roles():
return _role_denied_response(allowed_roles)
return blueprint
def is_admin_user(user_id):
"""Helper function to safely check if user is admin"""
from extensions import db