import webbrowser import base64 import hashlib import secrets from urllib.parse import urlencode, urlparse, parse_qs import requests # Your provided configuration CLIENT_ID = "" CLIENT_SECRET = "" REDIRECT_URI = "" AUTH_URL = "https://{subdomain}.zendesk.com/oauth/authorizations/new" TOKEN_URL = "https://{subdomain}.zendesk.com/oauth/tokens" # Generate PKCE code verifier and challenge CODE_VERIFIER = secrets.token_urlsafe(32) code_challenge = base64.urlsafe_b64encode( hashlib.sha256(CODE_VERIFIER.encode('ascii')).digest() ).decode('ascii').rstrip('=') def get_authorization_code(): """Generate authorization code with PKCE.""" # All required and optional parameters params = { "response_type": "code", "client_id": CLIENT_ID, "redirect_uri": REDIRECT_URI, "scope": "read write", "state": "random_state_123", "code_challenge": code_challenge, "code_challenge_method": "S256" } # Construct authorization URL auth_url = f"{AUTH_URL}?{urlencode(params)}" webbrowser.open(auth_url) # Get redirect URL redirect_response = input("Paste the FULL redirect URL here: ") try: # Parse redirect URL parsed_url = urlparse(redirect_response) query_params = parse_qs(parsed_url.query) # Check for errors if "error" in query_params: return None # Verify state returned_state = query_params.get("state", [None])[0] if returned_state != "random_state_123": return None # Extract authorization code auth_code = query_params.get("code", [None])[0] if not auth_code: return None return auth_code except Exception: return None def get_access_token(auth_code): """Exchange authorization code for access token with PKCE.""" payload = { "grant_type": "authorization_code", "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "code": auth_code, "redirect_uri": REDIRECT_URI, "code_verifier": CODE_VERIFIER } try: headers = {"Content-Type": "application/x-www-form-urlencoded"} response = requests.post(TOKEN_URL, data=payload, headers=headers) response.raise_for_status() token_response = response.json() access_token = token_response.get("access_token") if not access_token: return None return access_token except requests.exceptions.RequestException: return None if __name__ == "__main__": # Step 1: Get authorization code authorization_code = get_authorization_code() if not authorization_code: print("Failed to obtain authorization code.") exit(1) # Print authorization code print(f"Authorization Code: {authorization_code}") # Step 2: Exchange for access token access_token = get_access_token(authorization_code) if access_token: # Print access token print(f"Access Token: {access_token}") else: print("Failed to obtain access token.")