#!/usr/bin/env bash # End-zu-Ende-Pruefung Aufgabe 2 (quick-261008-mzu): Verbinden mit Passwort, Zwei-Faktor-Konto, # Browser-Anmeldung (Start/Abfrage/Abbruch), Wiederverbinden ohne verwaiste Zugaenge, Trennen mit # Widerruf. Voraussetzung: lokaler Stack laeuft (neu gebaut), nc-test-setup.sh ist gelaufen. # Die Zwei-Faktor-Anmeldung im Browser (Zugriff gewaehren) belegt der Playwright-Lauf, nicht dieses Skript. set -euo pipefail # shellcheck source=e2e-lib.sh source "$(dirname "${BASH_SOURCE[0]}")/e2e-lib.sh" JAR="$E2E_TMP/admin.jar" C="$API/modules/nextcloud-files" e2e_login "$JAR" e2e_activate "$JAR" e2e_set_address "$JAR" # Sauberer Start: Verbindung trennen (200, oder 409 wenn nicht verbunden). code=$(e2e_status "$JAR" DELETE "$C/connect") case "$code" in 200) ;; 409) e2e_contains "$E2E_TMP/body.out" 'notConnected' "Start: notConnected" ;; *) e2e_fail "DELETE connect (Start) -> $code" ;; esac e2e_expect 0 "$(e2e_nc_tokens anna)" "Start: keine Tessera-Zugaenge fuer anna" # 1. Verbinden mit Passwort code=$(e2e_connect_anna "$JAR") e2e_expect 200 "$code" "connect/password anna" e2e_contains "$E2E_TMP/body.out" '"ncUserId":"anna"' "Antwort: ncUserId" if grep -q -e 'User1-Pass' -e 'ncrypted' -e 'appPassword' "$E2E_TMP/body.out"; then e2e_fail "Antwort enthaelt ein Geheimnis"; fi code=$(e2e_status "$JAR" GET "$C/status") e2e_expect 200 "$code" "GET status" e2e_contains "$E2E_TMP/body.out" '"status":"ACTIVE"' "status ACTIVE" if grep -q -e 'User1-Pass' -e 'ncrypted' "$E2E_TMP/body.out"; then e2e_fail "status enthaelt ein Geheimnis"; fi e2e_expect 1 "$(e2e_nc_tokens anna)" "genau ein Tessera-Zugang fuer anna" # 2. Wiederverbinden: der alte Zugang wird widerrufen, es bleibt genau einer code=$(e2e_connect_anna "$JAR") e2e_expect 200 "$code" "Wiederverbinden anna" e2e_expect 1 "$(e2e_nc_tokens anna)" "nach Wiederverbinden genau ein Tessera-Zugang" # 2b. Anmeldung mit E-Mail-Adresse: das App-Passwort gehoert zum eingegebenen Anmeldenamen (gemessen: # mit der Kennung als Basic-Benutzer antwortet Nextcloud 401). Der Widerruf beim Trennen gelingt nur, # wenn Tessera den Anmeldenamen mitgespeichert hat; das belegt die Token-Zahl 0 danach. NC_OCC user:setting anna settings email anna@example.com >/dev/null code=$(e2e_status "$JAR" POST "$C/connect/password" '{"loginName":"anna@example.com","password":"User1-Pass-12345"}') e2e_expect 200 "$code" "connect/password mit E-Mail" e2e_contains "$E2E_TMP/body.out" '"ncUserId":"anna"' "E-Mail-Anmeldung: ncUserId ist die Kennung" e2e_expect 1 "$(e2e_nc_tokens anna)" "E-Mail-Anmeldung: der alte Zugang wurde widerrufen" code=$(e2e_status "$JAR" DELETE "$C/connect") e2e_expect 200 "$code" "Trennen nach E-Mail-Anmeldung" e2e_expect 0 "$(e2e_nc_tokens anna)" "Widerruf mit dem Anmeldenamen der Ausstellung" code=$(e2e_connect_anna "$JAR") e2e_expect 200 "$code" "wieder mit der Kennung verbinden" # 3. Zweiter Tessera-Benutzer derselben Organisation sieht das Konto nicht (Mandant UND Benutzer) e2e_second_user e2euser "$E2E_TMP/e2euser.jar" e2e_grant_use "$JAR" "$E2E_TMP/e2euser.jar" code=$(e2e_status "$E2E_TMP/e2euser.jar" GET "$C/status") e2e_expect 200 "$code" "e2euser GET status" e2e_contains "$E2E_TMP/body.out" '"account":null' "e2euser sieht anna's Konto nicht (account null)" code=$(e2e_status "$E2E_TMP/e2euser.jar" DELETE "$C/connect") e2e_expect 409 "$code" "e2euser kann annas Konto nicht trennen" e2e_contains "$E2E_TMP/body.out" 'notConnected' "e2euser: notConnected" e2e_expect 1 "$(e2e_nc_tokens anna)" "annas Zugang bleibt nach dem Trennversuch von e2euser" # 4. Zwei-Faktor-Konto: 422 credentialsOrTwoFactor. Jeder Versuch zaehlt in Tessera als Fehlversuch # (3 je Benutzer in 15 min); bei 429 startet die API neu und der Versuch wird einmal wiederholt. zoe_attempt() { e2e_status "$JAR" POST "$C/connect/password" '{"loginName":"zoe","password":"User2-Pass-12345"}' } code=$(zoe_attempt) if [ "$code" = "429" ]; then e2e_contains "$E2E_TMP/body.out" 'tooManyAttempts' "429 ist tooManyAttempts" (cd "$E2E_DIR/../../../.." && docker compose restart api >/dev/null) e2e_wait_health e2e_login "$JAR" code=$(zoe_attempt) fi e2e_expect 422 "$code" "zoe per Passwort" e2e_contains "$E2E_TMP/body.out" 'credentialsOrTwoFactor' "zoe: credentialsOrTwoFactor" e2e_expect 0 "$(e2e_nc_tokens zoe)" "zoe bekommt keinen Zugang" # 5. Browser-Anmeldung: Start, Abfrage (noch nicht bestaetigt), Abbruch code=$(e2e_status "$JAR" POST "$C/connect/flow") e2e_expect 200 "$code" "connect/flow Start" e2e_contains "$E2E_TMP/body.out" "\"loginUrl\":\"$NC_BASE/index.php/login/v2/flow/" "loginUrl zeigt auf die konfigurierte Adresse" if grep -qiE '"(token|poll)' "$E2E_TMP/body.out"; then e2e_fail "Flow-Antwort traegt Token oder Poll-Feld"; fi FLOW_ID=$(python3 -I -c 'import json,sys; print(json.load(open(sys.argv[1]))["flowId"])' "$E2E_TMP/body.out") code=$(e2e_status "$JAR" GET "$C/connect/flow/$FLOW_ID") e2e_expect 200 "$code" "connect/flow Abfrage" e2e_contains "$E2E_TMP/body.out" '"state":"pending"' "Abfrage: pending" # Ein zweiter Tessera-Benutzer kennt die Kennung nicht: 404. code=$(e2e_status "$E2E_TMP/e2euser.jar" GET "$C/connect/flow/$FLOW_ID") e2e_expect 404 "$code" "fremder Benutzer fragt Ablauf ab" code=$(e2e_status "$E2E_TMP/e2euser.jar" DELETE "$C/connect/flow/$FLOW_ID") e2e_expect 404 "$code" "fremder Benutzer bricht Ablauf ab" code=$(e2e_status "$JAR" GET "$C/connect/flow/$FLOW_ID") e2e_expect 200 "$code" "eigener Ablauf lebt nach dem fremden Versuch" code=$(e2e_status "$JAR" DELETE "$C/connect/flow/$FLOW_ID") e2e_expect 200 "$code" "connect/flow Abbruch" code=$(e2e_status "$JAR" GET "$C/connect/flow/$FLOW_ID") e2e_expect 404 "$code" "abgebrochener Ablauf ist weg" # 6. Trennen mit Widerruf e2e_expect 1 "$(e2e_nc_tokens anna)" "vor dem Trennen genau ein Zugang" code=$(e2e_status "$JAR" DELETE "$C/connect") e2e_expect 200 "$code" "DELETE connect" e2e_expect 0 "$(e2e_nc_tokens anna)" "nach dem Trennen kein Tessera-Zugang mehr" code=$(e2e_status "$JAR" GET "$C/status") e2e_expect 200 "$code" "GET status nach Trennen" e2e_contains "$E2E_TMP/body.out" '"account":null' "status: account null" echo "e2e connect ok"