mirror of
https://codeberg.org/angestoepselt/homepage.git
synced 2025-05-24 14:46:16 +00:00
Revert "Merge pull request 'Diverse Formular-Verbessungen' (#155) from form-tweaks into main"
Das Formular funktioniert nicht mehr sauber This reverts commit74cb447ac9, reversing changes made tof36e4d1548.
This commit is contained in:
parent
74cb447ac9
commit
a054bc1b07
1 changed files with 20 additions and 75 deletions
|
|
@ -1,17 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import base64
|
||||
import io
|
||||
import cgi
|
||||
import collections
|
||||
from collections.abc import Mapping
|
||||
import hmac
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import os
|
||||
import secrets
|
||||
import json
|
||||
from typing import Any, Optional, overload
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import itsdangerous
|
||||
import requests
|
||||
|
|
@ -34,20 +34,6 @@ except IOError:
|
|||
|
||||
|
||||
HONEYPOT_FIELD_NAME = "addressline1"
|
||||
# This regex merely validates what the in-browser form validation already checks and
|
||||
# isn't all too strict.
|
||||
EMAIL_REGEX = re.compile(r"^[^ ]+@[^ ]+\.[^ ]+$")
|
||||
|
||||
# Mapping from site-defined devices (see sites/angestoepselt/_data/config.json in this
|
||||
# repository) to the corresponding Zammad categories:
|
||||
# https://codeberg.org/angestoepselt/homepage/issues/120#issuecomment-1727768
|
||||
# This is a (str | int) -> str map because some keys we check against below might be
|
||||
# integers and it's just easier to type this way.
|
||||
FORM_CATEGORY_MAP: dict[str | int, str] = {
|
||||
"Laptop": "laptop",
|
||||
"Laptop ohne Akku": "laptop-battery-missing",
|
||||
"Desktop-Computer": "desktop",
|
||||
}
|
||||
|
||||
SITE_DIRECTORY = os.environ.get("SITE_DIRECTORY", "")
|
||||
request_uri = os.environ.get("REQUEST_URI", "").lower().rstrip("/")
|
||||
|
|
@ -142,16 +128,15 @@ if form_disabled:
|
|||
form = cgi.FieldStorage()
|
||||
|
||||
@overload
|
||||
def get_form_value(name: str, default: None = ..., *, cast: type[bytes]) -> tuple[str, bytes]:...
|
||||
def get_form_value(name: str, default: Optional[str], cast: type[str] = str) -> str: ...
|
||||
@overload
|
||||
def get_form_value(name: str, default: Optional[int] = ..., *, cast: type[int]) -> int:...
|
||||
def get_form_value(name: str, default: Optional[int], cast: type[int]) -> int:...
|
||||
@overload
|
||||
def get_form_value(name: str, default: Optional[str] = ..., *, cast: type[str] = ...) -> str: ...
|
||||
def get_form_value(name: str, default: None = ..., cast: type[bytes] = ...) -> tuple[str, bytes]:...
|
||||
def get_form_value(
|
||||
name: str,
|
||||
default: Any = None,
|
||||
*,
|
||||
cast: type[str] | type[int] | type[bytes] = str,
|
||||
cast: type[str] | type[int] | type[io.BytesIO] = str,
|
||||
) -> Any:
|
||||
if name not in form:
|
||||
if default is None:
|
||||
|
|
@ -169,10 +154,7 @@ def get_form_value(
|
|||
return (value_object.filename or "upload"), value_object.file.read()
|
||||
else:
|
||||
try:
|
||||
result = cast(form.getfirst(name))
|
||||
if isinstance(result, str):
|
||||
result = result.strip()
|
||||
return result
|
||||
return cast(form.getfirst(name))
|
||||
except (TypeError, ValueError):
|
||||
fail("400 Bad Request", f"Invalid value for field: {name}")
|
||||
|
||||
|
|
@ -181,7 +163,7 @@ def get_form_value(
|
|||
# constant-time string comparison here.
|
||||
given_csrf_token = get_form_value("csrftoken")
|
||||
if not hmac.compare_digest(csrf_token, given_csrf_token):
|
||||
fail("400 Bad Request", "Invalid CSRF token")
|
||||
fail("400 Bad Request", f"Invalid CSRF token")
|
||||
|
||||
|
||||
# If the honeypot field was not empty, back off.
|
||||
|
|
@ -201,21 +183,15 @@ if not isinstance(hcaptcha_data, Mapping) or not hcaptcha_data.get("success", Fa
|
|||
# Extract all the actually provided form data. This is different from form to
|
||||
# form (see the match block below).
|
||||
contact_name = get_form_value("contactname")
|
||||
contact_names = contact_name.split(" ")
|
||||
|
||||
contact_email = get_form_value("contactemail")
|
||||
if not EMAIL_REGEX.fullmatch(contact_email):
|
||||
fail("400 Bad Request", "Invalid Email address")
|
||||
|
||||
message = get_form_value("message", "[Keine Nachricht hinterlassen]")
|
||||
attachment: Optional[tuple[str, bytes]] = None
|
||||
|
||||
ticket_details = collections.OrderedDict[str, str | int]()
|
||||
ticket_details = collections.OrderedDict()
|
||||
ticket_details["Kontaktperson"] = contact_name
|
||||
ticket_details["Email"] = contact_email
|
||||
|
||||
form_group = "csw-Allgemein"
|
||||
form_category: str | None = None
|
||||
|
||||
match request_uri:
|
||||
case "/kontakt":
|
||||
|
|
@ -237,17 +213,14 @@ match request_uri:
|
|||
ticket_details["Adresse"] = get_form_value("addressline")
|
||||
ticket_details["PLZ"] = get_form_value("postalcode")
|
||||
ticket_details["Stadt"] = get_form_value("city")
|
||||
ticket_details["Anzahl Desktops"] = get_form_value("desktopcount", 0, cast=int)
|
||||
ticket_details["Anzahl Laptops"] = get_form_value("laptopcount", 0, cast=int)
|
||||
ticket_details["Anzahl Drucker"] = get_form_value("printercount", 0, cast=int)
|
||||
ticket_details["Anzahl Desktops"] = get_form_value("desktopcount", 0, int)
|
||||
ticket_details["Anzahl Laptops"] = get_form_value("laptopcount", 0, int)
|
||||
ticket_details["Anzahl Drucker"] = get_form_value("printercount", 0, int)
|
||||
|
||||
case "/computer-beantragen/privat":
|
||||
form_name = "Computerantrag (privat)"
|
||||
form_group = "csw-Anfragen"
|
||||
|
||||
ticket_details["Gewünschte Hardware"] = get_form_value("hardware", default="Unbekannt")
|
||||
form_category = FORM_CATEGORY_MAP.get(ticket_details["Gewünschte Hardware"], None)
|
||||
|
||||
ticket_details["Adresse"] = get_form_value("addressline")
|
||||
ticket_details["PLZ"] = get_form_value("postalcode")
|
||||
ticket_details["Stadt"] = get_form_value("city")
|
||||
|
|
@ -303,46 +276,18 @@ ticket_details["Kontaktformular"] = form_name
|
|||
# testing).
|
||||
form_group = os.environ.get("ZAMMAD_GROUP", "") or form_group
|
||||
|
||||
ZAMMAD_URL = os.environ.get("ZAMMAD_URL", "")
|
||||
ZAMMAD_URL = os.environ.get("ZAMMAD_URL", "").rstrip("/")
|
||||
ZAMMAD_TOKEN = os.environ.get("ZAMMAD_TOKEN", "")
|
||||
session.headers.update(Authorization=f"Token token={ZAMMAD_TOKEN}")
|
||||
|
||||
try:
|
||||
# Create a new user for the client. For some reason, using "guess:{email}" as the
|
||||
# customer_id when creating the ticket doesn't really work, as described in the
|
||||
# Zammad documentation [1]. Instead, we sometimes need to explictily create the
|
||||
# user beforehand. See this discussion [2] for more details.
|
||||
# [1]: https://docs.zammad.org/en/latest/api/ticket/index.html#create
|
||||
# [2]: https://codeberg.org/angestoepselt/homepage/issues/141
|
||||
response = session.post(
|
||||
urljoin(ZAMMAD_URL, "api/v1/users"),
|
||||
json=dict(
|
||||
# Yes, yes... This goes against pretty much all best practices for parsing
|
||||
# names. But: it's only internal and we save the name verbatim again below
|
||||
# so we're going to go ahead and do it anyway.
|
||||
firstname=" ".join(contact_names[:-1]) if len(contact_names) >= 2 else "?",
|
||||
lastname=contact_names[-1],
|
||||
email=contact_email,
|
||||
)
|
||||
)
|
||||
if response.status_code == 422:
|
||||
# This email address is already in use by another user.
|
||||
customer_id = f"guess:{contact_email}"
|
||||
else:
|
||||
response.raise_for_status()
|
||||
customer_id = response.json()["id"]
|
||||
assert isinstance(customer_id, (str, int))
|
||||
|
||||
# Add the actual ticket to the system.
|
||||
response = session.post(
|
||||
urljoin(ZAMMAD_URL, "api/v1/tickets"),
|
||||
headers={
|
||||
"X-On-Behalf-Of": contact_email,
|
||||
},
|
||||
f"{ZAMMAD_URL}/api/v1/tickets",
|
||||
json=dict(
|
||||
title=f"Kontaktformular {contact_name} – {form_name}",
|
||||
group=form_group,
|
||||
customer_id=customer_id,
|
||||
customer_id=f"guess:{contact_email}",
|
||||
article=dict(
|
||||
type="web",
|
||||
internal=True,
|
||||
|
|
@ -364,7 +309,7 @@ try:
|
|||
# Add a second article to the ticket that contains all the other information
|
||||
# from the contact form.
|
||||
response = session.post(
|
||||
urljoin(ZAMMAD_URL, "api/v1/ticket_articles"),
|
||||
f"{ZAMMAD_URL}/api/v1/ticket_articles",
|
||||
json=dict(
|
||||
ticket_id=ticket_id,
|
||||
type="note",
|
||||
|
|
@ -379,7 +324,7 @@ try:
|
|||
|
||||
# Add a tag to the ticket, denoting which contact form it came from.
|
||||
response = session.post(
|
||||
urljoin(ZAMMAD_URL, "api/v1/tags/add"),
|
||||
f"{ZAMMAD_URL}/api/v1/tags/add",
|
||||
json=dict(
|
||||
object="Ticket",
|
||||
o_id=ticket_id,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue