#!/bin/bash # fe_comment Isolationstest (2026-11-03): zwei FE-User NACHEINANDER einloggen # und pruefen, dass /api/fe-comment/state UND das USER_INT-Feld auf # /_json/ticket-overview jedem User nur die EIGENEN Tickets zeigen. # Aufruf: bash migrations/fec_isolation_test.sh # (fragt beide Passwoerter unsichtbar ab) set -e cd /usr/www/users/vitecevo/live BASE=https://dev.vitec.com U1=${1:?Aufruf: fec_isolation_test.sh } U2=${2:?Aufruf: fec_isolation_test.sh } extract_token() { php -r ' $j = json_decode(file_get_contents($argv[1]), true); $f = ""; $w = function ($n) use (&$w, &$f) { if (is_array($n)) { if (($n["name"] ?? "") === "__RequestToken" && isset($n["value"])) { $f = (string)$n["value"]; } foreach ($n as $c) { $w($c); } } elseif (is_string($n) && $f === "") { if (preg_match("/name=\"__RequestToken\" value=\"([^\"]+)\"/", $n, $m)) { $f = $m[1]; } } }; $w($j); echo $f; ' "$1" } login() { # $1=user $2=pass $3=jar rm -f "$3" curl -sS -c "$3" -o /tmp/fec_form.json "$BASE/_json/fe-user-profile" TOKEN=$(extract_token /tmp/fec_form.json) if [ -z "$TOKEN" ]; then echo "KEIN __RequestToken gefunden"; exit 1; fi curl -sS -b "$3" -c "$3" -o /tmp/fec_login.json \ --data-urlencode "user=$1" \ --data-urlencode "pass=$2" \ --data-urlencode "logintype=login" \ --data-urlencode "pid=520" \ --data-urlencode "__RequestToken=$TOKEN" \ "$BASE/_json/fe-user-profile" if ! grep -q fe_typo_user "$3"; then echo "LOGIN FEHLGESCHLAGEN fuer $1 (kein fe_typo_user-Cookie)"; exit 1 fi } summarize_state() { # stdin = state json, $1 = label php -r ' $j = json_decode(stream_get_contents(STDIN), true); printf("%-28s allowed=%s user=%s summaryUid=%s items=%d\n", $argv[1], var_export($j["allowed"] ?? null, true), $j["user"]["name"] ?? "-", isset($j["summary"]["uid"]) ? (string)$j["summary"]["uid"] : "-", is_array($j["summary"]["items"] ?? null) ? count($j["summary"]["items"]) : 0); foreach (($j["summary"]["items"] ?? []) as $i) { printf(" item #%d %s\n", $i["uid"], mb_substr($i["url"], 0, 70)); } ' "$1" } summarize_overview() { # stdin = page json, $1 = label php -r ' $j = json_decode(stream_get_contents(STDIN), true); $fo = null; foreach (($j["content"]["colPos0"] ?? []) as $el) { if (($el["type"] ?? "") === "fecomment_overview") { $fo = $el["content"]["feedbackOverview"] ?? null; } } if ($fo === null) { echo $argv[1] . " KEIN fecomment_overview-Element gefunden\n"; exit; } printf("%-28s allowed=%s user=%s summaryUid=%s items=%d\n", $argv[1], var_export($fo["allowed"] ?? null, true), $fo["user"]["name"] ?? "-", isset($fo["summary"]["uid"]) ? (string)$fo["summary"]["uid"] : "-", is_array($fo["summary"]["items"] ?? null) ? count($fo["summary"]["items"]) : 0); ' "$1" } check_user() { # $1=user $2=jar echo "=== $1 ===" curl -sS -b "$2" "$BASE/api/fe-comment/state" | summarize_state "state-API" curl -sS -b "$2" "$BASE/_json/ticket-overview" | summarize_overview "ticket-overview (USER_INT)" echo } read -rsp "Passwort fuer $U1: " P1; echo read -rsp "Passwort fuer $U2: " P2; echo login "$U1" "$P1" /tmp/fec_u1.jar login "$U2" "$P2" /tmp/fec_u2.jar # Testticket als U1 anlegen, damit es etwas zu sehen (bzw. NICHT zu sehen) gibt echo "--- lege Testticket als $U1 an ---" TICKET=$(curl -sS -b /tmp/fec_u1.jar -H 'Content-Type: application/json' \ -d '{"url":"/isolation-test","note":"

Isolationstest - bitte ignorieren

"}' \ "$BASE/api/fe-comment/feedback" | php -r ' $j = json_decode(stream_get_contents(STDIN), true); echo (int)($j["uid"] ?? 0);') echo "Testticket uid=$TICKET" if [ "$TICKET" = "0" ]; then echo "ANLEGEN FEHLGESCHLAGEN"; exit 1; fi echo # beide Sessions leben gleichzeitig - genau wie zwei Browser check_user "$U1" /tmp/fec_u1.jar check_user "$U2" /tmp/fec_u2.jar # Gegenprobe: darf U2 das Ticket von U1 veraendern? (erwartet: Fehler) echo "--- Gegenprobe: $U2 versucht Ticket #$TICKET von $U1 zu loeschen ---" curl -sS -b /tmp/fec_u2.jar -X POST "$BASE/api/fe-comment/feedback/$TICKET/delete"; echo echo "(erwartet: {\"error\":\"feedback not found or not yours\"})" echo # aufraeumen: U1 loescht sein eigenes Testticket echo "--- aufraeumen: $U1 loescht Testticket #$TICKET ---" curl -sS -b /tmp/fec_u1.jar -X POST "$BASE/api/fe-comment/feedback/$TICKET/delete"; echo echo echo "=== anonym (ohne Session) ===" curl -sS "$BASE/api/fe-comment/state" | summarize_state "state-API" curl -sS "$BASE/_json/ticket-overview" | summarize_overview "ticket-overview (USER_INT)" echo echo "ERWARTUNG: $U1 sieht 1 Item (das Testticket), $U2 sieht 0 Items," echo "die Gegenprobe-Loeschung durch $U2 schlaegt fehl, anonym ist allowed=false." rm -f /tmp/fec_u1.jar /tmp/fec_u2.jar /tmp/fec_form.json /tmp/fec_login.json