You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

62 lines
1.6 KiB

from __future__ import annotations
import secrets
from pathlib import Path
from typing import Dict
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
security = HTTPBasic()
def verify_basic_auth(config: Dict[str, object], credentials: HTTPBasicCredentials) -> None:
auth_conf = config.get("auth", {})
expected_username = str(auth_conf.get("username", ""))
expected_password = str(auth_conf.get("password", ""))
user_ok = secrets.compare_digest(credentials.username, expected_username)
pass_ok = secrets.compare_digest(credentials.password, expected_password)
if not (user_ok and pass_ok):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"},
)
def ensure_tls_certificate(cert_path: Path, key_path: Path) -> None:
if cert_path.exists() and key_path.exists():
return
cert_path.parent.mkdir(parents=True, exist_ok=True)
import subprocess
subprocess.run(
[
"openssl",
"req",
"-x509",
"-nodes",
"-newkey",
"rsa:2048",
"-keyout",
str(key_path),
"-out",
str(cert_path),
"-days",
"3650",
"-subj",
"/CN=pysonnerie.local",
],
check=True,
)
def make_auth_dependency(get_config):
def auth_dependency(credentials: HTTPBasicCredentials = Depends(security)) -> None:
verify_basic_auth(get_config(), credentials)
return auth_dependency