fix(auth): block local login bypass for external accounts

This commit is contained in:
2026-02-26 20:54:54 +13:00
parent 9be0ec75ec
commit 4685f813c9
2 changed files with 91 additions and 5 deletions

View File

@@ -8,6 +8,7 @@ from ..db import (
create_user_if_missing,
set_last_login,
get_user_by_username,
get_users_by_username_ci,
set_user_password,
set_jellyfin_auth_cache,
set_user_jellyseerr_id,
@@ -82,9 +83,26 @@ def _extract_jellyseerr_user_id(response: dict) -> int | None:
@router.post("/login")
async def login(form_data: OAuth2PasswordRequestForm = Depends()) -> dict:
# Provider placeholder passwords must never be accepted by the local-login endpoint.
if form_data.password in {"jellyfin-user", "jellyseerr-user"}:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
matching_users = get_users_by_username_ci(form_data.username)
has_external_match = any(
str(user.get("auth_provider") or "local").lower() != "local" for user in matching_users
)
if has_external_match:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="This account uses external sign-in. Use the external sign-in option.",
)
user = verify_user_password(form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
if str(user.get("auth_provider") or "local").lower() != "local":
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="This account uses external sign-in. Use the external sign-in option.",
)
if user.get("is_blocked"):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="User is blocked")
token = create_access_token(user["username"], user["role"])