feat: add auth module with login and access control
This commit is contained in:
53
server/src/app/core/admin_secret.py
Normal file
53
server/src/app/core/admin_secret.py
Normal 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)
|
||||
Reference in New Issue
Block a user