This commit is contained in:
2026-05-31 20:19:44 +12:00
parent 2f2466ecac
commit 84792c0947
59 changed files with 5412 additions and 898 deletions
+14 -14
View File
@@ -109,15 +109,11 @@ def _serialize_session(user: User, *, include_token: bool = False) -> UserSessio
def login(payload: LoginRequest, response: Response, request: Request, db: Session = Depends(get_db)):
"""Internal-user login.
Authenticates against a shared internal password (``ADMIN_PASSWORD``) and
looks up the user by email. Inactive or unknown users are rejected with
a generic 401 to avoid leaking which emails are valid.
Authenticates against the per-user password hash stored on ``users``.
Inactive or unknown users are rejected with a generic 401 to avoid
leaking which emails are valid.
"""
login_rate_limiter.hit(request_client_key(request, suffix="internal-login"))
if payload.password != settings.admin_password:
log_security_event("auth.login_failed", audience="internal", ip=request_client_key(request))
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid email or password")
email = payload.email.strip().lower()
user = db.scalar(
select(User)
@@ -127,6 +123,12 @@ def login(payload: LoginRequest, response: Response, request: Request, db: Sessi
if user is None or not user.is_active:
log_security_event("auth.login_failed", audience="internal", ip=request_client_key(request))
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid email or password")
if not (
verify_password(payload.password, user.password_hash)
or (user.password_hash is None and payload.password == settings.admin_password)
):
log_security_event("auth.login_failed", audience="internal", ip=request_client_key(request))
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid email or password")
session = _serialize_session(user, include_token=True)
if session.token:
@@ -161,13 +163,11 @@ def update_me(
):
"""Allow an internal user to update their own name, email, or password."""
if payload.new_password:
# Require current password verification before allowing a password change.
# Users who have never set a personal password must supply the shared
# admin password as the current credential.
current_ok = (
verify_password(payload.current_password or "", user.password_hash)
if user.password_hash
else (payload.current_password or "") == settings.admin_password
# Require current password verification before allowing a password
# change. Keep a narrow fallback for legacy rows that still have no
# password hash yet.
current_ok = verify_password(payload.current_password or "", user.password_hash) or (
user.password_hash is None and (payload.current_password or "") == settings.admin_password
)
if not current_ok:
raise HTTPException(