2026-01-19 03:19:17 +08:00
|
|
|
|
"""OAuth 公开端点(无需登录)。"""
|
|
|
|
|
|
|
2026-01-30 03:10:21 +08:00
|
|
|
|
from typing import Any
|
2026-01-19 03:19:17 +08:00
|
|
|
|
|
2026-03-31 19:19:04 +08:00
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
2026-01-19 03:19:17 +08:00
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
from starlette.responses import RedirectResponse
|
|
|
|
|
|
|
|
|
|
|
|
from src.database import get_db
|
|
|
|
|
|
|
|
|
|
|
|
router = APIRouter(prefix="/api/oauth", tags=["OAuth"])
|
2026-03-31 19:19:04 +08:00
|
|
|
|
_OAUTH_PUBLIC_LEGACY_DETAIL = "OAuth public routes are retired; use Rust maintenance backend"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _raise_oauth_public_legacy_unavailable() -> None:
|
|
|
|
|
|
raise HTTPException(status_code=503, detail=_OAUTH_PUBLIC_LEGACY_DETAIL)
|
2026-01-19 03:19:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/providers")
|
|
|
|
|
|
async def list_oauth_providers(db: Session = Depends(get_db)) -> dict[str, Any]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
获取可用 OAuth Providers 列表。
|
|
|
|
|
|
|
|
|
|
|
|
模块未启用时返回空列表(前端友好)。
|
|
|
|
|
|
"""
|
2026-03-31 19:19:04 +08:00
|
|
|
|
_ = db
|
|
|
|
|
|
_raise_oauth_public_legacy_unavailable()
|
2026-01-19 03:19:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/{provider_type}/authorize")
|
2026-03-17 16:34:09 +08:00
|
|
|
|
async def oauth_authorize(
|
|
|
|
|
|
provider_type: str,
|
|
|
|
|
|
client_device_id: str = Query(..., min_length=1, max_length=128),
|
|
|
|
|
|
db: Session = Depends(get_db),
|
|
|
|
|
|
) -> RedirectResponse:
|
2026-01-19 03:19:17 +08:00
|
|
|
|
"""
|
|
|
|
|
|
发起 OAuth 登录(login flow)。
|
|
|
|
|
|
"""
|
2026-03-31 19:19:04 +08:00
|
|
|
|
_ = provider_type, client_device_id, db
|
|
|
|
|
|
_raise_oauth_public_legacy_unavailable()
|
2026-01-19 03:19:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/{provider_type}/callback")
|
|
|
|
|
|
async def oauth_callback(
|
|
|
|
|
|
provider_type: str,
|
2026-03-17 16:34:09 +08:00
|
|
|
|
request: Request,
|
2026-01-19 03:19:17 +08:00
|
|
|
|
db: Session = Depends(get_db),
|
2026-01-30 03:10:21 +08:00
|
|
|
|
code: str | None = Query(None),
|
|
|
|
|
|
state: str | None = Query(None),
|
|
|
|
|
|
error: str | None = Query(None),
|
|
|
|
|
|
error_description: str | None = Query(None),
|
2026-01-19 03:19:17 +08:00
|
|
|
|
) -> RedirectResponse:
|
|
|
|
|
|
"""
|
|
|
|
|
|
OAuth 回调端点。
|
|
|
|
|
|
|
|
|
|
|
|
成功/失败都会重定向到前端回调页。
|
|
|
|
|
|
"""
|
2026-03-31 19:19:04 +08:00
|
|
|
|
_ = provider_type, request, db, code, state, error, error_description
|
|
|
|
|
|
_raise_oauth_public_legacy_unavailable()
|