feat: add auth module with login and access control

This commit is contained in:
2026-05-07 14:34:42 +08:00
parent 2d56bc2889
commit b8ba0ea6a0
15 changed files with 501 additions and 34 deletions

View File

@@ -0,0 +1,53 @@
from __future__ import annotations
import hashlib
import json
import secrets
from pathlib import Path
from app.core.config import SERVER_DIR
ADMIN_SECRET_FILE = SERVER_DIR / ".secrets" / "admin.json"
def read_admin_secret() -> dict[str, object] | None:
if not ADMIN_SECRET_FILE.exists():
return None
try:
payload = json.loads(ADMIN_SECRET_FILE.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
return None
if (
payload
and payload.get("algorithm") == "scrypt"
and isinstance(payload.get("username"), str)
and isinstance(payload.get("salt"), str)
and isinstance(payload.get("derived_key"), str)
):
return payload
return None
def verify_admin_secret(password: str, record: dict[str, object]) -> bool:
try:
salt = bytes.fromhex(str(record["salt"]))
stored_key = bytes.fromhex(str(record["derived_key"]))
key_length = int(record.get("key_length", 64))
n_value = int(record.get("N", 16384))
r_value = int(record.get("r", 8))
p_value = int(record.get("p", 1))
except (KeyError, TypeError, ValueError):
return False
derived_key = hashlib.scrypt(
password.encode("utf-8"),
salt=salt,
n=n_value,
r=r_value,
p=p_value,
dklen=key_length,
)
return secrets.compare_digest(derived_key, stored_key)