35 lines
1 KiB
Python
35 lines
1 KiB
Python
from fastapi import APIRouter, Form, HTTPException
|
|
|
|
from app.auth import (
|
|
TokenPair,
|
|
fetch_account,
|
|
issue_access_token,
|
|
issue_refresh_token,
|
|
store_refresh_token,
|
|
verify_password,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/auth", tags=["auth"])
|
|
|
|
|
|
@router.post("/token", response_model=TokenPair)
|
|
async def issue_token(
|
|
username: str = Form(...),
|
|
password: str = Form(...),
|
|
) -> TokenPair:
|
|
record = await fetch_account(username)
|
|
if record is None:
|
|
raise HTTPException(status_code=401, detail="invalid credentials")
|
|
account_id, password_hash, scopes = record
|
|
if not verify_password(password, password_hash):
|
|
raise HTTPException(status_code=401, detail="invalid credentials")
|
|
|
|
access, ttl = issue_access_token(account_id, scopes)
|
|
refresh, expires_at, refresh_hash = issue_refresh_token(account_id)
|
|
await store_refresh_token(account_id, refresh_hash, expires_at)
|
|
|
|
return TokenPair(
|
|
access_token=access,
|
|
refresh_token=refresh,
|
|
expires_in=ttl,
|
|
)
|