import os import base64 import boto3 from chalice import Chalice, AuthResponse from chalicelib import auth, db app = Chalice(app_name='mytodo') app.debug = True _DB = None _USER_DB = None _AUTH_KEY = None _SSM_AUTH_KEY_NAME = '/todo-sample-app/auth-key' @app.route('/login', methods=['POST']) def login(): body = app.current_request.json_body record = get_users_db().get_item( Key={'username': body['username']})['Item'] jwt_token = auth.get_jwt_token( body['username'], body['password'], record, get_auth_key()) return {'token': jwt_token} @app.authorizer() def jwt_auth(auth_request): token = auth_request.token decoded = auth.decode_jwt_token(token, get_auth_key()) return AuthResponse(routes=['*'], principal_id=decoded['sub']) def get_auth_key(): global _AUTH_KEY if _AUTH_KEY is None: base64_key = boto3.client('ssm').get_parameter( Name=_SSM_AUTH_KEY_NAME, WithDecryption=True )['Parameter']['Value'] _AUTH_KEY = base64.b64decode(base64_key) return _AUTH_KEY def get_users_db(): global _USER_DB if _USER_DB is None: _USER_DB = boto3.resource('dynamodb').Table( os.environ['USERS_TABLE_NAME']) return _USER_DB def get_app_db(): global _DB if _DB is None: _DB = db.DynamoDBTodo( boto3.resource('dynamodb').Table( os.environ['APP_TABLE_NAME']) ) return _DB def get_authorized_username(current_request): return current_request.context['authorizer']['principalId'] @app.route('/todos', methods=['GET'], authorizer=jwt_auth) def list_todos(): username = get_authorized_username(app.current_request) return get_app_db().list_items(username=username) @app.route('/todos', methods=['POST'], authorizer=jwt_auth) def create_todo(): body = app.current_request.json_body username = get_authorized_username(app.current_request) return get_app_db().add_item( username=username, description=body['description'], metadata=body.get('metadata'), ) @app.route('/todos/{uid}', methods=['GET'], authorizer=jwt_auth) def get_todo(uid): username = get_authorized_username(app.current_request) return get_app_db().get_item(uid, username=username) @app.route('/todos/{uid}', methods=['PUT'], authorizer=jwt_auth) def update_todo(uid): body = app.current_request.json_body username = get_authorized_username(app.current_request) get_app_db().update_item( uid, description=body.get('description'), state=body.get('state'), metadata=body.get('metadata'), username=username) @app.route('/todos/{uid}', methods=['DELETE'], authorizer=jwt_auth) def delete_todo(uid): username = get_authorized_username(app.current_request) return get_app_db().delete_item(uid, username=username)