refactor(auth): centralize token hashing, email validation & admin gating
- app/utils.py: shared valid_email() + now_utc() (one email regex, was duplicated in auth.py and admin.py with a looser "@"-in check elsewhere). - security.hash_token(): one SHA-256 token hasher (was duplicated in auth.py + state.py). - auth.admin_user dependency + count_admins() helper, replacing the inline role checks and the last-admin count query repeated across admin.py/me.py/tags.py.
This commit is contained in:
parent
8ef748c7b8
commit
63701f5344
7 changed files with 84 additions and 65 deletions
|
|
@ -3,6 +3,7 @@ from sqlalchemy import func, select
|
|||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.auth import (
|
||||
count_admins,
|
||||
current_user,
|
||||
google_enabled,
|
||||
has_read_scope,
|
||||
|
|
@ -111,13 +112,11 @@ def delete_my_account(
|
|||
(that would lock everyone out of the admin surfaces)."""
|
||||
if user.is_demo:
|
||||
raise HTTPException(status_code=403, detail="The shared demo account can't be deleted.")
|
||||
if user.role == "admin":
|
||||
admins = db.scalar(select(func.count()).select_from(User).where(User.role == "admin")) or 0
|
||||
if admins <= 1:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="You're the only admin — promote another admin before deleting your account.",
|
||||
)
|
||||
if user.role == "admin" and count_admins(db) <= 1:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="You're the only admin — promote another admin before deleting your account.",
|
||||
)
|
||||
user_id = user.id
|
||||
# Full erasure (cascades) + access-request cleanup + Google-grant revocation; shared with the
|
||||
# admin delete path. Capture the id first — `user` is detached once purge_user deletes the row.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue