diff --git a/.gitignore b/.gitignore index 69d0f2d..eaefc8c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ _site/ # Private environments in the HTTP playground folder /playground/*.private.env.json +/httpd.dev.conf diff --git a/cgi-bin/form.py b/cgi-bin/form.py index 0569a69..293e3d5 100755 --- a/cgi-bin/form.py +++ b/cgi-bin/form.py @@ -1,12 +1,14 @@ #!/usr/bin/env python +import base64 import io import cgi import collections import hmac +import mimetypes import os import secrets -from typing import Any, Optional, overload +from typing import Any, Optional, overload, IO import itsdangerous import requests @@ -90,7 +92,7 @@ def get_form_value(name: str, default: Optional[str], cast: type[str] = str) -> @overload def get_form_value(name: str, default: Optional[int], cast: type[int]) -> int:... @overload -def get_form_value(name: str, default: None = ..., cast: type[io.BytesIO] = ...) -> io.BytesIO:... +def get_form_value(name: str, default: None = ..., cast: type[bytes] = ...) -> tuple[str, bytes]:... def get_form_value( name: str, default: Any = None, @@ -102,11 +104,14 @@ def get_form_value( else: return default - if cast is io.BytesIO: + if cast is bytes: value_object = form[name] - if isinstance(value_object, list) or not value_object.file: + if ( + isinstance(value_object, list) + or not value_object.file + ): fail("400 Bad Request", f"Invalid value for field: {name}") - return io.BytesIO(value_object.file) + return (value_object.filename or "upload"), value_object.file.read() else: try: return cast(form.getfirst(name)) @@ -126,6 +131,7 @@ if not hmac.compare_digest(csrf_token, given_csrf_token): contact_name = get_form_value("contactname") contact_email = get_form_value("contactemail") message = get_form_value("message") +attachment: Optional[tuple[str, bytes]] = None ticket_details = collections.OrderedDict() ticket_details["Kontaktperson"] = contact_name @@ -159,7 +165,7 @@ match request_uri: ticket_details["Adresse"] = get_form_value("addressline") ticket_details["PLZ"] = get_form_value("postalcode") ticket_details["Stadt"] = get_form_value("city") - #document = get_form_value("document") + attachment = get_form_value("document") # Note: the actual form contains a checkbox for whether the user has # read the guidelines, but we don't actually bother checking that here. @@ -167,7 +173,7 @@ match request_uri: case "/hardware-spenden/organisation": form_name = "Hardwarespende (Organisation)" ticket_details["Organisation"] = get_form_value("organization") - #inventory = get_form_value("inventory") + attachment = get_form_value("inventory", cast=bytes) case "/hardware-spenden/privat/laptop": form_name = "Laptopspende (privat)" @@ -199,9 +205,14 @@ try: type="web", content_type="text/plain", subject=f"Kontaktformular-Anfrage {contact_name}", - body=message - ) - ) + body=message, + attachments=[] if attachment is None else [{ + "filename": attachment[0], + "data": base64.b64encode(attachment[1]).decode(), + "mime-type": mimetypes.guess_type(attachment[0])[0] or "text/plain", + }], + ), + ), ) response.raise_for_status() ticket_id = response.json()["id"] @@ -238,6 +249,6 @@ try: print("Content-Type: text/html") print("Location: /kontakt/fertig") print("") -except: - fail("500 Internal Server Error", "Backend error") +except Exception as e: + fail("500 Internal Server Error", str(e)) diff --git a/flake.nix b/flake.nix index 0dd2603..2b03389 100644 --- a/flake.nix +++ b/flake.nix @@ -53,7 +53,6 @@ config = { Env = [ - "SITE_DIRECTORY=${packages.site}" # We need to provide these default variables because otherwise # lighttpd doesn't even parse its configuration file: "ZAMMAD_URL=https://ticket.z31.it" @@ -78,6 +77,7 @@ buildInputs = [ pkgs.makeWrapper ]; paths = [ + pkgs.lighttpd nodejs nodeDependencies python @@ -91,7 +91,7 @@ shellHook = '' export NODE_PATH=${nodeDependencies}/lib/node_modules - export PATH="${nodeDependencies}/bin:${nodejs}/bin:${pkgs.nodePackages.npm-check-updates}/bin:${python}/bin:$PATH" + export PATH="${pkgs.lighttpd}/bin:${nodeDependencies}/bin:${nodejs}/bin:${pkgs.nodePackages.npm-check-updates}/bin:${python}/bin:$PATH" echo "" echo " To start editing content, run:" diff --git a/httpd.conf b/httpd.conf index 4ac6bd4..3a6c058 100644 --- a/httpd.conf +++ b/httpd.conf @@ -32,7 +32,7 @@ $HTTP["url"] =~ "^/cgi-bin/" { cgi.x-sendfile-docroot = ( "@site@" ) setenv.set-environment = ( - "SITE_DIRECTORY" => env.SITE_DIRECTORY, + "SITE_DIRECTORY" => "@site@", "ZAMMAD_URL" => env.ZAMMAD_URL, "ZAMMAD_TOKEN" => env.ZAMMAD_TOKEN, "ZAMMAD_GROUP" => env.ZAMMAD_GROUP diff --git a/src/content/computer-beantragen/privat.md b/src/content/computer-beantragen/privat.md index 560ba5b..72c6c0a 100644 --- a/src/content/computer-beantragen/privat.md +++ b/src/content/computer-beantragen/privat.md @@ -5,7 +5,7 @@ useForms: true # Privat einen Computer beantragen -