Add attachment support for forms

This commit is contained in:
Yannik Rödel 2022-03-17 13:45:08 +01:00
parent 5b84a20963
commit c7aefe142d
6 changed files with 31 additions and 17 deletions

1
.gitignore vendored
View file

@ -19,3 +19,4 @@ _site/
# Private environments in the HTTP playground folder
/playground/*.private.env.json
/httpd.dev.conf

View file

@ -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))

View file

@ -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:"

View file

@ -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

View file

@ -5,7 +5,7 @@ useForms: true
# Privat einen Computer beantragen
<form method="post" action="/computer-beantragen/privat">
<form method="post" action="/computer-beantragen/privat" enctype="multipart/form-data">
Auf dieser Seite kannst du einen Antrag einreichen, um einen Computer von uns zu
erhalten. Bitte teile uns zunächst deine Kontaktdaten mit.

View file

@ -5,7 +5,7 @@ useForms: true
# Hardware als Organisation spenden
<form method="post" action="/hardware-spenden/organisation">
<form method="post" action="/hardware-spenden/organisation" enctype="multipart/form-data">
Vielen Dank, dass du uns deine gebrauchte Hardware überlassen möchtest! Um die
Übergabe möglichst reibungslos zu gestalten, benötigen wir zunächst ein paar
@ -59,11 +59,13 @@ _SSD_-Festplatten werden in einem standardisierten Vorgehen über den Terminal g
Das Bundesamt für Sicherheit in der Informationstechnik (BSI) empfiehlt für die Datenlöschung ebenfalls **DBAN** oder vergleichbare Software. Weitere Informationen zum Thema findest du auf der Website des [BSI](https://www.bsi-fuer-buerger.de/BSIFB/DE/Empfehlungen/RichtigLoeschen/richtigloeschen_node.html).
Es gibt vier gängige Lösungen, die Datenschutzanforderungen deines Unternehmens mit einer Spende an Angestöpselt in Einklang zu bringen:
- Löschung im Unternehmen (gut für uns): Ihr übernehmt die Löschung bzw. das Überschreiben der Daten. Das installieren von Windows ist nicht notwendig. Im Verein installieren wir dann Ubuntu.
- Löschung im Verein (gängigste Variante): Ihr überlasst uns Computer + Festplatten auf Vertrauensbasis. Wir überschreiben alle Inhalte nach obiger Methode und installieren Ubuntu. Defekte HDD/SSDs vernichten wir mechanisch vor dem Recycling.
- Zertifizierte Löschung bei unserem [Kooperationspartner](https://bb-net.de/) (ab ca. 100 Geräten möglich): Die gespendeten Geräte liefert ihr an bb-net media GmbH in Schweinfurt. Dort werden die Festplatten zertifiziert gelöscht. Unser Kooperationspartner behält entweder einen Teil der Geräte zur Kostendeckung oder stellt euch klassisch eine Rechnung für die Löschung aus.
## Weitere Informationen
<dl>
<dt>Spendenquittungen</dt>
<dd>