Skip to content

fix(event_sources): add test for Function URL AuthZ #1421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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