| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #!/usr/bin/env bash
- set -euo pipefail
- # Get an OAuth 2.1 access token through the full flow:
- # 1. Register a client (if needed)
- # 2. Login as admin
- # 3. Generate PKCE
- # 4. Authorize with consent
- # 5. Exchange code for token
- # 6. Print the access token
- BASE_URL="${BASE_URL:-http://localhost:3000}"
- REDIRECT_URI="${REDIRECT_URI:-http://localhost/callback}"
- ADMIN_EMAIL="${ADMIN_EMAIL:-admin@delete.me}"
- ADMIN_PASSWORD="${ADMIN_PASSWORD:-deleteme}"
- SCOPE="${SCOPE:-llm}"
- COOKIE_FILE="${COOKIE_FILE:-cookies.txt}"
- # Colors for output
- GREEN='\033[0;32m'
- BLUE='\033[0;34m'
- YELLOW='\033[1;33m'
- RED='\033[0;31m'
- NC='\033[0m' # No Color
- # ---------------------------------------------------------------------------
- # Step 1: Register a Client
- # ---------------------------------------------------------------------------
- echo -e "${BLUE}=== Step 1: Register OAuth Client ===${NC}"
- REGISTER_RESPONSE=$(curl -s -X POST "${BASE_URL}/oauth/register" \
- -H "Content-Type: application/json" \
- -d "{
- \"client_name\": \"get-token-script\",
- \"redirect_uris\": [\"${REDIRECT_URI}\"],
- \"grant_types\": [\"authorization_code\"],
- \"response_types\": [\"code\"],
- \"scope\": \"${SCOPE}\",
- \"token_endpoint_auth_method\": \"client_secret_basic\"
- }")
- # Extract client credentials
- CLIENT_ID=$(echo "$REGISTER_RESPONSE" | grep -o '"client_id":"[^"]*"' | cut -d'"' -f4 || true)
- CLIENT_SECRET=$(echo "$REGISTER_RESPONSE" | grep -o '"client_secret":"[^"]*"' | cut -d'"' -f4 || true)
- if [ -z "$CLIENT_ID" ] || [ -z "$CLIENT_SECRET" ]; then
- echo -e "${RED}Failed to register client. Response:${NC}"
- echo "$REGISTER_RESPONSE"
- exit 1
- fi
- echo -e "${GREEN}Client ID:${NC} $CLIENT_ID"
- echo -e "${GREEN}Client Secret:${NC} $CLIENT_SECRET"
- # ---------------------------------------------------------------------------
- # Step 2: Login (Get Session Cookie)
- # ---------------------------------------------------------------------------
- echo -e "${BLUE}=== Step 2: Login ===${NC}"
- # Remove old cookie file if it exists
- rm -f "$COOKIE_FILE"
- LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/oauth/login" \
- -H "Content-Type: application/x-www-form-urlencoded" \
- -d "email=${ADMIN_EMAIL}" \
- -d "password=${ADMIN_PASSWORD}" \
- -c "$COOKIE_FILE" \
- -o /dev/null)
- HTTP_CODE=$(echo "$LOGIN_RESPONSE" | tail -n1)
- if [ "$HTTP_CODE" != "302" ] && [ "$HTTP_CODE" != "200" ]; then
- echo -e "${RED}Login failed (HTTP $HTTP_CODE). Check credentials.${NC}"
- exit 1
- fi
- # Verify cookie was set
- if ! grep -q "oauth_session" "$COOKIE_FILE" 2>/dev/null; then
- echo -e "${RED}Login succeeded but no session cookie was set.${NC}"
- exit 1
- fi
- echo -e "${GREEN}Login successful. Session cookie saved to ${COOKIE_FILE}${NC}"
- # ---------------------------------------------------------------------------
- # Step 3: Generate PKCE
- # ---------------------------------------------------------------------------
- echo -e "${BLUE}=== Step 3: Generate PKCE ===${NC}"
- CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-128)
- CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl enc -base64 | tr '+/' '-_' | tr -d '=')
- STATE=$(openssl rand -hex 16)
- echo -e "${GREEN}Code Verifier:${NC} $CODE_VERIFIER"
- echo -e "${GREEN}Code Challenge:${NC} $CODE_CHALLENGE"
- echo -e "${GREEN}State:${NC} $STATE"
- # ---------------------------------------------------------------------------
- # Step 4: Authorize (with auto-consent)
- # ---------------------------------------------------------------------------
- echo -e "${BLUE}=== Step 4: Authorize ===${NC}"
- # First call authorize - it will redirect to consent if needed, or to callback with code
- AUTHORIZE_RESPONSE=$(curl -s -G "${BASE_URL}/oauth/authorize" \
- -b "$COOKIE_FILE" \
- -d "response_type=code" \
- -d "client_id=${CLIENT_ID}" \
- -d "redirect_uri=${REDIRECT_URI}" \
- -d "scope=${SCOPE}" \
- -d "code_challenge=${CODE_CHALLENGE}" \
- -d "code_challenge_method=S256" \
- -d "state=${STATE}" \
- -d "consent_given=1" \
- -w "\nFINAL_URL:%{redirect_url}" \
- -o /dev/null)
- FINAL_URL=$(echo "$AUTHORIZE_RESPONSE" | grep "FINAL_URL:" | cut -d':' -f2-)
- echo -e "${GREEN}Final redirect URL:${NC} $FINAL_URL"
- # Extract authorization code from the final URL
- AUTH_CODE=$(echo "$FINAL_URL" | grep -o 'code=[^&]*' | cut -d'=' -f2 || true)
- if [ -z "$AUTH_CODE" ]; then
- echo -e "${RED}No authorization code found in redirect URL.${NC}"
- echo -e "${YELLOW}Full response:${NC}"
- echo "$AUTHORIZE_RESPONSE"
- exit 1
- fi
- echo -e "${GREEN}Authorization Code:${NC} $AUTH_CODE"
- # ---------------------------------------------------------------------------
- # Step 5: Exchange Code for Token
- # ---------------------------------------------------------------------------
- echo -e "${BLUE}=== Step 5: Exchange Code for Token ===${NC}"
- TOKEN_RESPONSE=$(curl -s -X POST "${BASE_URL}/oauth/token" \
- -H "Content-Type: application/x-www-form-urlencoded" \
- -d "grant_type=authorization_code" \
- -d "code=${AUTH_CODE}" \
- -d "redirect_uri=${REDIRECT_URI}" \
- -d "client_id=${CLIENT_ID}" \
- -d "client_secret=${CLIENT_SECRET}" \
- -d "code_verifier=${CODE_VERIFIER}")
- # Check for errors
- if echo "$TOKEN_RESPONSE" | grep -q '"error"'; then
- echo -e "${RED}Token exchange failed:${NC}"
- echo "$TOKEN_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$TOKEN_RESPONSE"
- exit 1
- fi
- ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)
- REFRESH_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"refresh_token":"[^"]*"' | cut -d'"' -f4)
- EXPIRES_IN=$(echo "$TOKEN_RESPONSE" | grep -o '"expires_in":[0-9]*' | cut -d':' -f2)
- if [ -z "$ACCESS_TOKEN" ]; then
- echo -e "${RED}No access token in response.${NC}"
- echo "$TOKEN_RESPONSE"
- exit 1
- fi
- # ---------------------------------------------------------------------------
- # Output
- # ---------------------------------------------------------------------------
- echo ""
- echo -e "${GREEN}========================================${NC}"
- echo -e "${GREEN} SUCCESS! Token obtained${NC}"
- echo -e "${GREEN}========================================${NC}"
- echo ""
- echo -e "${BLUE}Access Token:${NC} ${ACCESS_TOKEN}"
- echo -e "${BLUE}Refresh Token:${NC} ${REFRESH_TOKEN}"
- echo -e "${BLUE}Expires In:${NC} ${EXPIRES_IN} seconds"
- echo ""
- echo -e "${YELLOW}Usage example:${NC}"
- echo " curl ${BASE_URL}/v1/models -H \"Authorization: Bearer ${ACCESS_TOKEN}\""
- echo ""
- echo -e "${YELLOW}Environment variables (for reuse):${NC}"
- echo " export OAUTH_CLIENT_ID='${CLIENT_ID}'"
- echo " export OAUTH_CLIENT_SECRET='${CLIENT_SECRET}'"
- echo " export OAUTH_ACCESS_TOKEN='${ACCESS_TOKEN}'"
- echo ""
- # Optionally save to a file for easy sourcing
- TOKEN_FILE="${TOKEN_FILE:-.oauth-token}"
- cat > "$TOKEN_FILE" <<EOF
- # OAuth 2.1 Token - Generated $(date)
- export OAUTH_CLIENT_ID='${CLIENT_ID}'
- export OAUTH_CLIENT_SECRET='${CLIENT_SECRET}'
- export OAUTH_ACCESS_TOKEN='${ACCESS_TOKEN}'
- export OAUTH_REFRESH_TOKEN='${REFRESH_TOKEN}'
- EOF
- echo -e "${GREEN}Token saved to ${TOKEN_FILE}${NC}"
- echo -e "${YELLOW}Source it with:${NC} source ${TOKEN_FILE}"
|