from __future__ import annotations
import base64
import html
import secrets
from uuid import uuid4
from .redis_session import AdminSessionStore
CAPTCHA_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
def _captcha_code(length: int = 4) -> str:
return "".join(secrets.choice(CAPTCHA_ALPHABET) for _ in range(length))
def _captcha_image(code: str) -> str:
lines = "".join(
f''
for _ in range(5)
)
safe_code = html.escape(code)
svg = (
'"
)
encoded = base64.b64encode(svg.encode("utf-8")).decode("ascii")
return f"data:image/svg+xml;base64,{encoded}"
def create_captcha(store: AdminSessionStore, ttl_seconds: int) -> dict[str, object]:
captcha_id = uuid4().hex
code = _captcha_code()
store.create_captcha(captcha_id, code, ttl_seconds)
return {
"captchaEnabled": True,
"captchaId": captcha_id,
"image": _captcha_image(code),
"expiresIn": ttl_seconds,
}
def verify_captcha(store: AdminSessionStore, captcha_id: str, code: str) -> bool:
return store.consume_captcha(captcha_id, code)