scheduler / api /auth.py
umangchaudhry's picture
Upload 31 files
0d04b76 verified
Raw
History Blame Contribute Delete
2.82 kB
"""Auth routes: login (admin/provider), logout, me."""
import os
from fastapi import APIRouter, HTTPException, Response, Cookie
from pydantic import BaseModel
from utils import auth as auth_utils
from api.deps import SESSION_COOKIE
router = APIRouter(prefix="/api/auth", tags=["auth"])
# HuggingFace Spaces serves the app inside a cross-site iframe, so the session
# cookie needs SameSite=None; Secure to be sent. Locally over http://localhost,
# `secure=True` would prevent the cookie from being set at all — so we detect
# the environment and pick the right pair. HF sets SPACE_ID automatically.
_IN_HF_SPACE = bool(os.environ.get("SPACE_ID"))
_COOKIE_KW = (
{"samesite": "none", "secure": True} if _IN_HF_SPACE else {"samesite": "lax"}
)
class LoginRequest(BaseModel):
username: str
password: str
class ProviderLoginRequest(BaseModel):
name: str
password: str
@router.post("/login")
def login(req: LoginRequest, response: Response):
if not auth_utils.check_credentials(req.username, req.password):
raise HTTPException(status_code=401, detail="Invalid username or password")
token = auth_utils.create_session(user_role="admin", current_user=req.username)
response.set_cookie(key=SESSION_COOKIE, value=token, httponly=True, max_age=60 * 60 * 24 * 7, **_COOKIE_KW)
return {"user_role": "admin", "current_user": req.username}
@router.post("/provider-login")
def provider_login(req: ProviderLoginRequest, response: Response):
provider = auth_utils.check_provider_credentials(req.name, req.password)
if not provider:
raise HTTPException(status_code=401, detail="Invalid provider name or password")
token = auth_utils.create_session(
user_role="provider",
current_user=provider["name"],
provider_id=provider["id"],
)
response.set_cookie(key=SESSION_COOKIE, value=token, httponly=True, max_age=60 * 60 * 24 * 7, **_COOKIE_KW)
return {"user_role": "provider", "current_user": provider["name"], "provider_id": provider["id"]}
@router.post("/logout")
def logout(response: Response, session_token: str | None = Cookie(default=None, alias=SESSION_COOKIE)):
auth_utils.destroy_session(session_token)
response.delete_cookie(SESSION_COOKIE)
return {"ok": True}
@router.get("/me")
def me(session_token: str | None = Cookie(default=None, alias=SESSION_COOKIE)):
session = auth_utils.get_session(session_token)
if not session:
return {"authenticated": False}
return {"authenticated": True, **session}
@router.get("/provider-names")
def provider_names():
"""Public list of provider names for the login dropdown."""
from core import data_manager
providers = data_manager.get_all_providers(active_only=False)
return [{"id": p["id"], "name": p["name"]} for p in providers]