Files
idrs-api/app/auth.py
T

57 lines
1.7 KiB
Python

import logging
import os
import secrets
from pathlib import Path
from sqladmin.authentication import AuthenticationBackend
from starlette.requests import Request
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_FILE = BASE_DIR / ".session_secret"
logger = logging.getLogger("idrs.auth")
def get_admin_credentials():
user = os.environ.get("ADMIN_USERNAME", "")
password = os.environ.get("ADMIN_PASSWORD", "")
return user, password
def get_session_secret():
secret = os.environ.get("IDRS_SESSION_SECRET", "")
if not secret:
if SECRET_FILE.exists():
secret = SECRET_FILE.read_text(encoding="utf-8").strip()
else:
secret = secrets.token_urlsafe(48)
SECRET_FILE.write_text(secret, encoding="utf-8")
os.chmod(SECRET_FILE, 0o600)
return secret
def credentials_configured() -> bool:
user, password = get_admin_credentials()
return bool(user and password)
class AdminAuthBackend(AuthenticationBackend):
async def authenticate(self, request: Request) -> bool:
return bool(request.session.get("auth"))
async def login(self, request: Request) -> bool:
user, password = get_admin_credentials()
if not (user and password):
logger.warning("ADMIN_USERNAME/ADMIN_PASSWORD not set — login refused (fail closed)")
return False
form = await request.form()
if secrets.compare_digest(form.get("username", ""), user) and secrets.compare_digest(
form.get("password", ""), password
):
request.session["auth"] = True
return True
return False
async def logout(self, request: Request) -> bool:
request.session.clear()
return True