fix(auth): validate stopped workspace restore
This commit is contained in:
@@ -983,7 +983,8 @@ PY
|
||||
}
|
||||
|
||||
task13_assert_server_oidc_restore_verification() {
|
||||
local archive frontend status diagnostics
|
||||
local archive frontend status diagnostics active_state_before restore_output restore_rc restore_cause
|
||||
local rollback_output rollback_rc rollback_sentinel provider_label checkpoint_leftover
|
||||
archive="$TASK13_TMP/server-oidc-restore-source.zip"
|
||||
frontend="$(task13_frontend_address)"
|
||||
task13_compose_logged "seed valid server authentication runtime excluded from restore" exec -T core node --input-type=module -e '
|
||||
@@ -1003,14 +1004,88 @@ task13_assert_server_oidc_restore_verification() {
|
||||
browserTransactionDigest: "d".repeat(64), browserTransactionTransport: "https",
|
||||
});
|
||||
'
|
||||
active_state_before="$(task13_compose exec -T core node -e '
|
||||
const fs = require("node:fs");
|
||||
process.stdout.write(fs.existsSync("/data/workspace-registry/state/active.json") ? "present" : "absent");
|
||||
')"
|
||||
[[ "$active_state_before" == present || "$active_state_before" == absent ]] \
|
||||
|| task13_fail "server restore fixture returned an invalid registry state diagnostic"
|
||||
task13_compose_logged "stop server stack for OIDC restore" stop
|
||||
rollback_sentinel="$TASK13_SERVER_DATA/task13-restore-rollback"
|
||||
printf 'backup-state\n' >"$rollback_sentinel"
|
||||
task13_run_logged "create real server default-custody backup" "$TASK13_THT" \
|
||||
--installation "$TASK13_INSTALLATION" backup --output "$archive"
|
||||
task13_run_logged "perform real stopped OIDC production restore verification" "$TASK13_THT" \
|
||||
--installation "$TASK13_INSTALLATION" restore "$archive" --yes
|
||||
printf 'current-state\n' >"$rollback_sentinel"
|
||||
|
||||
provider_label="$(docker container inspect --format '{{ index .Config.Labels "io.thothii.task13.run" }}' "$TASK13_OIDC_CONTAINER")"
|
||||
[[ "$provider_label" == "$TASK13_RUN_ID" ]] || task13_fail "fake OIDC provider ownership changed before rollback injection"
|
||||
task13_run_logged "inject post-mutation OIDC verification failure" docker stop "$TASK13_OIDC_CONTAINER"
|
||||
rollback_output="$TASK13_TMP/server-oidc-rollback.out"
|
||||
set +e
|
||||
"$TASK13_THT" --installation "$TASK13_INSTALLATION" restore "$archive" --yes \
|
||||
>"$rollback_output" 2>&1
|
||||
rollback_rc=$?
|
||||
set -e
|
||||
[[ "$rollback_rc" -ne 0 ]] || task13_fail "server restore unexpectedly passed with its OIDC provider unavailable"
|
||||
grep -Eq 'restore verification doctor:|authentication diagnostics did not pass after restore' "$rollback_output" \
|
||||
|| task13_fail "server restore rollback injection did not reach post-mutation authentication verification"
|
||||
if grep -Fq "$TASK13_OIDC_CLIENT_SECRET" "$rollback_output" \
|
||||
|| grep -Fq "$TASK13_AUTHENTIK_API_TOKEN" "$rollback_output"; then
|
||||
task13_fail "failed server restore exposed fake-provider custody values"
|
||||
fi
|
||||
[[ "$(cat "$rollback_sentinel")" == current-state ]] \
|
||||
|| task13_fail "failed server restore did not roll back the server data bind"
|
||||
checkpoint_leftover="$(find "$TASK13_CONTROL_DIR" -maxdepth 1 -name 'restore-checkpoint-*.zip' -print -quit)"
|
||||
[[ -z "$checkpoint_leftover" ]] || task13_fail "failed server restore retained its private recovery checkpoint"
|
||||
task13_compose_logged "verify failed restore cleared authentication runtime" \
|
||||
run --rm --no-deps --no-TTY core sh -ceu '
|
||||
test "$(stat -c %a /data/auth)" = 700
|
||||
test "$(stat -c %a /data/auth/sessions)" = 700
|
||||
test "$(stat -c %a /data/auth/oidc)" = 700
|
||||
test "$(stat -c %u /data/auth)" = "$(id -u)"
|
||||
test -z "$(find /data/auth/sessions /data/auth/oidc -mindepth 1 -print -quit)"
|
||||
'
|
||||
task13_run_logged "restore scoped fake OIDC provider after failure injection" docker start "$TASK13_OIDC_CONTAINER"
|
||||
for _attempt in $(seq 1 30); do
|
||||
if docker exec "$TASK13_OIDC_CONTAINER" node -e \
|
||||
"fetch('https://task13-fake-oidc:9443/health',{signal:AbortSignal.timeout(3000)}).then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))" \
|
||||
>>"$TASK13_LOG" 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
docker exec "$TASK13_OIDC_CONTAINER" node -e \
|
||||
"fetch('https://task13-fake-oidc:9443/health',{signal:AbortSignal.timeout(3000)}).then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))" \
|
||||
>>"$TASK13_LOG" 2>&1 || task13_log_failure "restored scoped fake OIDC provider readiness"
|
||||
printf 'Task 13 server rollback injection passed: exit=%s; recovery checkpoint removed.\n' "$rollback_rc"
|
||||
|
||||
restore_output="$TASK13_TMP/server-oidc-restore.out"
|
||||
set +e
|
||||
"$TASK13_THT" --installation "$TASK13_INSTALLATION" restore "$archive" --yes \
|
||||
>"$restore_output" 2>&1
|
||||
restore_rc=$?
|
||||
set -e
|
||||
if [[ "$restore_rc" -ne 0 ]]; then
|
||||
restore_cause=restore-failed
|
||||
if grep -Fq 'restore verification workspace: validate restored workspace registry' "$restore_output"; then
|
||||
restore_cause=workspace-validator-rejected
|
||||
fi
|
||||
printf 'Task 13 stopped restore diagnostic: exit=%s active-state-before=%s cause=%s\n' \
|
||||
"$restore_rc" "$active_state_before" "$restore_cause" >&2
|
||||
task13_sanitize <"$restore_output" | tail -n 8 >&2
|
||||
return "$restore_rc"
|
||||
fi
|
||||
checkpoint_leftover="$(find "$TASK13_CONTROL_DIR" -maxdepth 1 -name 'restore-checkpoint-*.zip' -print -quit)"
|
||||
[[ -z "$checkpoint_leftover" ]] || task13_fail "successful server restore retained its private recovery checkpoint"
|
||||
task13_compose_start_logged "start restored server stack" up --detach --wait --wait-timeout 120 core frontend
|
||||
status="$(curl --connect-timeout "$TASK13_CURL_CONNECT_TIMEOUT" --max-time "$TASK13_CURL_MAX_TIME" \
|
||||
--silent --output /dev/null --write-out '%{http_code}' "http://$frontend/api/me")"
|
||||
frontend="$(task13_frontend_address)"
|
||||
status=""
|
||||
for _attempt in $(seq 1 30); do
|
||||
status="$(curl --connect-timeout "$TASK13_CURL_CONNECT_TIMEOUT" --max-time "$TASK13_CURL_MAX_TIME" \
|
||||
--silent --output /dev/null --write-out '%{http_code}' "http://$frontend/api/me" || true)"
|
||||
[[ "$status" == 401 ]] && break
|
||||
sleep 1
|
||||
done
|
||||
[[ "$status" == 401 ]] || task13_fail "OIDC restore did not require browser reauthentication"
|
||||
task13_compose_logged "verify private empty server authentication state" exec -T core sh -ceu '
|
||||
test "$(stat -c %a /data/auth)" = 700
|
||||
|
||||
Reference in New Issue
Block a user