From 58e8f39bde12d71bea59429b00296fe3acad9993 Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Tue, 14 Dec 2021 12:14:32 -0800 Subject: [PATCH 1/2] fix(event-sources): Pass authorizer data to APIGatewayEventAuthorizer Changes: - contract APIGatewayEventAuthorizer from the authorizer data - add test cases for the additional fields that can optional be in the authorizer dict - Update DictWrapper to allow for a default in `get` --- .../data_classes/api_gateway_proxy_event.py | 6 +++--- .../utilities/data_classes/common.py | 4 ++-- tests/events/apiGatewayProxyEventPrincipalId.json | 13 +++++++++++++ tests/functional/test_data_classes.py | 12 ++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 tests/events/apiGatewayProxyEventPrincipalId.json diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index 34ac8d83993..c6c7342a416 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -11,11 +11,11 @@ class APIGatewayEventAuthorizer(DictWrapper): @property def claims(self) -> Optional[Dict[str, Any]]: - return self["requestContext"]["authorizer"].get("claims") + return self.get("claims") @property def scopes(self) -> Optional[List[str]]: - return self["requestContext"]["authorizer"].get("scopes") + return self.get("scopes") class APIGatewayEventRequestContext(BaseRequestContext): @@ -56,7 +56,7 @@ def route_key(self) -> Optional[str]: @property def authorizer(self) -> APIGatewayEventAuthorizer: - return APIGatewayEventAuthorizer(self._data) + return APIGatewayEventAuthorizer(self._data["requestContext"]["authorizer"]) class APIGatewayProxyEvent(BaseProxyEvent): diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 566e1c56259..f209fc8c192 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -18,8 +18,8 @@ def __eq__(self, other: Any) -> bool: return self._data == other._data - def get(self, key: str) -> Optional[Any]: - return self._data.get(key) + def get(self, key: str, default: Optional[Any] = None) -> Optional[Any]: + return self._data.get(key, default) @property def raw_event(self) -> Dict[str, Any]: diff --git a/tests/events/apiGatewayProxyEventPrincipalId.json b/tests/events/apiGatewayProxyEventPrincipalId.json new file mode 100644 index 00000000000..f18a2a44bbd --- /dev/null +++ b/tests/events/apiGatewayProxyEventPrincipalId.json @@ -0,0 +1,13 @@ +{ + "resource": "/trip", + "path": "/trip", + "httpMethod": "POST", + "requestContext": { + "requestId": "34972478-2843-4ced-a657-253108738274", + "authorizer": { + "user_id": "fake_username", + "principalId": "fake", + "integrationLatency": 451 + } + } +} diff --git a/tests/functional/test_data_classes.py b/tests/functional/test_data_classes.py index ded32639233..3cff0630c3d 100644 --- a/tests/functional/test_data_classes.py +++ b/tests/functional/test_data_classes.py @@ -897,6 +897,18 @@ def test_api_gateway_proxy_event(): assert request_context.identity.client_cert.subject_dn == "www.example.com" +def test_api_gateway_proxy_event_with_principal_id(): + event = APIGatewayProxyEvent(load_event("apiGatewayProxyEventPrincipalId.json")) + + request_context = event.request_context + authorizer = request_context.authorizer + assert authorizer.claims is None + assert authorizer.scopes is None + assert authorizer["principalId"] == "fake" + assert authorizer.get("principalId") == "fake" + assert authorizer.get("foo", "default") == "default" + + def test_api_gateway_proxy_v2_event(): event = APIGatewayProxyEventV2(load_event("apiGatewayProxyV2Event.json")) From c2461367037640812c862caee3bf5c6f06ec3c5f Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Tue, 14 Dec 2021 12:34:13 -0800 Subject: [PATCH 2/2] feat: add missing properties from authorizer --- .../utilities/data_classes/api_gateway_proxy_event.py | 11 +++++++++++ tests/functional/test_data_classes.py | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index c6c7342a416..adce2d4b11b 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -17,6 +17,17 @@ def claims(self) -> Optional[Dict[str, Any]]: def scopes(self) -> Optional[List[str]]: return self.get("scopes") + @property + def principal_id(self) -> Optional[str]: + """The principal user identification associated with the token sent by the client and returned from an + API Gateway Lambda authorizer (formerly known as a custom authorizer)""" + return self.get("principalId") + + @property + def integration_latency(self) -> Optional[int]: + """The authorizer latency in ms.""" + return self.get("integrationLatency") + class APIGatewayEventRequestContext(BaseRequestContext): @property diff --git a/tests/functional/test_data_classes.py b/tests/functional/test_data_classes.py index 3cff0630c3d..7a211ec2e01 100644 --- a/tests/functional/test_data_classes.py +++ b/tests/functional/test_data_classes.py @@ -906,7 +906,9 @@ def test_api_gateway_proxy_event_with_principal_id(): assert authorizer.scopes is None assert authorizer["principalId"] == "fake" assert authorizer.get("principalId") == "fake" - assert authorizer.get("foo", "default") == "default" + assert authorizer.principal_id == "fake" + assert authorizer.integration_latency == 451 + assert authorizer.get("integrationStatus", "failed") == "failed" def test_api_gateway_proxy_v2_event():