Merge pull request 'hCaptcha-Integration' (#55) from captcha into main

Schaut gut aus
Reviewed-on: https://codeberg.org/angestoepselt/homepage/pulls/55
This commit is contained in:
matti 2023-01-18 22:08:12 +00:00
commit 4720e17373
2 changed files with 25 additions and 7 deletions

View file

@ -4,11 +4,12 @@ import base64
import io
import cgi
import collections
from collections.abc import Mapping
import hmac
import mimetypes
import os
import secrets
from typing import Any, Optional, overload, IO
from typing import Any, Optional, overload
import itsdangerous
import requests
@ -28,7 +29,7 @@ HONEYPOT_FIELD_NAME = "addressline1"
SITE_DIRECTORY = os.environ.get("SITE_DIRECTORY", "")
request_uri = os.environ.get("REQUEST_URI", "").lower().rstrip("/")
serializer = itsdangerous.URLSafeSerializer("secret key", "salt")
session = requests.Session()
cookies = dict[str, str]()
for entry in os.environ.get("HTTP_COOKIE", "").split(";"):
@ -81,6 +82,9 @@ match os.environ.get("REQUEST_METHOD", "").upper():
print(f'<script type="text/javascript">')
print(f'document.querySelector("input[name={HONEYPOT_FIELD_NAME}]").parentNode.classList.add("isolated")')
print(f'</script>')
print('<script src="https://js.hcaptcha.com/1/api.js" async defer></script>')
print(f'<div class="h-captcha" data-sitekey="{os.environ.get("HCAPTCHA_SITE_KEY", "")}"></div>')
print(line)
exit(0)
@ -138,9 +142,22 @@ if not hmac.compare_digest(csrf_token, given_csrf_token):
# If the honeypot field was not empty, back off.
if get_form_value(HONEYPOT_FIELD_NAME, ""):
fail("200 OK", f"Invalid value for field: {HONEYPOT_FIELD_NAME}")
if (
get_form_value(HONEYPOT_FIELD_NAME, "")
or get_form_value(CAPTCHA_FIELD_NAME,
"").lower().strip() != CAPTCHA_FIELD_VALUE
):
fail("200 OK", f"Invalid value for field: {CAPTCHA_FIELD_NAME}")
if not (hcaptcha_token := get_form_value("h-captcha-response", "")):
fail("200 OK", "Empty hCaptcha token")
response = session.post("https://hcaptcha.com/siteverify", data={
"secret": os.environ.get("HCAPTCHA_SECRET_KEY", ""),
"response": hcaptcha_token,
})
hcaptcha_data = response.json()
if not isinstance(hcaptcha_data, Mapping) or not hcaptcha_data.get("success", False):
fail("200 OK", "hCaptcha fail")
# Extract all the actually provided form data. This is different from form to
# form (see the match block below).
@ -214,7 +231,6 @@ form_group = os.environ.get("ZAMMAD_GROUP", "") or form_group
ZAMMAD_URL = os.environ.get("ZAMMAD_URL", "").rstrip("/")
ZAMMAD_TOKEN = os.environ.get("ZAMMAD_TOKEN", "")
session = requests.Session()
session.headers.update(Authorization=f"Token token={ZAMMAD_TOKEN}")
try:

View file

@ -11,7 +11,7 @@ server.document-root = "@site@"
index-file.names = ( "index.html" )
setenv.set-response-header += (
"Content-Security-Policy" => "default-src 'self'; script-src 'self' 'unsafe-inline'; frame-ancestors 'none'",
"Content-Security-Policy" => "default-src 'self'; script-src 'self' 'unsafe-inline' https://hcaptcha.com https://*.hcaptcha.com; frame-src 'self' https://hcaptcha.com https://*.hcaptcha.com; style-src 'self' https://hcaptcha.com, https://*.hcaptcha.com; connect-src 'self' https://hcaptcha.com https://*.hcaptcha.com; frame-ancestors 'none'",
)
url.redirect = (
@ -61,6 +61,8 @@ $HTTP["url"] =~ "^/cgi-bin/" {
"SITE_DIRECTORY" => "@site@",
"ZAMMAD_URL" => env.ZAMMAD_URL,
"ZAMMAD_TOKEN" => env.ZAMMAD_TOKEN,
"ZAMMAD_GROUP" => env.ZAMMAD_GROUP
"ZAMMAD_GROUP" => env.ZAMMAD_GROUP,
"HCAPTCHA_SITE_KEY" => env.HCAPTCHA_SITE_KEY,
"HCAPTCHA_SECRET_KEY" => env.HCAPTCHA_SECRET_KEY,
)
}