This commit is contained in:
Sergey Antropoff
2026-07-17 15:57:36 +03:00
commit e4240a7be5
72 changed files with 6227 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
from __future__ import annotations
import httpx
from app.config import get_settings
from app.models import CaptchaProvider
async def verify_captcha(
provider: CaptchaProvider,
token: str | None,
remote_ip: str | None,
*,
turnstile_site_configured: bool,
hcaptcha_site_configured: bool,
) -> tuple[bool, str]:
if provider == CaptchaProvider.off:
return True, "off"
if not token:
return False, "missing_token"
settings = get_settings()
if provider == CaptchaProvider.turnstile:
if not turnstile_site_configured:
return False, "turnstile_not_configured"
secret = settings.turnstile_secret_key
if not secret:
return False, "turnstile_secret_missing"
return await _post_verify(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
{"secret": secret, "response": token, "remoteip": remote_ip or ""},
)
if provider == CaptchaProvider.hcaptcha:
if not hcaptcha_site_configured:
return False, "hcaptcha_not_configured"
secret = settings.hcaptcha_secret_key
if not secret:
return False, "hcaptcha_secret_missing"
return await _post_verify(
"https://hcaptcha.com/siteverify",
{"secret": secret, "response": token, "remoteip": remote_ip or ""},
)
return False, "unknown_provider"
async def _post_verify(url: str, data: dict) -> tuple[bool, str]:
try:
async with httpx.AsyncClient(timeout=10.0) as client:
resp = await client.post(url, data=data)
payload = resp.json()
if payload.get("success"):
return True, "ok"
return False, "verify_failed"
except Exception:
return False, "verify_error"