Skip to content

feat(event_sources): add get_context() to standardize API Gateway Lambda Authorizer context in v1 and v2 #3454

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 9 commits into from
Dec 6, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ def integration_latency(self) -> Optional[int]:
"""The authorizer latency in ms."""
return self.get("integrationLatency")

def get_context(self) -> Dict[str, Any]:
"""Retrieve the authorization context details injected by a Lambda Authorizer.

Example
--------

```python
ctx: dict = request_context.authorizer.get_context()

tenant_id = ctx.get("tenant_id")
```

Returns:
--------
Dict[str, Any]
A dictionary containing Lambda authorization context details.
"""
return self._data


class APIGatewayEventRequestContext(BaseRequestContext):
@property
Expand Down Expand Up @@ -184,6 +203,25 @@ def get_lambda(self) -> Optional[Dict[str, Any]]:
"""Lambda authorization context details"""
return self.get("lambda")

def get_context(self) -> Dict[str, Any]:
"""Retrieve the authorization context details injected by a Lambda Authorizer.

Example
--------

```python
ctx: dict = request_context.authorizer.get_context()

tenant_id = ctx.get("tenant_id")
```

Returns:
--------
Dict[str, Any]
A dictionary containing Lambda authorization context details.
"""
return self.get("lambda", {}) or {}

@property
def iam(self) -> Optional[RequestContextV2AuthorizerIam]:
"""IAM authorization details used for making the request."""
Expand Down
15 changes: 12 additions & 3 deletions tests/events/apiGatewayProxyV2LambdaAuthorizerEvent.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@
"stage": "$default",
"requestId": "id",
"authorizer": {
"jwt": {
"claims": {
"claim1": "value1"
},
"scopes": [
"scope1",
"scope2"
]
},
"lambda": {
"key": "value"
"tenantId": "123-456-789-012"
}
},
},
"apiId": "api-id",
"domainName": "id.execute-api.us-east-1.amazonaws.com",
"domainPrefix": "id",
Expand All @@ -47,4 +56,4 @@
},
"body": "{\r\n\t\"a\": 1\r\n}",
"isBase64Encoded": false
}
}
20 changes: 19 additions & 1 deletion tests/unit/data_classes/test_api_gateway_proxy_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ def test_api_gateway_proxy_event_with_principal_id():
assert authorizer.integration_latency == raw_event["requestContext"]["authorizer"]["integrationLatency"]
assert authorizer.get("integrationStatus", "failed") == "failed"

# Accessing context with direct function
context_variables = request_context.authorizer.get_context()
assert context_variables.get("user_id") == raw_event["requestContext"]["authorizer"]["user_id"]


def test_api_gateway_proxy_v2_event():
raw_event = load_event("apiGatewayProxyV2Event.json")
Expand Down Expand Up @@ -200,9 +204,23 @@ def test_api_gateway_proxy_v2_lambda_authorizer_event():

request_context = parsed_event.request_context
assert request_context is not None

lambda_props = request_context.authorizer.get_lambda
assert lambda_props is not None
assert lambda_props.get("key") == "value"
assert lambda_props.get("tenantId") == raw_event["requestContext"]["authorizer"]["lambda"]["tenantId"]

# Accessing context with direct function
context_variables = request_context.authorizer.get_context()
assert context_variables.get("tenantId") == raw_event["requestContext"]["authorizer"]["lambda"]["tenantId"]

jwt_claims = request_context.authorizer.jwt_claim
assert jwt_claims is not None
assert jwt_claims.get("claim1") == raw_event["requestContext"]["authorizer"]["jwt"]["claims"]["claim1"]

jwt_scopes = request_context.authorizer.jwt_scopes
assert jwt_scopes is not None
assert jwt_scopes[0] == raw_event["requestContext"]["authorizer"]["jwt"]["scopes"][0]
assert jwt_scopes[1] == raw_event["requestContext"]["authorizer"]["jwt"]["scopes"][1]


def test_api_gateway_proxy_v2_iam_event():
Expand Down
11 changes: 10 additions & 1 deletion tests/unit/parser/test_apigwv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,16 @@ def test_api_gateway_proxy_v2_event_lambda_authorizer():

lambda_props: RequestContextV2Authorizer = request_context.authorizer.lambda_value
assert lambda_props is not None
assert lambda_props["key"] == raw_event["requestContext"]["authorizer"]["lambda"]["key"]
assert lambda_props["tenantId"] == raw_event["requestContext"]["authorizer"]["lambda"]["tenantId"]

jwt_claims: RequestContextV2Authorizer = request_context.authorizer.jwt.claims
assert jwt_claims is not None
assert jwt_claims["claim1"] == raw_event["requestContext"]["authorizer"]["jwt"]["claims"]["claim1"]

jwt_scopes: RequestContextV2Authorizer = request_context.authorizer.jwt.scopes
assert jwt_scopes is not None
assert jwt_scopes[0] == raw_event["requestContext"]["authorizer"]["jwt"]["scopes"][0]
assert jwt_scopes[1] == raw_event["requestContext"]["authorizer"]["jwt"]["scopes"][1]


def test_api_gateway_proxy_v2_event_iam_authorizer():
Expand Down