feat: add control panel
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Smoke a deployed managed Control Panel endpoint.
|
||||
#
|
||||
# Required:
|
||||
# CASAN_CP_BASE_URL=https://control-panel.example.com
|
||||
#
|
||||
# Optional:
|
||||
# CASAN_CP_COOKIE_JAR=/path/to/cookies.txt # authenticated browser/session cookie jar
|
||||
# CASAN_CP_ALLOW_INSECURE=1 # only for local labs/self-signed certs
|
||||
#
|
||||
# Without a cookie jar this proves auth is enforced. With a cookie jar it also proves
|
||||
# the API identity mapping and Command Center contract behind the auth proxy.
|
||||
|
||||
BASE="${CASAN_CP_BASE_URL:-}"
|
||||
COOKIE_JAR="${CASAN_CP_COOKIE_JAR:-}"
|
||||
|
||||
fail() {
|
||||
echo "CP_MANAGED_SMOKE_FAIL $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -n "$BASE" ]] || fail "missing_base_url env=CASAN_CP_BASE_URL"
|
||||
BASE="${BASE%/}"
|
||||
if [[ "$BASE" != https://* && "${CASAN_CP_ALLOW_INSECURE:-0}" != "1" ]]; then
|
||||
fail "base_url_must_be_https"
|
||||
fi
|
||||
|
||||
CURL=(curl -sS)
|
||||
if [[ "${CASAN_CP_ALLOW_INSECURE:-0}" == "1" ]]; then
|
||||
CURL+=(-k)
|
||||
fi
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
root_code="$("${CURL[@]}" -o "$tmp/root.html" -w "%{http_code}" "$BASE/" || true)"
|
||||
if [[ "$root_code" == "200" ]]; then
|
||||
fail "unauth_root_returned_200"
|
||||
fi
|
||||
|
||||
spoof_code="$("${CURL[@]}" \
|
||||
-H 'X-CASAN-Actor: spoofed-admin' \
|
||||
-H 'X-CASAN-Role: org-admin' \
|
||||
-H 'X-CASAN-Groups: casan-org-admin' \
|
||||
-o "$tmp/spoof.json" \
|
||||
-w "%{http_code}" \
|
||||
"$BASE/api/v1/settings" || true)"
|
||||
if [[ "$spoof_code" == "200" ]]; then
|
||||
fail "spoofed_identity_bypass"
|
||||
fi
|
||||
|
||||
if [[ -z "$COOKIE_JAR" ]]; then
|
||||
echo "CP_MANAGED_SMOKE_PARTIAL unauth_protected=true spoof_blocked=true authenticated=false"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[[ -f "$COOKIE_JAR" ]] || fail "missing_cookie_jar path=$COOKIE_JAR"
|
||||
|
||||
settings_code="$("${CURL[@]}" -L -b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
||||
-o "$tmp/settings.json" -w "%{http_code}" "$BASE/api/v1/settings" || true)"
|
||||
if [[ "$settings_code" != "200" ]]; then
|
||||
cat "$tmp/settings.json" || true
|
||||
fail "settings_http=$settings_code"
|
||||
fi
|
||||
|
||||
command_code="$("${CURL[@]}" -L -b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
||||
-o "$tmp/command.json" -w "%{http_code}" "$BASE/api/v1/command" || true)"
|
||||
if [[ "$command_code" != "200" ]]; then
|
||||
cat "$tmp/command.json" || true
|
||||
fail "command_http=$command_code"
|
||||
fi
|
||||
|
||||
python3 - "$tmp/settings.json" "$tmp/command.json" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
settings = json.load(open(sys.argv[1]))
|
||||
assert settings.get("success") is True, settings
|
||||
actor = settings.get("data", {}).get("actor", {})
|
||||
assert actor.get("actor") and actor.get("actor") != "anonymous", actor
|
||||
assert actor.get("role") and actor.get("role") != "unknown", actor
|
||||
|
||||
command = json.load(open(sys.argv[2]))
|
||||
assert command.get("success") is True, command
|
||||
widgets = command.get("data", {}).get("widgets", {})
|
||||
assert len(widgets) == 8, widgets.keys()
|
||||
for widget in widgets.values():
|
||||
envelope = widget.get("envelope", {})
|
||||
required = {"source", "artifact_path", "commit", "run_at", "verified", "status"}
|
||||
assert required <= set(envelope), envelope
|
||||
print(f"CP_MANAGED_SMOKE_PASS actor={actor.get('actor')} role={actor.get('role')} widgets={len(widgets)}")
|
||||
PY
|
||||
Reference in New Issue
Block a user