81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
"""访问门控 API 与管理接口。"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Request
|
|
|
|
from app import auth
|
|
from app import uuid_store
|
|
|
|
router = APIRouter(prefix="/api/auth", tags=["auth"])
|
|
admin_router = APIRouter(prefix="/api/admin", tags=["admin"])
|
|
|
|
|
|
@router.post("/verify")
|
|
def verify_credential(req: auth.VerifyIn) -> auth.VerifyOut:
|
|
"""校验管理员令牌或普通 UUID,成功后返回访问令牌及角色。"""
|
|
role = auth.verify_credential(req.credential)
|
|
if role:
|
|
token = auth.create_access_token(role)
|
|
return auth.VerifyOut(valid=True, role=role.value, token=token)
|
|
return auth.VerifyOut(valid=False, role=None, token=None)
|
|
|
|
|
|
@router.get("/status")
|
|
def auth_status(request: Request) -> auth.AuthStatusOut:
|
|
"""返回当前门控状态、当前请求是否通过校验及角色。"""
|
|
enabled = auth.access_control_enabled()
|
|
token = auth.get_access_token_from_request(request)
|
|
role = auth.validate_access_token(token)
|
|
return auth.AuthStatusOut(
|
|
enabled=enabled,
|
|
verified=role is not None,
|
|
role=role.value if role else None,
|
|
)
|
|
|
|
|
|
# ===== 管理员 UUID 管理 =====
|
|
|
|
@admin_router.get("/uuids")
|
|
def list_uuids(request: Request) -> list[auth.UuidRecordOut]:
|
|
"""列出所有动态 UUID(仅管理员)。"""
|
|
auth.require_admin(request)
|
|
records = uuid_store.list_uuids()
|
|
return [
|
|
auth.UuidRecordOut(
|
|
uuid=r["uuid"],
|
|
label=r.get("label", ""),
|
|
enabled=r.get("enabled", True),
|
|
created_at=r.get("created_at", 0),
|
|
)
|
|
for r in records
|
|
]
|
|
|
|
|
|
@admin_router.post("/uuids")
|
|
def create_uuid(req: auth.UuidCreateIn, request: Request) -> auth.UuidRecordOut:
|
|
"""创建新的访问 UUID(仅管理员)。"""
|
|
auth.require_admin(request)
|
|
record = uuid_store.create(req.label)
|
|
return auth.UuidRecordOut(
|
|
uuid=record["uuid"],
|
|
label=record["label"],
|
|
enabled=record["enabled"],
|
|
created_at=record["created_at"],
|
|
)
|
|
|
|
|
|
@admin_router.delete("/uuids/{uuid}")
|
|
def delete_uuid(uuid: str, request: Request) -> dict:
|
|
"""删除访问 UUID(仅管理员)。"""
|
|
auth.require_admin(request)
|
|
ok = uuid_store.delete(uuid)
|
|
return {"ok": ok}
|
|
|
|
|
|
@admin_router.put("/uuids/{uuid}/toggle")
|
|
def toggle_uuid(uuid: str, request: Request, enabled: bool) -> dict:
|
|
"""启用/禁用访问 UUID(仅管理员)。"""
|
|
auth.require_admin(request)
|
|
ok = uuid_store.toggle(uuid, enabled)
|
|
return {"ok": ok}
|