"""Lambda spotify-api function module.""" import jwt from lambdacommon.common_config import logger import config def handler(event, context): """Lambda entry point.""" try: logger.info('Extracting token from the event...') authorization_token = _extract_token(event) jwks_client = jwt.PyJWKClient(config.JWK_CLIENT_URI) signing_key = jwks_client.get_signing_key_from_jwt(authorization_token) jwt.decode( authorization_token, signing_key.key, algorithms=['RS256'], issuer=config.TOKEN_ISSUER, audience=config.TOKEN_AUDIENCE) logger.info('Token is valid. Operation is allowed.') return generate_policy( 'user', 'Allow', _api_resource_arn(event['methodArn'])) except jwt.exceptions.PyJWTError as e: logger.warning(f'JWT validation failed with the error {e}') return generate_policy( 'user', 'Deny', _api_resource_arn(event['methodArn'])) except Exception as e: logger.error(f'Failed with the error {e}') return 'unauthorized' def _extract_token(event): """Extract token from the event.""" header = event['authorizationToken'] return header.split(' ')[1] def _api_resource_arn(method_arn): """Build a wildcard resource ARN scoped to the entire API+stage.""" prefix, resource = method_arn.rsplit(':', 1) api_id, stage, *_ = resource.split('/') return f'{prefix}:{api_id}/{stage}/*/*' def generate_policy(principal_id, effect, resource): """Generate policy for the given principal id, effect and resource.""" return { 'principalId': principal_id, 'policyDocument': { 'Version': '2012-10-17', 'Statement': [{ 'Action': 'execute-api:Invoke', 'Effect': effect, 'Resource': resource }] } }