v_2.3
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
"""Auth helpers and decorators."""
|
||||
from functools import wraps
|
||||
from flask import abort, redirect, url_for, session, flash, request
|
||||
from flask_login import current_user
|
||||
|
||||
|
||||
def admin_required(view):
|
||||
@wraps(view)
|
||||
def wrapped(*args, **kwargs):
|
||||
if not current_user.is_authenticated:
|
||||
return redirect(url_for("auth.login", next=request.full_path))
|
||||
if not current_user.is_admin:
|
||||
abort(403)
|
||||
if session.get("mfa_pending"):
|
||||
return redirect(url_for("auth.mfa_challenge"))
|
||||
return view(*args, **kwargs)
|
||||
return wrapped
|
||||
|
||||
|
||||
def login_required_full(view):
|
||||
"""Like flask_login.login_required, but also blocks users with pending MFA."""
|
||||
@wraps(view)
|
||||
def wrapped(*args, **kwargs):
|
||||
if not current_user.is_authenticated:
|
||||
return redirect(url_for("auth.login", next=request.full_path))
|
||||
if session.get("mfa_pending"):
|
||||
return redirect(url_for("auth.mfa_challenge"))
|
||||
return view(*args, **kwargs)
|
||||
return wrapped
|
||||
|
||||
|
||||
def get_remote_ip() -> str:
|
||||
"""Best-effort IP detection for audit logs."""
|
||||
fwd = request.headers.get("X-Forwarded-For", "")
|
||||
if fwd:
|
||||
return fwd.split(",")[0].strip()
|
||||
return request.remote_addr or ""
|
||||
Reference in New Issue
Block a user