This commit is contained in:
2026-04-01 13:51:25 -07:00
parent c3263a0eaf
commit dc81c8e2a7
6 changed files with 313 additions and 11 deletions

View File

@@ -211,4 +211,74 @@ def register_admin_routes(app):
abort(400, "A user with this email already exists")
except Exception as e:
print(f"[ERR] Failed to create user: {e}")
abort(500, "Failed to create user")
abort(500, "Failed to create user")
@app.route("/admin/users/<uid>/become-user", methods=["POST"])
@admin_required
def become_user(uid):
"""Allow admin to impersonate another user by replacing session UID"""
try:
# Verify the target user exists
target_user_doc = db.collection("users").document(uid).get()
if not target_user_doc.exists:
abort(404, "User not found")
# Store original admin UID and set impersonation flags
session['original_uid'] = session.get('uid')
session['impersonating'] = True
# Replace session UID with target user's UID
session['uid'] = uid
print(f"[INFO] Admin {session['original_uid']} is now impersonating user {uid}")
# Redirect to dashboard
return redirect(url_for('dashboard'))
except Exception as e:
print(f"[ERR] Failed to become user {uid}: {e}")
abort(500, "Failed to impersonate user")
@app.route("/admin/users/revert")
def revert_user():
"""Revert back to the original admin session.
Only accessible if the original session owner (before impersonation) was an admin.
This check must happen before @admin_required decorator to verify the original UID,
not the currently impersonated user's UID.
"""
try:
# Check if user is currently impersonating
if 'original_uid' not in session:
# Not impersonating - check if current user is admin
uid = session.get('uid')
if not uid:
return redirect(url_for('login'))
profile = get_user_profile(uid)
if profile.get('is_admin'):
return redirect(url_for('admin_users'))
# Not an admin, deny access
abort(403, "Access denied. Admin privileges required.")
# Verify the original session owner was an admin (not the impersonated user)
original_uid = session.get('original_uid')
if not original_uid:
abort(403, "Access denied. Invalid session state.")
original_profile = get_user_profile(original_uid)
if not original_profile.get('is_admin'):
abort(403, "Access denied. Only admins can revert from impersonation.")
# Restore original admin UID
session['uid'] = original_uid
session.pop('impersonating', None)
session.pop('original_uid', None)
print(f"[INFO] Reverted from impersonation back to admin")
# Redirect to admin users page
return redirect(url_for('admin_users'))
except Exception as e:
print(f"[ERR] Failed to revert user: {e}")
abort(500, "Failed to revert session")