Skip to content

fix(event_handler): security scheme unhashable list when working with router #4421

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
12 changes: 7 additions & 5 deletions aws_lambda_powertools/event_handler/api_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
from aws_lambda_powertools.event_handler.util import (
_FrozenDict,
_FrozenListDict,
_validate_openapi_security_parameters,
extract_origin_header,
validate_openapi_security_parameters,
)
from aws_lambda_powertools.shared.cookies import Cookie
from aws_lambda_powertools.shared.functions import powertools_dev_is_set
Expand Down Expand Up @@ -1595,12 +1595,13 @@ def get_openapi_schema(
# Add routes to the OpenAPI schema
for route in all_routes:

if route.security and not validate_openapi_security_parameters(
if route.security and not _validate_openapi_security_parameters(
security=route.security,
security_schemes=security_schemes,
):
raise SchemaValidationError(
"Security configuration was not found in security_schemas or security_schema was not defined.",
"Security configuration was not found in security_schemas or security_schema was not defined. "
"See: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#security-schemes",
)

if not route.include_in_schema:
Expand Down Expand Up @@ -1649,9 +1650,10 @@ def _get_openapi_security(
if not security:
return None

if not validate_openapi_security_parameters(security=security, security_schemes=security_schemes):
if not _validate_openapi_security_parameters(security=security, security_schemes=security_schemes):
raise SchemaValidationError(
"Security configuration was not found in security_schemas or security_schema was not defined.",
"Security configuration was not found in security_schemas or security_schema was not defined. "
"See: https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#security-schemes",
)

return security
Expand Down
18 changes: 10 additions & 8 deletions aws_lambda_powertools/event_handler/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ def extract_origin_header(resolver_headers: Dict[str, Any]):
return resolved_header


def validate_openapi_security_parameters(
def _validate_openapi_security_parameters(
security: List[Dict[str, List[str]]],
security_schemes: Optional[Dict[str, "SecurityScheme"]],
) -> bool:
"""
Validates the security parameters based on the provided security schemes.
This function checks if all security requirements listed in the 'security'
parameter are defined in the 'security_schemes' dictionary, as specified
in the OpenAPI schema.

Parameters
----------
Expand All @@ -88,11 +90,11 @@ def validate_openapi_security_parameters(
Returns
-------
bool
True if all security scheme names in the `security` parameter are present in the `security_schemes` parameter,
False otherwise.

Whether list of security schemes match allowed security_schemes.
"""

return bool(
security_schemes and all(key in security_schemes for sec in security for key in sec),
)
security_schemes = security_schemes or {}

security_schema_match = all(key in security_schemes for sec in security for key in sec)

return bool(security_schema_match and security_schemes)
6 changes: 3 additions & 3 deletions tests/functional/event_handler/test_openapi_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def handler():
raise NotImplementedError()

# WHEN the get_openapi_schema method is called with security defined security schemes as APIKey
# WHEN top level security is defined as HTTPBearer
# AND top level security is defined as HTTPBearer
# THEN a SchemaValidationError should be raised
with pytest.raises(SchemaValidationError):
app.get_openapi_schema(
Expand Down Expand Up @@ -80,7 +80,7 @@ def test_openapi_operation_level_security_missing():
# GIVEN an APIGatewayRestResolver instance
app = APIGatewayRestResolver()

# WHEN we define a security in operation
# AND a route with a security scheme defined
@app.get("/", security=[{"apiKey": []}])
def handler():
raise NotImplementedError()
Expand All @@ -95,7 +95,7 @@ def test_openapi_operation_level_security_mismatch(security_scheme):
# GIVEN an APIGatewayRestResolver instance
app = APIGatewayRestResolver()

# WHEN we define a security in operation with value HTTPBearer
# AND a route with a security scheme using HTTPBearer
@app.get("/", security=[{"HTTPBearer": []}])
def handler():
raise NotImplementedError()
Expand Down