- Fix missing await on FocusGroup.get_messages() (N-L1) - Replace time.sleep with asyncio.sleep in key_theme_service and focus_group_service (N-P10) - Replace flask import with quart in focus_groups.py (N-S3) - Add logger.error before all 500 returns in focus_groups.py (N-P6) - Add logging to silent except blocks across routes (N-M10, N-M11) - Add @rate_limit to 6 remaining AI endpoints (N-H4) - Add --confirm flag to populate scripts before delete_many (S-H2) - Remove hardcoded Azure ID fallbacks from msal_service.py and msalConfig.ts (A-M2, F-H4) - Centralize make_serializable() in utils.py, remove duplicates from 3 route files (N-P7) - Replace all datetime.utcnow() with datetime.now(timezone.utc) across entire backend (M-L2) - AuthContext.tsx: only mark token validated on 200 success, not on non-401 errors (F-H2) - Rename authType → auth_type in auth.py (N-S4) - Add security_report.md and security_report.pdf with full 92-finding status Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
33 lines
No EOL
1 KiB
Python
Executable file
33 lines
No EOL
1 KiB
Python
Executable file
from functools import wraps
|
|
from datetime import datetime
|
|
from bson import ObjectId
|
|
from quart import jsonify
|
|
from app.auth.quart_jwt import get_jwt_identity
|
|
from app.models.user import User
|
|
|
|
|
|
def make_serializable(obj):
|
|
"""Recursively convert MongoDB documents to JSON-serializable types."""
|
|
if isinstance(obj, dict):
|
|
return {k: make_serializable(v) for k, v in obj.items()}
|
|
elif isinstance(obj, list):
|
|
return [make_serializable(item) for item in obj]
|
|
elif isinstance(obj, ObjectId):
|
|
return str(obj)
|
|
elif isinstance(obj, datetime):
|
|
return obj.isoformat()
|
|
else:
|
|
return obj
|
|
|
|
def admin_required(f):
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_jwt_identity()
|
|
user_data = User.find_by_id(user_id)
|
|
|
|
if not user_data or user_data.get('role') != 'admin':
|
|
return jsonify({"message": "Admin privileges required"}), 403
|
|
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function |