feat(2-Schritt2): Login-Link + persistentes is_admin-Flag pro Nutzer
- Nutzerverwaltung zeigt beim Anlegen/„Link erneuern" jetzt den vollen
Ein-Klick-Link (location.origin/?k=<token>) statt nur des Tokens.
- Neuer Admin-Schalter pro Nutzer (DB-Spalte users.is_admin + Migration).
is_admin_user() honoriert das Flag ODER ADMIN_USERS (SSO). Dadurch zeigt
/me den Admin-Button anhand des Flags — Grundlage für den nginx-Cutover.
- admin.py: PUT /admin/users/{id}/admin; list_users liefert is_admin.
Migration live verifiziert (Spalte vorhanden, bestehende Admins via
ADMIN_USERS weiterhin korrekt). app.js v=45. 219 passed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
47daf918ae
commit
bd55807a1c
8 changed files with 94 additions and 9 deletions
|
|
@ -17,7 +17,7 @@ from app.auth import is_admin_user, require_admin, require_admin_or_user
|
|||
from app.config import settings
|
||||
from app.dependencies import get_store
|
||||
from app.runtime_config import RUNTIME_SETTABLE, invalidate_cache, runtime_settings
|
||||
from app.schemas import AdminUserPrefsUpdate, MemoryCreate, MemoryOut, UserCreate, UserCreated, UserUpdate
|
||||
from app.schemas import AdminUserPrefsUpdate, MemoryCreate, MemoryOut, UserCreate, UserCreated, UserUpdate, UserAdminUpdate
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
@ -94,6 +94,15 @@ async def reset_token(user_id: str):
|
|||
return UserCreated(user_id=user.id, display_name=user.display_name, token=token)
|
||||
|
||||
|
||||
@router.put("/admin/users/{user_id}/admin", dependencies=[Depends(require_admin)])
|
||||
async def set_user_admin(user_id: str, payload: UserAdminUpdate):
|
||||
"""Schaltet Admin-Rechte (persistentes DB-Flag) für einen Nutzer ein/aus."""
|
||||
user = get_store().set_user_admin(user_id, payload.is_admin)
|
||||
if user is None:
|
||||
raise HTTPException(status_code=404, detail=f"Nutzer {user_id!r} nicht gefunden.")
|
||||
return {"user_id": user.id, "is_admin": user.is_admin}
|
||||
|
||||
|
||||
@router.put("/admin/users/{user_id}/prefs", dependencies=[Depends(require_admin)])
|
||||
async def update_user_prefs(user_id: str, payload: AdminUserPrefsUpdate):
|
||||
"""Setzt Nutzer-Einstellungen (z. B. erlaubte Sprachen). Merge mit bestehenden Prefs."""
|
||||
|
|
@ -135,6 +144,7 @@ async def list_users():
|
|||
"external_id": u.external_id,
|
||||
"created_at": u.created_at,
|
||||
"allowed_languages": (u.prefs or {}).get("allowed_languages", ""),
|
||||
"is_admin": is_admin_user(u),
|
||||
}
|
||||
for u in get_store().list_users()
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue