Files
KNELAgentIdentityProvisioning/skills/agent-provisioning/scripts/oidc-login.sh
T
TSYS Group COO bde7845490 skills: agent-provisioning - codified identity stand-up workflow
Policy rulings (#942): unique passwords, Cloudron-only SSO accounts,
no reachableceo credentials, TOTP seeds MUST be captured to the vault.
Cloudron admin API wrapper, cookie-jar OIDC login, RFC-6238-tested
TOTP helper, per-system SSO/API references, incident log.
2026-09-08 04:07:14 -05:00

60 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
# Full SSO login for an identity into one of the four systems, via cookie jar.
# usage: oidc-login.sh <glpi|gitea|discourse|redmine> <login>
# Reads the Cloudron password from vault item "<login> Cloudron" (env login
# triple; USERNAME may be the email form). Success leaves cookie jar at
# /tmp/oidc-<login>-<system>.txt and prints the landing URL.
# TOTP-enforced identity? Set TOTP_CODE=$(scripts/totp.sh <seed>) first.
set -euo pipefail
SYS="${1:?usage: oidc-login.sh <glpi|gitea|discourse|redmine> <login>}"
LOGIN="${2:?usage: oidc-login.sh <glpi|gitea|discourse|redmine> <login>}"
case "$SYS" in
glpi) START="https://cmdb.knownelement.com/plugins/singlesignon/front/callback.php/provider/1?remember=1"; APP="https://cmdb.knownelement.com";;
gitea) START="https://git.knownelement.com/user/oauth2/cloudron"; APP="https://git.knownelement.com";;
discourse) START="https://community.turnsys.com/auth/openid_connect"; APP="https://community.turnsys.com";;
redmine) START="https://projects.knownelement.com/oauth"; APP="https://projects.knownelement.com";;
*) echo "unknown system: $SYS" >&2; exit 2;;
esac
if [ "$(id -un)" = "TSGCOO" ]; then
SM() { /data2/TSGCOO/.local/bin/sm "$@" </dev/null; }
else
SM() { sudo -u TSGCOO /data2/TSGCOO/.local/bin/sm "$@" </dev/null; }
fi
eval "$(SM env "$LOGIN Cloudron")"
[ -n "${PASSWORD:-}" ] || { echo "vault item '$LOGIN Cloudron' empty" >&2; exit 1; }
USER_FIELD="${USERNAME:-$LOGIN}"
JAR="/tmp/oidc-${LOGIN}-${SYS}.txt"; rm -f "$JAR"
# 1. Start the SSO flow; follow redirects to the OIDC interaction page.
INTURL=$(curl -s -o /dev/null -w '%{redirect_url}' -c "$JAR" "$START")
case "$INTURL" in
https://my.knownelement.com/openid/interaction/*) : ;;
*) echo "no interaction redirect (got: '${INTURL:-none}'). If this is redmine, see references/systems.md (known bounce). If discourse, the route may need CSRF via a real session." >&2; exit 3;;
esac
# 2. Interaction login. Field name is `username` (NOT `login`).
BODY="{\"username\":\"$USER_FIELD\",\"password\":\"$PASSWORD\""
if [ -n "${TOTP_CODE:-}" ]; then BODY="$BODY,\"totpToken\":\"$TOTP_CODE\""; fi
BODY="$BODY}"
RESP=$(curl -s -b "$JAR" -c "$JAR" -X POST "${INTURL}/login" \
-H 'Content-Type: application/json' -d "$BODY")
unset BODY
case "$RESP" in
*redirectTo*)
RED=$(printf '%s' "$RESP" | sed -n 's/.*"redirectTo":"\([^"]*\)".*/\1/p')
case "$RED" in http*) : ;; *) RED="$APP$RED" ;; esac
FINAL=$(curl -s -L -b "$JAR" -c "$JAR" -o /dev/null -w '%{url_effective}' "$RED")
echo "logged in: cookie jar $JAR"
echo "landing: $FINAL"
echo "verify the identity before use (users/current or /api/v1/user)."
;;
*twoFactorRequired*)
echo "2FA enforced and no/invalid TOTP_CODE given." >&2
echo "If the seed is in the vault: TOTP_CODE=\$(scripts/totp.sh \$(sm get '$LOGIN Cloudron' --field totp_seed)) $0 $SYS $LOGIN" >&2
exit 4;;
*)
echo "login rejected: $RESP" >&2
exit 5;;
esac