refactor: centralize runtime configuration and API access policy
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Literal
|
||||
|
||||
|
||||
AccessRole = Literal["authenticated", "member", "admin"]
|
||||
|
||||
MEMBER_GET_PATHS = frozenset(
|
||||
{
|
||||
"/api/screener/setup",
|
||||
"/api/mentors/setup",
|
||||
"/api/mentors/messages",
|
||||
"/api/heaven/setup",
|
||||
}
|
||||
)
|
||||
|
||||
MEMBER_POST_PATHS = frozenset(
|
||||
{
|
||||
"/api/screener/sync",
|
||||
"/api/screener/compile",
|
||||
"/api/screener/strategies",
|
||||
"/api/screener/run",
|
||||
"/api/mentors/chat",
|
||||
"/api/heaven/hexagram",
|
||||
"/api/heaven/personal",
|
||||
"/api/heaven/interpret",
|
||||
}
|
||||
)
|
||||
|
||||
ADMIN_POST_PATHS = frozenset(
|
||||
{
|
||||
"/api/backfill",
|
||||
"/api/reasons",
|
||||
"/api/seat-aliases",
|
||||
"/api/heaven/sector-phases",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def required_role(method: str, path: str) -> AccessRole:
|
||||
method = method.upper()
|
||||
if path.startswith("/api/admin/"):
|
||||
return "admin"
|
||||
if method == "GET" and path in MEMBER_GET_PATHS:
|
||||
return "member"
|
||||
if method == "POST":
|
||||
if path in ADMIN_POST_PATHS:
|
||||
return "admin"
|
||||
if path in MEMBER_POST_PATHS:
|
||||
return "member"
|
||||
if method == "DELETE":
|
||||
if re.fullmatch(r"/api/heaven/sector-phases/.+", path):
|
||||
return "admin"
|
||||
if path == "/api/mentors/messages" or re.fullmatch(
|
||||
r"/api/screener/strategies/\d+", path
|
||||
):
|
||||
return "member"
|
||||
return "authenticated"
|
||||
Reference in New Issue
Block a user