Skip to content

Commit

Permalink
fix(event_sources): add test for Function URL AuthZ (#1421)
Browse files Browse the repository at this point in the history
Co-authored-by: heitorlessa <lessa@amazon.co.uk>
  • Loading branch information
rubenfonseca and heitorlessa authored Aug 5, 2022
1 parent 9f1555c commit 3ed48e7
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,26 +123,26 @@ def caller_id(self) -> Optional[str]:
"""The principal identifier of the caller making the request."""
return self.get("callerId")

def _cognito_identity(self) -> Dict:
return self.get("cognitoIdentity", {}) or {} # not available in FunctionURL

@property
def cognito_amr(self) -> Optional[List[str]]:
"""This represents how the user was authenticated.
AMR stands for Authentication Methods References as per the openid spec"""
cognito_identity = self["cognitoIdentity"] or {} # not available in FunctionURL
return cognito_identity.get("amr")
return self._cognito_identity().get("amr")

@property
def cognito_identity_id(self) -> Optional[str]:
"""The Amazon Cognito identity ID of the caller making the request.
Available only if the request was signed with Amazon Cognito credentials."""
cognito_identity = self.get("cognitoIdentity") or {} # not available in FunctionURL
return cognito_identity.get("identityId")
return self._cognito_identity().get("identityId")

@property
def cognito_identity_pool_id(self) -> Optional[str]:
"""The Amazon Cognito identity pool ID of the caller making the request.
Available only if the request was signed with Amazon Cognito credentials."""
cognito_identity = self.get("cognitoIdentity") or {} # not available in FunctionURL
return cognito_identity.get("identityPoolId")
return self._cognito_identity().get("identityPoolId")

@property
def principal_org_id(self) -> Optional[str]:
Expand Down
95 changes: 45 additions & 50 deletions tests/events/lambdaFunctionUrlEvent.json
Original file line number Diff line number Diff line change
@@ -1,52 +1,47 @@
{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/my/path",
"rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
"cookies": [
"cookie1",
"cookie2"
],
"headers": {
"header1": "value1",
"header2": "value1,value2"
},
"queryStringParameters": {
"parameter1": "value1,value2",
"parameter2": "value"
},
"requestContext": {
"accountId": "123456789012",
"apiId": "<urlid>",
"authentication": null,
"authorizer": {
"iam": {
"accessKey": "AKIA...",
"accountId": "111122223333",
"callerId": "AIDA...",
"cognitoIdentity": null,
"principalOrgId": null,
"userArn": "arn:aws:iam::111122223333:user/example-user",
"userId": "AIDA..."
}
},
"domainName": "<url-id>.lambda-url.us-west-2.on.aws",
"domainPrefix": "<url-id>",
"http": {
"method": "POST",
"path": "/my/path",
"protocol": "HTTP/1.1",
"sourceIp": "123.123.123.123",
"userAgent": "agent"
},
"requestId": "id",
"routeKey": "$default",
"stage": "$default",
"time": "12/Mar/2020:19:03:58 +0000",
"timeEpoch": 1583348638390
},
"body": "Hello from client!",
"pathParameters": null,
"isBase64Encoded": false,
"stageVariables": null
"version":"2.0",
"routeKey":"$default",
"rawPath":"/",
"rawQueryString":"",
"headers":{
"sec-fetch-mode":"navigate",
"x-amzn-tls-version":"TLSv1.2",
"sec-fetch-site":"cross-site",
"accept-language":"pt-BR,pt;q=0.9",
"x-forwarded-proto":"https",
"x-forwarded-port":"443",
"x-forwarded-for":"123.123.123.123",
"sec-fetch-user":"?1",
"accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"x-amzn-tls-cipher-suite":"ECDHE-RSA-AES128-GCM-SHA256",
"sec-ch-ua":"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"",
"sec-ch-ua-mobile":"?0",
"x-amzn-trace-id":"Root=1-62ecd163-5f302e550dcde3b12402207d",
"sec-ch-ua-platform":"\"Linux\"",
"host":"<url-id>.lambda-url.us-east-1.on.aws",
"upgrade-insecure-requests":"1",
"cache-control":"max-age=0",
"accept-encoding":"gzip, deflate, br",
"sec-fetch-dest":"document",
"user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"
},
"requestContext":{
"accountId":"anonymous",
"apiId":"<url-id>",
"domainName":"<url-id>.lambda-url.us-east-1.on.aws",
"domainPrefix":"<url-id>",
"http":{
"method":"GET",
"path":"/",
"protocol":"HTTP/1.1",
"sourceIp":"123.123.123.123",
"userAgent":"agent"
},
"requestId":"id",
"routeKey":"$default",
"stage":"$default",
"time":"05/Aug/2022:08:14:39 +0000",
"timeEpoch":1659687279885
},
"isBase64Encoded":false
}
52 changes: 52 additions & 0 deletions tests/events/lambdaFunctionUrlIAMEvent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/my/path",
"rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
"cookies": [
"cookie1",
"cookie2"
],
"headers": {
"header1": "value1",
"header2": "value1,value2"
},
"queryStringParameters": {
"parameter1": "value1,value2",
"parameter2": "value"
},
"requestContext": {
"accountId": "123456789012",
"apiId": "<urlid>",
"authentication": null,
"authorizer": {
"iam": {
"accessKey": "AKIA...",
"accountId": "111122223333",
"callerId": "AIDA...",
"cognitoIdentity": null,
"principalOrgId": null,
"userArn": "arn:aws:iam::111122223333:user/example-user",
"userId": "AIDA..."
}
},
"domainName": "<url-id>.lambda-url.us-west-2.on.aws",
"domainPrefix": "<url-id>",
"http": {
"method": "POST",
"path": "/my/path",
"protocol": "HTTP/1.1",
"sourceIp": "123.123.123.123",
"userAgent": "agent"
},
"requestId": "id",
"routeKey": "$default",
"stage": "$default",
"time": "12/Mar/2020:19:03:58 +0000",
"timeEpoch": 1583348638390
},
"body": "Hello from client!",
"pathParameters": null,
"isBase64Encoded": false,
"stageVariables": null
}
46 changes: 46 additions & 0 deletions tests/functional/data_classes/test_lambda_function_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,51 @@ def test_lambda_function_url_event():
assert event.version == "2.0"
assert event.route_key == "$default"

assert event.path == "/"
assert event.raw_query_string == ""

assert event.cookies is None

headers = event.headers
assert len(headers) == 20

assert event.query_string_parameters is None

assert event.is_base64_encoded is False
assert event.body is None
assert event.path_parameters is None
assert event.stage_variables is None
assert event.http_method == "GET"

request_context = event.request_context

assert request_context.account_id == "anonymous"
assert request_context.api_id is not None
assert request_context.domain_name == "<url-id>.lambda-url.us-east-1.on.aws"
assert request_context.domain_prefix == "<url-id>"
assert request_context.request_id == "id"
assert request_context.route_key == "$default"
assert request_context.stage == "$default"
assert request_context.time is not None
assert request_context.time_epoch == 1659687279885
assert request_context.authentication is None

http = request_context.http
assert http.method == "GET"
assert http.path == "/"
assert http.protocol == "HTTP/1.1"
assert http.source_ip == "123.123.123.123"
assert http.user_agent == "agent"

assert request_context.authorizer is None


def test_lambda_function_url_event_iam():
event = LambdaFunctionUrlEvent(load_event("lambdaFunctionUrlIAMEvent.json"))

assert event.version == "2.0"
assert event.route_key == "$default"

assert event.path == "/my/path"
assert event.raw_query_string == "parameter1=value1&parameter1=value2&parameter2=value"

Expand Down Expand Up @@ -60,6 +105,7 @@ def test_lambda_function_url_event():
assert iam.access_key is not None
assert iam.account_id == "111122223333"
assert iam.caller_id is not None
assert iam.cognito_amr is None
assert iam.cognito_identity_id is None
assert iam.cognito_identity_pool_id is None
assert iam.principal_org_id is None
Expand Down
4 changes: 2 additions & 2 deletions tests/functional/event_handler/test_lambda_function_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def foo():
return Response(200, content_types.TEXT_HTML, "foo")

# WHEN calling the event handler
result = app(load_event("lambdaFunctionUrlEvent.json"), {})
result = app(load_event("lambdaFunctionUrlIAMEvent.json"), {})

# THEN process event correctly
# AND set the current_event type as LambdaFunctionUrlEvent
Expand All @@ -33,7 +33,7 @@ def foo():
raise RuntimeError()

# WHEN calling the event handler
result = app(load_event("lambdaFunctionUrlEvent.json"), {})
result = app(load_event("lambdaFunctionUrlIAMEvent.json"), {})

# THEN process event correctly
# AND return 404 because the event doesn't match any known route
Expand Down

0 comments on commit 3ed48e7

Please sign in to comment.