Created
April 17, 2022 06:59
-
-
Save matthewroche/a551b32126608c816825746fc842389f to your computer and use it in GitHub Desktop.
Python OAuth flow for Intervals.icu Lambda
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from base64 import b64decode | |
# Handles a call from the intervals.icu OauthAPI, requests the auth token and returns this in a redirect URL | |
def lambda_handler(event, context): | |
# Generic error object to handle errors | |
def createErrorObject(reason): | |
return { | |
'statusCode': 301, | |
'headers': { | |
'Location': f'intervalsapp:login?error=true&reason={reason}' | |
} | |
} | |
# Ensure query parameters exist | |
if not 'queryStringParameters' in event: | |
return createErrorObject("No queryStringParameters") | |
qsp = event['queryStringParameters'] | |
# Ensure there is a code in the query string parameters | |
if not 'code' in qsp: | |
return createErrorObject("No code available") | |
code = qsp['code'] | |
client_secret = os.environ['client_secret'] | |
# Construct the call back to the intervals.icu server | |
url = 'https://intervals.icu/api/oauth/token' | |
data = { | |
'client_id': 12, | |
'client_secret': client_secret, | |
'code': code | |
} | |
# Send the request | |
http = urllib3.PoolManager() | |
response = http.request( | |
'POST', | |
url, | |
fields=data | |
) | |
print(response.status) | |
# Ensure the request was successful | |
if response.status == 200: | |
# Parse the json response | |
response_dict = json.loads(response.data.decode('utf-8')) | |
# Ensure all fields are present | |
if not 'token_type' in response_dict: | |
return createErrorObject("No token_type") | |
if not 'access_token' in response_dict: | |
return createErrorObject("No access_token") | |
if not 'scope' in response_dict: | |
return createErrorObject("No scope") | |
if not 'athlete' in response_dict: | |
return createErrorObject("No athlete") | |
if not 'id' in response_dict['athlete']: | |
return createErrorObject("No id") | |
if not 'name' in response_dict['athlete']: | |
return createErrorObject("No name") | |
# Obtain the fields | |
token_type = response_dict['token_type'] | |
access_token = response_dict['access_token'] | |
scope = response_dict['scope'] | |
athlete_id = response_dict['athlete']['id'] | |
athlete_name = response_dict['athlete']['name'] | |
# Create redirect response | |
return { | |
'statusCode': 301, | |
'headers': { | |
'Location': f'intervalsapp:login?token_type={token_type}&access_token={access_token}&scope={scope}&athlete_id={athlete_id}&athlete_name={athlete_name}' | |
} | |
} | |
else: | |
# Handle invalid response from server | |
return createErrorObject(f"Incorrect response from server: {response.status}") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment