Skip to content

Commit

Permalink
Optimized dynamodb requests, reduced global lambda execution time, be…
Browse files Browse the repository at this point in the history
…tter imports in some functions, better auth handling, bugfixes
  • Loading branch information
tlegoc committed Aug 9, 2023
1 parent b3af2fe commit 2bc9674
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 158 deletions.
16 changes: 4 additions & 12 deletions accept_join_team/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,16 @@ def lambda_handler(event, context):
token = jwt.decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

if 'body' not in event:
if 'cognito:groups' not in token or 'Admin' not in token['cognito:groups']:
return {
'statusCode': 400,
'body': json.dumps({"message": 'Missing body'})
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

body = json.loads(event['body'])

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'leader' and user['role'] != 'admin':
return {
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

teams_table = dynamodb.Table(os.environ['TEAMS_TABLE'])
team_name = event['pathParameters']['team']

Expand Down
17 changes: 8 additions & 9 deletions accept_request_challenge/app.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import boto3, json, os, time
import boto3, json, os
from jwt import decode

def lambda_handler(event, context):
try:
token = decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

if 'cognito:groups' not in token or 'Admin' not in token['cognito:groups']:
return {
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

if 'body' not in event:
return {
'statusCode': 400,
'body': json.dumps({"message": 'Missing body'})
}

body = json.loads(event['body'])

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'leader' and user['role'] != 'admin':
return {
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

username = event['pathParameters']['username']
# Get the team and check if user is in pending
response = user_table.get_item(
Expand Down
25 changes: 6 additions & 19 deletions create_challenge/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,16 @@ def lambda_handler(event, context):
token = jwt.decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

if 'body' not in event:
if 'cognito:groups' not in token or 'Admin' not in token['cognito:groups']:
return {
'statusCode': 400,
'body': json.dumps({"message": 'Missing body'})
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

body = json.loads(event['body'])

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'admin' and user['role'] != 'leader':
return {
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

name = body['name']
description = body['description']
picture_id = body['picture_id'] if 'picture_id' in body else ''
Expand All @@ -45,12 +37,6 @@ def lambda_handler(event, context):
challenge_table = dynamodb.Table(os.environ['CHALLENGES_TABLE'])
challenge_id = event['pathParameters']['challenge']

if challenge_table.get_item(Key={'challenge': challenge_id}).get('Item'):
return {
'statusCode': 400,
'body': json.dumps({"message": 'Challenge already exists'})
}

response = challenge_table.put_item(
Item={
'challenge': challenge_id,
Expand All @@ -61,7 +47,8 @@ def lambda_handler(event, context):
'start': start,
'end': end,
'max_count': max_count
}
},
ConditionExpression='attribute_not_exists(challenge)'
)

if response['ResponseMetadata']['HTTPStatusCode'] != 200:
Expand Down
40 changes: 14 additions & 26 deletions create_team/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,32 @@ def lambda_handler(event, context):
token = jwt.decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

if 'body' not in event:
return {
'statusCode': 400,
'body': json.dumps({"message": 'Missing body'})
}
body = json.loads(event['body'])

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'admin' and user['role'] != 'leader':
if 'cognito:groups' not in token or 'Admin' not in token['cognito:groups']:
return {
'statusCode': 401,
'body': json.dumps({"message": 'Unauthorized'})
}

body = json.loads(event['body'])

dynamodb = boto3.resource('dynamodb')

teams_table = dynamodb.Table(os.environ['TEAMS_TABLE'])
team_name = event['pathParameters']['team']

if teams_table.get_item(Key={'team': team_name}).get('Item'):
return {
'statusCode': 400,
'body': json.dumps({"message": 'Team already exists'})
}

display_name = body['display_name']
picture_id = body['picture_id']

response = teams_table.put_item(Item={
'team': team_name,
'display_name': display_name,
'picture_id': picture_id,
'members': [],
'pending': []
})
response = teams_table.put_item(
Item={
'team': team_name,
'display_name': display_name,
'picture_id': picture_id,
'members': [],
'pending': []
},
ConditionExpression='attribute_not_exists(team)'
)

if response['ResponseMetadata']['HTTPStatusCode'] != 200:
return {
Expand Down
29 changes: 15 additions & 14 deletions join_team/app.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import boto3, json, os, jwt
import boto3, os
from jwt import decode
from json import dumps as json_dumps


def lambda_handler(event, context):
try:
token = jwt.decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
token = decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'player':
if 'cognito:groups' in token and 'Admin' in token['cognito:groups']:
return {
'statusCode': 401,
'body': json.dumps({"message": 'You must be a player to join a team!'})
'body': json_dumps({"message": 'You must be a player to join a team'})
}

teams_table = dynamodb.Table(os.environ['TEAMS_TABLE'])
Expand All @@ -23,45 +22,47 @@ def lambda_handler(event, context):
response = teams_table.scan(
FilterExpression='contains(members, :player) OR contains(pending, :player)',
ExpressionAttributeValues={
':player': user['username']
':player': token['cognito:username']
}
)

if response['ResponseMetadata']['HTTPStatusCode'] != 200:
return {
'statusCode': 500,
'body': json.dumps({"message": 'Error joining team'})
'body': json_dumps({"message": 'Error joining team'})
}

if len(response['Items']) > 0:
return {
'statusCode': 400,
'body': json.dumps({"message": 'You are already in a team.'})
'body': json_dumps({"message": 'You are already in a team.'})
}

response = teams_table.update_item(
Key={
'team': team_name
},
UpdateExpression='SET pending = list_append(pending, :player)',
ConditionExpression=('team = :team'),
ExpressionAttributeValues={
':player': [user['username']]
':player': [token['cognito:username']],
':team': team_name
},
ReturnValues="UPDATED_NEW"
)

if response['ResponseMetadata']['HTTPStatusCode'] != 200:
return {
'statusCode': 500,
'body': json.dumps({"message": 'Error joining team'})
'body': json_dumps({"message": 'Error joining team'})
}

return {
'statusCode': 200,
'body': json.dumps({"message": 'Team joined successfully'})
'body': json_dumps({"message": 'Team joined successfully'})
}
except Exception as error:
return {
"statusCode": 500,
"body": json.dumps({"message": str(error)})
"body": json_dumps({"message": str(error)})
}
2 changes: 1 addition & 1 deletion post_confirm_sign_up/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def lambda_handler(event, context):
'challenges_pending': [],
'challenges_to_do': [],
'profile_picture_id': '',
'role': 'player'
'show': True,
}
)

Expand Down
39 changes: 27 additions & 12 deletions request_challenge/app.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,61 @@
import json, os, boto3
import os, boto3
from time import time
from jwt import decode
from json import dumps as json_dumps


def lambda_handler(event, context):
try:
token = decode(event['headers']['Authorization'].replace('Bearer ', ''), algorithms=['RS256'],
options={"verify_signature": False})

if 'cognito:groups' in token and 'Admin' in token['cognito:groups']:
return {
'statusCode': 401,
'body': json_dumps({"message": 'You must be a player to request a challenge'})
}

dynamodb = boto3.resource('dynamodb')

user_table = dynamodb.Table(os.environ['USER_TABLE'])
user = user_table.get_item(Key={'username': token['cognito:username']})['Item']

if user['role'] != 'player':
# Get challenge
challenge_table = dynamodb.Table(os.environ['CHALLENGES_TABLE'])
response = challenge_table.get_item(Key={'challenge': event['pathParameters']['challenge']})

if response['ResponseMetadata']['HTTPStatusCode'] != 200:
return {
'statusCode': 401,
'body': json.dumps({"message": 'You must be a player to request a challenge!'})
'statusCode': 404,
'body': json_dumps({"message": 'Error connecting to database'})
}

# Get challenge
challenge_table = dynamodb.Table(os.environ['CHALLENGES_TABLE'])
challenge = challenge_table.get_item(Key={'challenge': event['pathParameters']['challenge']})['Item']
if 'Item' not in response:
return {
'statusCode': 404,
'body': json_dumps({"message": 'Challenge not found'})
}

challenge = response['Item']

if not challenge:
return {
'statusCode': 404,
'body': json.dumps({"message": 'Challenge not found'})
'body': json_dumps({"message": 'Challenge not found'})
}

if user['challenges_done'].count(challenge['challenge']) + user['challenges_pending'].count(challenge['challenge']) >= challenge['max_count']:
return {
'statusCode': 400,
'body': json.dumps({"message": 'You have already completed this challenge the maximum number of times'})
'body': json_dumps({"message": 'You have already completed this challenge the maximum number of times'})
}

t = int(time())
print(f'Time : {t}')
if challenge['start'] > t or challenge['end'] < t:
return {
'statusCode': 400,
'body': json.dumps({"message": 'Challenge not active'})
'body': json_dumps({"message": 'Challenge not active'})
}

# Add the challenge to the user's pending challenges
Expand All @@ -56,11 +71,11 @@ def lambda_handler(event, context):

return {
'statusCode': 200,
'body': json.dumps({"message": 'Challenge requested'})
'body': json_dumps({"message": 'Challenge requested'})
}

except Exception as error:
return {
"statusCode": 500,
"body": json.dumps({"message": str(error)})
"body": json_dumps({"message": str(error)})
}
7 changes: 7 additions & 0 deletions template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ Resources:
LambdaConfig:
PostConfirmation: !GetAtt PostConfirmSignUpFunction.Arn

WeiAppUserPoolAdminGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
Description: Admin group
GroupName: Admin
UserPoolId: !Ref WeiAppUserPool

OnCognitoPostConfirmationSignUpPermission:
Type: AWS::Lambda::Permission
Properties:
Expand Down
Loading

0 comments on commit 2bc9674

Please sign in to comment.