File indexing completed on 2026-05-15 08:35:32
0001
0002
0003
0004
0005
0006 PANDA_SERVER=${PANDA_SERVER:-"https://pandaserver.cern.ch:25443"}
0007 VO=${VO:-"atlas"}
0008 TOKEN_FILE=${TOKEN_FILE:-"${HOME}/.panda_id_token"}
0009
0010 echo "==> Fetching auth config from ${PANDA_SERVER}/auth/${VO}_auth_config.json"
0011
0012 AUTH_CONFIG=$(curl -sk "${PANDA_SERVER}/auth/${VO}_auth_config.json")
0013 if [ -z "$AUTH_CONFIG" ]; then
0014 echo "ERROR: Failed to fetch auth config"
0015 return 1 2>/dev/null || exit 1
0016 fi
0017
0018
0019 read -r CLIENT_ID CLIENT_SECRET AUDIENCE OIDC_CONFIG_URL < <(
0020 python3 -c "
0021 import sys, json
0022 d = json.load(sys.stdin)
0023 print(d['client_id'], d.get('client_secret') or '', d['audience'], d['oidc_config_url'])
0024 " <<< "$AUTH_CONFIG")
0025
0026 echo "==> client_id: $CLIENT_ID"
0027 echo "==> audience: $AUDIENCE"
0028
0029
0030 OIDC_CONFIG=$(curl -sk "$OIDC_CONFIG_URL")
0031 read -r DEVICE_ENDPOINT TOKEN_ENDPOINT < <(
0032 python3 -c "
0033 import sys, json
0034 d = json.load(sys.stdin)
0035 print(d['device_authorization_endpoint'], d['token_endpoint'])
0036 " <<< "$OIDC_CONFIG")
0037
0038 echo "==> Requesting device code..."
0039 DEVICE_RESPONSE=$(curl -sk -X POST "$DEVICE_ENDPOINT" \
0040 -H "Content-Type: application/x-www-form-urlencoded" \
0041 -d "client_id=${CLIENT_ID}&scope=openid profile email offline_access&audience=${AUDIENCE}")
0042
0043
0044
0045
0046
0047
0048 read -r DEVICE_CODE VERIFICATION_URI EXPIRES_IN INTERVAL < <(
0049 python3 -c "
0050 import sys, json
0051 d = json.load(sys.stdin)
0052 print(d['device_code'], d['verification_uri_complete'], d['expires_in'], d.get('interval', 5))
0053 " <<< "$DEVICE_RESPONSE")
0054
0055 if ! [[ "$EXPIRES_IN" =~ ^[0-9]+$ ]] || ! [[ "$INTERVAL" =~ ^[0-9]+$ ]]; then
0056 echo "ERROR: Invalid expires_in or interval in device response"
0057 return 1 2>/dev/null || exit 1
0058 fi
0059
0060 echo ""
0061 echo "==> Please open the following URL in your browser and sign in:"
0062 echo ""
0063 echo " $VERIFICATION_URI"
0064 echo ""
0065 read -rp "Press Enter once you have signed in..."
0066
0067
0068 echo "==> Polling for token..."
0069 ELAPSED=0
0070 while [ "$ELAPSED" -lt "$EXPIRES_IN" ]; do
0071
0072 TOKEN_RESPONSE=$(curl -sk -X POST "$TOKEN_ENDPOINT" \
0073 -H "Content-Type: application/x-www-form-urlencoded" \
0074 -d "client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=${DEVICE_CODE}")
0075
0076 ERROR=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('error',''))" 2>/dev/null)
0077
0078 if [ "$ERROR" == "authorization_pending" ]; then
0079
0080 sleep $((INTERVAL + 1))
0081 ELAPSED=$((ELAPSED + INTERVAL + 1))
0082 continue
0083 elif [ -z "$ERROR" ]; then
0084 read -r ID_TOKEN TOKEN_EXPIRES_IN < <(
0085 python3 -c "
0086 import sys, json
0087 d = json.load(sys.stdin)
0088 print(d['id_token'], d.get('expires_in', ''))
0089 " <<< "$TOKEN_RESPONSE")
0090 echo "$TOKEN_RESPONSE" > "$TOKEN_FILE"
0091 EXPIRY_STR=$(date -d "+${TOKEN_EXPIRES_IN} seconds" 2>/dev/null || date -v "+${TOKEN_EXPIRES_IN}S" 2>/dev/null || echo "unknown")
0092 echo ""
0093 echo "==> Token saved to $TOKEN_FILE"
0094 echo "==> Token expires at: $EXPIRY_STR"
0095 break
0096 else
0097 echo "ERROR: $TOKEN_RESPONSE"
0098 return 1 2>/dev/null || exit 1
0099 fi
0100 done
0101
0102 if [ -z "$ID_TOKEN" ]; then
0103 echo "ERROR: Timed out waiting for authentication"
0104 return 1 2>/dev/null || exit 1
0105 fi
0106
0107 echo "==> Token generated successfully!"
0108
0109
0110 if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
0111
0112 export ACCESS_TOKEN=$ID_TOKEN
0113
0114 export TOKEN_FILE
0115 echo "==> ACCESS_TOKEN exported to current shell (full response in \$TOKEN_FILE: $TOKEN_FILE)"
0116
0117 else
0118 echo ""
0119 echo "Run the following to set your token:"
0120 echo ""
0121 echo " export ACCESS_TOKEN=$ID_TOKEN"
0122 echo " export TOKEN_FILE=$TOKEN_FILE"
0123 fi