generated from coulomb/repo-seed
Add KeyCape privacyIDEA token repair flow
This commit is contained in:
89
sso-mfa/k8s/privacyidea/check-user-mfa-state.sh
Normal file
89
sso-mfa/k8s/privacyidea/check-user-mfa-state.sh
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
# check-user-mfa-state.sh — non-secret privacyIDEA MFA state diagnostic.
|
||||
#
|
||||
# Reports realm presence and user/token counts for a user without printing
|
||||
# passwords, OTP seeds, admin JWTs, token serials, or token metadata.
|
||||
#
|
||||
# Usage:
|
||||
# bash check-user-mfa-state.sh [username]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
USERNAME="${1:-platform-root}"
|
||||
PI_URL="${PI_URL:-https://pink.coulomb.social}"
|
||||
SSO_NAMESPACE="${SSO_NAMESPACE:-sso}"
|
||||
KUBECTL="${KUBECTL:-kubectl}"
|
||||
|
||||
TOKEN="$(
|
||||
"$KUBECTL" get secret keycape-pi-token -n "$SSO_NAMESPACE" \
|
||||
-o jsonpath='{.data.token}' 2>/dev/null | base64 -d 2>/dev/null || true
|
||||
)"
|
||||
if [[ -z "$TOKEN" ]]; then
|
||||
TOKEN="$(
|
||||
"$KUBECTL" get secret keycape-pi-token -n "$SSO_NAMESPACE" \
|
||||
-o jsonpath='{.data.pi_admin_token}' 2>/dev/null | base64 -d 2>/dev/null || true
|
||||
)"
|
||||
fi
|
||||
|
||||
if [[ -z "$TOKEN" || "$TOKEN" == "PENDING_create-pi-token.sh" ]]; then
|
||||
echo "[FAIL] keycape-pi-token is missing or still a placeholder."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
api_get() {
|
||||
local path="$1"
|
||||
curl -sk -H "Authorization: $TOKEN" "$PI_URL$path"
|
||||
}
|
||||
|
||||
json_field() {
|
||||
python3 -c "$1"
|
||||
}
|
||||
|
||||
echo "privacyIDEA MFA state for user: $USERNAME"
|
||||
echo "Endpoint: $PI_URL"
|
||||
echo ""
|
||||
|
||||
REALM_RESP="$(api_get "/realm/")"
|
||||
echo "Realms:"
|
||||
printf '%s' "$REALM_RESP" | json_field '
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
if not data.get("result", {}).get("status", False):
|
||||
print(" [WARN] realm query returned status=false")
|
||||
err = data.get("result", {}).get("error", {})
|
||||
if err:
|
||||
print(" [WARN] error=" + str(err.get("message", err)))
|
||||
realms = data.get("result", {}).get("value", {})
|
||||
if not realms:
|
||||
print(" [WARN] no realms returned")
|
||||
for name in sorted(realms):
|
||||
print(" - " + name + " default=" + str(bool(realms[name].get("default"))))
|
||||
'
|
||||
|
||||
for realm in coulomb netkingdom; do
|
||||
echo ""
|
||||
echo "Realm: $realm"
|
||||
USER_RESP="$(api_get "/user/?realm=$realm&username=$USERNAME")"
|
||||
TOKEN_RESP="$(api_get "/token/?realm=$realm&user=$USERNAME")"
|
||||
|
||||
printf '%s' "$USER_RESP" | json_field '
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
users = data.get("result", {}).get("value", {}).get("users", [])
|
||||
print(f" users={len(users)}")
|
||||
'
|
||||
printf '%s' "$TOKEN_RESP" | json_field '
|
||||
import json
|
||||
import sys
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
value = data.get("result", {}).get("value", {})
|
||||
tokens = value.get("tokens", []) if isinstance(value, dict) else []
|
||||
active = sum(1 for token in tokens if token.get("active", True))
|
||||
print(f" tokens={len(tokens)} active={active}")
|
||||
'
|
||||
done
|
||||
Reference in New Issue
Block a user