Skip to content

Commit 4f81f22

Browse files
authored
fix: surface user-facing errors for malformed Auth.securityDefinitions and Domain.AccessAssociation (#3923)
1 parent aadb050 commit 4f81f22

6 files changed

Lines changed: 78 additions & 0 deletions

samtranslator/model/api/api_generator.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,10 @@ def _generate_domain_access_association(
15891589
"""
15901590
Generate domain access association resource
15911591
"""
1592+
# Validate before .get() so a non-map (e.g. a string) raises a user-facing
1593+
# error pointing at the resource and property instead of an opaque
1594+
# AttributeError surfaced as "Internal transform failure".
1595+
sam_expect(domain_access_association, self.logical_id, "Domain.AccessAssociation").to_be_a_map()
15921596
vpcEndpointId = domain_access_association.get("VpcEndpointId")
15931597
logical_id = LogicalIdGenerator("DomainNameAccessAssociation", [vpcEndpointId, domain_logical_id]).gen()
15941598

samtranslator/swagger/swagger.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,11 @@ def add_authorizers_security_definitions(self, authorizers): # type: ignore[no-
475475
:param list authorizers: List of Authorizer configurations which get translated to securityDefinitions.
476476
"""
477477
self.security_definitions = self.security_definitions or Py27Dict()
478+
if not isinstance(self.security_definitions, dict):
479+
# The user's DefinitionBody supplied securityDefinitions as a non-dict
480+
# (e.g. a YAML list). Indexing self.security_definitions[name] below
481+
# would raise an opaque TypeError; surface a user-facing error instead.
482+
raise InvalidTemplateException("securityDefinitions must be a dictionary.")
478483

479484
for authorizer_name, authorizer in authorizers.items():
480485
self.security_definitions[authorizer_name] = authorizer.generate_swagger()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Resources:
2+
MyApi:
3+
Type: AWS::Serverless::Api
4+
Properties:
5+
StageName: Prod
6+
Domain:
7+
DomainName: example.com
8+
CertificateArn: arn:aws:acm:us-east-1:111111111111:certificate/abcd
9+
EndpointConfiguration: PRIVATE
10+
# Malformed: AccessAssociation must be a map (with VpcEndpointId).
11+
# Previously this crashed the transform with a Python
12+
# `AttributeError: 'str' object has no attribute 'get'`, which
13+
# CloudFormation surfaced as "Internal transform failure".
14+
AccessAssociation: vpce-1234567890abcdef0
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Resources:
2+
MyApi:
3+
Type: AWS::Serverless::Api
4+
Properties:
5+
StageName: Prod
6+
Auth:
7+
Authorizers:
8+
MyAuth:
9+
FunctionArn: arn:aws:lambda:us-east-1:111111111111:function:authfn
10+
FunctionPayloadType: TOKEN
11+
DefaultAuthorizer: MyAuth
12+
# Malformed: securityDefinitions must be a dict, not a list. When SAM
13+
# tried to attach the authorizer it indexed the list with a string and
14+
# crashed the transform with a Python
15+
# `TypeError: list indices must be integers or slices, not Py27UniStr`,
16+
# which CloudFormation surfaced as "Internal transform failure".
17+
DefinitionBody:
18+
swagger: '2.0'
19+
info:
20+
title: MyApi
21+
version: '1.0'
22+
securityDefinitions:
23+
- InvalidEntryShouldBeDict
24+
paths:
25+
/:
26+
get:
27+
responses: {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"_autoGeneratedBreakdownErrorMessage": [
3+
"Invalid Serverless Application Specification document. ",
4+
"Number of errors found: 1. ",
5+
"Resource with id [MyApi] is invalid. ",
6+
"Property 'Domain.AccessAssociation' should be a map."
7+
],
8+
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MyApi] is invalid. Property 'Domain.AccessAssociation' should be a map.",
9+
"errors": [
10+
{
11+
"errorMessage": "Resource with id [MyApi] is invalid. Property 'Domain.AccessAssociation' should be a map."
12+
}
13+
]
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"_autoGeneratedBreakdownErrorMessage": [
3+
"Invalid Serverless Application Specification document. ",
4+
"Number of errors found: 1. ",
5+
"Structure of the SAM template is invalid. ",
6+
"securityDefinitions must be a dictionary."
7+
],
8+
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Structure of the SAM template is invalid. securityDefinitions must be a dictionary.",
9+
"errors": [
10+
{
11+
"errorMessage": "Structure of the SAM template is invalid. securityDefinitions must be a dictionary."
12+
}
13+
]
14+
}

0 commit comments

Comments
 (0)