fix(auth): only block bootstrap login when admin users exist
The previous check counted ALL users (func.count(User.id)), which incorrectly blocked bootstrap login if any non-admin user (e.g., Google OAuth sign-in) already existed. The fix queries specifically for admin users using the legacy is_admin flag OR the admin role assignment in user_roles. Also add tests for the non-admin-user-only scenario and fix the stale test_non_admin_user_cannot_login_as_admin assertion (401 not 403 — bootstrap path is still active when no admin exists).
This commit is contained in:
+20
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -62,14 +62,28 @@ async def login(payload: LoginRequest):
|
||||
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Bootstrap admin not configured")
|
||||
|
||||
from app.database import async_session
|
||||
from app.user_models import Role
|
||||
from app.user_models import Role, user_roles
|
||||
|
||||
# Check if any admins already exist in the DB
|
||||
# Check if any admin users already exist in the DB
|
||||
async with async_session() as session:
|
||||
admin_count_result = await session.execute(select(func.count(User.id)))
|
||||
admin_count = admin_count_result.scalar()
|
||||
# Check for admin users: legacy is_admin flag OR admin role assignment
|
||||
admin_role_subq = (
|
||||
select(1)
|
||||
.select_from(user_roles)
|
||||
.join(Role, user_roles.c.role_id == Role.id)
|
||||
.where(user_roles.c.user_id == User.id)
|
||||
.where(Role.name == "admin")
|
||||
.exists()
|
||||
)
|
||||
|
||||
if admin_count > 0:
|
||||
result = await session.execute(
|
||||
select(1).where(
|
||||
(User.is_admin == True) | admin_role_subq
|
||||
).limit(1)
|
||||
)
|
||||
has_admins = result.scalar() is not None
|
||||
|
||||
if has_admins:
|
||||
# Admins exist — bootstrap creds are locked. Try normal password login.
|
||||
if (payload.username == settings.ADMIN_USERNAME and
|
||||
payload.password == settings.ADMIN_PASSWORD):
|
||||
|
||||
Reference in New Issue
Block a user