#!/usr/bin/env bash # Aufgabe 3: Datei-Schnittstelle gegen die Test-Nextcloud (Liste mit Speicher, Vorschau, Ordner, # Verschieben/Umbenennen, Papierkorb, zweiter Benutzer). Setzt einen laufenden Stack und # nc-test-setup.sh voraus. Nur Testwerte; liest keine .env-Dateien. set -euo pipefail source "$(dirname "${BASH_SOURCE[0]}")/e2e-lib.sh" trap 'rm -rf "$E2E_TMP"' EXIT FILES="$API/modules/nextcloud-files" NC_DAV="http://localhost:18080/remote.php/dav" ANNA="anna:User1-Pass-12345" # 1x1-PNG als Base64 (Vorschau) PNG_B64='iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==' UMLAUT_NAME='Ärger & Ölpreis 100%.txt' UMLAUT_ENC='%C3%84rger%20%26%20%C3%96lpreis%20100%25.txt' ADMIN="$E2E_TMP/admin.jar" e2e_wait_health e2e_login "$ADMIN" e2e_activate "$ADMIN" e2e_set_address "$ADMIN" code=$(e2e_connect_anna "$ADMIN") e2e_expect 200 "$code" "anna verbinden" # GET — Pfad als Query-Parameter, sauber codiert; Status auf stdout. qget() { curl -s -o "$E2E_TMP/body.out" -w '%{http_code}' -b "$1" -G --data-urlencode "path=$3" "$FILES/$2"; } qdel() { curl -s -o "$E2E_TMP/body.out" -w '%{http_code}' -b "$1" -X DELETE -G --data-urlencode "path=$3" "$FILES/$2"; } post() { e2e_status "$1" POST "$FILES/$2" "$3"; } # JSON-Body: die Umlautdatei im Testordner ins Unterverzeichnis Ziel verschieben move_umlaut_json() { python3 -I -c 'import json,sys print(json.dumps({"from": sys.argv[1] + "/" + sys.argv[2], "to": sys.argv[1] + "/Ziel/" + sys.argv[2]}))' "$F" "$UMLAUT_NAME" } F="/Tessera-E2E-$(date +%s)" FNAME="${F#/}" # --- Vorbereitung direkt in der Nextcloud (mit annas Passwort) -------------------------------- nc_put() { curl -s -o /dev/null -w '%{http_code}' -u "$ANNA" -X PUT --data-binary "$2" "$NC_DAV/files/anna$1"; } code=$(curl -s -o /dev/null -w '%{http_code}' -u "$ANNA" -X MKCOL "$NC_DAV/files/anna$F"); e2e_expect 201 "$code" "Fixture-Ordner" code=$(nc_put "$F/$UMLAUT_ENC" "hallo"); e2e_expect 201 "$code" "Fixture Umlautdatei" echo "$PNG_B64" | base64 -d > "$E2E_TMP/pixel.png" code=$(curl -s -o /dev/null -w '%{http_code}' -u "$ANNA" -X PUT -H 'Content-Type: image/png' \ --data-binary "@$E2E_TMP/pixel.png" "$NC_DAV/files/anna$F/pixel.png"); e2e_expect 201 "$code" "Fixture PNG" # --- Liste der Wurzel mit Speicherangabe --------------------------------------------------------- code=$(qget "$ADMIN" files "/"); e2e_expect 200 "$code" "Wurzel auflisten" e2e_contains "$E2E_TMP/body.out" '"entries"' "Wurzel: entries" e2e_contains "$E2E_TMP/body.out" '"quota"' "Wurzel: quota" e2e_contains "$E2E_TMP/body.out" "\"name\":\"$FNAME\"" "Wurzel enthaelt den Testordner" # --- Liste des Testordners: Umlautname, PNG mit Vorschau ------------------------------------------- code=$(qget "$ADMIN" files "$F"); e2e_expect 200 "$code" "Testordner auflisten" e2e_contains "$E2E_TMP/body.out" "\"name\":\"$UMLAUT_NAME\"" "Umlautname exakt" e2e_contains "$E2E_TMP/body.out" '"name":"pixel.png"' "PNG vorhanden" PNG_ID=$(python3 -I -c 'import json,sys for e in json.load(open(sys.argv[1]))["entries"]: if e["name"]=="pixel.png": assert e["hasPreview"] is True, "hasPreview" print(e["fileId"])' "$E2E_TMP/body.out") [ -n "$PNG_ID" ] || e2e_fail "PNG-Kennung fehlt" # --- Vorschau --------------------------------------------------------------------------------------- code=$(curl -s -D "$E2E_TMP/prev.hdr" -o "$E2E_TMP/prev.png" -w '%{http_code}' -b "$ADMIN" "$FILES/preview?fileId=$PNG_ID&v=%22x%22") e2e_expect 200 "$code" "Vorschau" grep -qi '^content-type: image/png' "$E2E_TMP/prev.hdr" || e2e_fail "Vorschau: kein image/png" grep -qi '^cache-control: private, max-age=86400' "$E2E_TMP/prev.hdr" || e2e_fail "Vorschau: cache-control" grep -qi '^set-cookie' "$E2E_TMP/prev.hdr" && e2e_fail "Vorschau: set-cookie aus Nextcloud weitergereicht" || true code=$(curl -s -o "$E2E_TMP/body.out" -w '%{http_code}' -b "$ADMIN" "$FILES/preview?fileId=abc") e2e_expect 400 "$code" "Vorschau mit ungueltiger Kennung" code=$(curl -s -o "$E2E_TMP/body.out" -w '%{http_code}' -b "$ADMIN" "$FILES/preview?fileId=99999999") e2e_expect 404 "$code" "Vorschau ohne Datei" # --- Neuer Ordner ----------------------------------------------------------------------------------- code=$(post "$ADMIN" folders "{\"path\":\"$F/Ziel\"}") case "$code" in 200|201) ;; *) e2e_fail "Ordner anlegen -> $code" ;; esac code=$(post "$ADMIN" folders "{\"path\":\"$F/Ziel\"}") e2e_expect 409 "$code" "Ordner doppelt anlegen" e2e_contains "$E2E_TMP/body.out" '"code":"nameTaken"' "Ordner doppelt: nameTaken" # --- Verschieben und Konflikt ------------------------------------------------------------------------ code=$(post "$ADMIN" move "$(move_umlaut_json)") e2e_expect 200 "$code" "Umlautdatei verschieben" code=$(nc_put "$F/$UMLAUT_ENC" "zweite"); e2e_expect 201 "$code" "zweite Umlautdatei" code=$(post "$ADMIN" move "$(move_umlaut_json)") e2e_expect 409 "$code" "Verschieben auf vorhandenen Namen" e2e_contains "$E2E_TMP/body.out" '"code":"nameTaken"' "Verschieben: nameTaken" # die verschobene Datei im Ziel ist unveraendert (nicht ueberschrieben) body=$(curl -s -u "$ANNA" "$NC_DAV/files/anna$F/Ziel/$UMLAUT_ENC") [ "$body" = "hallo" ] || e2e_fail "Ziel wurde ueberschrieben: '$body'" # --- Umbenennen ---------------------------------------------------------------------------------------- code=$(post "$ADMIN" move "{\"from\":\"$F/Ziel\",\"to\":\"$F/Ziel2\"}") e2e_expect 200 "$code" "Ordner umbenennen" code=$(qget "$ADMIN" files "$F/Ziel2"); e2e_expect 200 "$code" "umbenannter Ordner" e2e_contains "$E2E_TMP/body.out" "\"name\":\"$UMLAUT_NAME\"" "Datei im umbenannten Ordner" code=$(post "$ADMIN" move "{\"from\":\"$F\",\"to\":\"$F/Ziel2/innen\"}") e2e_expect 400 "$code" "Ordner in sich selbst" e2e_contains "$E2E_TMP/body.out" '"code":"moveIntoItself"' "moveIntoItself" # --- Ungueltiger Pfad ------------------------------------------------------------------------------------ code=$(qget "$ADMIN" files "/../x"); e2e_expect 400 "$code" "Pfad mit .." e2e_contains "$E2E_TMP/body.out" '"code":"invalidPath"' "invalidPath" code=$(qget "$ADMIN" files "/gibt-es-nicht-$(date +%s)"); e2e_expect 404 "$code" "fehlender Ordner" e2e_contains "$E2E_TMP/body.out" '"code":"notFound"' "notFound" # --- Zweiter Tessera-Benutzer: kein Zugriff auf annas Konto ------------------------------------------- J2="$E2E_TMP/zweit.jar" e2e_second_user "nc-e2e-zweit" "$J2" e2e_grant_use "$ADMIN" "$J2" code=$(e2e_status "$J2" GET "$FILES/status"); e2e_expect 200 "$code" "Status zweiter Benutzer" e2e_contains "$E2E_TMP/body.out" '"account":null' "zweiter Benutzer: kein Konto" code=$(qget "$J2" files "/"); e2e_expect 409 "$code" "Dateien zweiter Benutzer" e2e_contains "$E2E_TMP/body.out" '"code":"notConnected"' "zweiter Benutzer: notConnected" code=$(qget "$J2" files "$F"); e2e_expect 409 "$code" "fremder Ordner, zweiter Benutzer" code=$(qdel "$J2" files "$F"); e2e_expect 409 "$code" "Loeschen, zweiter Benutzer" code=$(qget "$ADMIN" files "$F"); e2e_expect 200 "$code" "Admin sieht weiter seine Dateien" # --- Loeschen in den Papierkorb --------------------------------------------------------------------------- code=$(qdel "$ADMIN" files "$F"); e2e_expect 200 "$code" "Testordner loeschen" code=$(qget "$ADMIN" files "$F"); e2e_expect 404 "$code" "Testordner ist weg" curl -s -u "$ANNA" -X PROPFIND -H 'Depth: 1' "$NC_DAV/trashbin/anna/trash" > "$E2E_TMP/trash.xml" grep -q "$FNAME" "$E2E_TMP/trash.xml" || e2e_fail "Papierkorb enthaelt $FNAME nicht" # --- Aufraeumen --------------------------------------------------------------------------------------------- code=$(e2e_status "$ADMIN" DELETE "$FILES/connect"); e2e_expect 200 "$code" "Abmelden" echo "e2e files ok"