Spaces:
Sleeping
Sleeping
File size: 2,820 Bytes
0d04b76 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | """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]
|