42 lines
1.1 KiB
Python
42 lines
1.1 KiB
Python
|
|
import re
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
from fastapi import APIRouter, HTTPException
|
||
|
|
from pydantic import BaseModel
|
||
|
|
|
||
|
|
POLICY_DIR = Path(__file__).parent.parent.parent / "policies"
|
||
|
|
_VALID_NAME = re.compile(r"^[a-z0-9][a-z0-9-]{0,63}$")
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/policy", tags=["policy"])
|
||
|
|
|
||
|
|
|
||
|
|
class PolicyRead(BaseModel):
|
||
|
|
name: str
|
||
|
|
content: str
|
||
|
|
|
||
|
|
|
||
|
|
class PolicyUpdate(BaseModel):
|
||
|
|
content: str
|
||
|
|
|
||
|
|
|
||
|
|
def _policy_path(name: str) -> Path:
|
||
|
|
if not _VALID_NAME.match(name):
|
||
|
|
raise HTTPException(status_code=400, detail="Invalid policy name")
|
||
|
|
path = POLICY_DIR / f"{name}.md"
|
||
|
|
if not path.exists():
|
||
|
|
raise HTTPException(status_code=404, detail=f"Policy '{name}' not found")
|
||
|
|
return path
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/{name}", response_model=PolicyRead)
|
||
|
|
def get_policy(name: str) -> PolicyRead:
|
||
|
|
path = _policy_path(name)
|
||
|
|
return PolicyRead(name=name, content=path.read_text())
|
||
|
|
|
||
|
|
|
||
|
|
@router.put("/{name}", response_model=PolicyRead)
|
||
|
|
def update_policy(name: str, body: PolicyUpdate) -> PolicyRead:
|
||
|
|
path = _policy_path(name)
|
||
|
|
path.write_text(body.content)
|
||
|
|
return PolicyRead(name=name, content=body.content)
|