Skip to content

Commit 02ebd1e

Browse files
committed
wip: Allow explicit AWS::NoValue for Api Gateway Default Authorizer
Outstanding: - HTTP API - Integration tests
1 parent c75a133 commit 02ebd1e

14 files changed

+5268
-7
lines changed
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
Resources:
2+
MyApiWithCognitoAuth:
3+
Type: AWS::Serverless::Api
4+
Properties:
5+
StageName: Prod
6+
Auth:
7+
DefaultAuthorizer:
8+
Ref: AWS::NoValue
9+
Authorizers:
10+
MyCognitoAuth:
11+
UserPoolArn: !GetAtt MyUserPool.Arn
12+
13+
MyApiWithLambdaTokenAuth:
14+
Type: AWS::Serverless::Api
15+
Properties:
16+
StageName: Prod
17+
Auth:
18+
DefaultAuthorizer:
19+
Ref: AWS::NoValue
20+
Authorizers:
21+
MyLambdaTokenAuth:
22+
FunctionArn: !GetAtt MyAuthFn.Arn
23+
24+
MyApiWithLambdaRequestAuth:
25+
Type: AWS::Serverless::Api
26+
Properties:
27+
StageName: Prod
28+
Auth:
29+
DefaultAuthorizer:
30+
Ref: AWS::NoValue
31+
Authorizers:
32+
MyLambdaRequestAuth:
33+
FunctionPayloadType: REQUEST
34+
FunctionArn: !GetAtt MyAuthFn.Arn
35+
Identity:
36+
Headers:
37+
- Authorization1
38+
MyAuthFn:
39+
Type: AWS::Serverless::Function
40+
Properties:
41+
CodeUri: s3://bucket/key
42+
Handler: index.handler
43+
Runtime: nodejs12.x
44+
MyFn:
45+
Type: AWS::Serverless::Function
46+
Properties:
47+
CodeUri: s3://bucket/key
48+
Handler: index.handler
49+
Runtime: nodejs12.x
50+
Events:
51+
CognitoNoAuth:
52+
Type: Api
53+
Properties:
54+
RestApiId: !Ref MyApiWithCognitoAuth
55+
Method: get
56+
Path: /cognito/no-auth
57+
CognitoNoAuthAnyMethod:
58+
Type: Api
59+
Properties:
60+
RestApiId: !Ref MyApiWithCognitoAuth
61+
Method: any
62+
Path: /cognito/any/no-auth
63+
Cognito:
64+
Type: Api
65+
Properties:
66+
RestApiId: !Ref MyApiWithCognitoAuth
67+
Method: get
68+
Path: /any/cognito
69+
Auth:
70+
Authorizer: MyCognitoAuth
71+
CognitoAnyMethod:
72+
Type: Api
73+
Properties:
74+
RestApiId: !Ref MyApiWithCognitoAuth
75+
Method: any
76+
Path: /any/cognito
77+
Auth:
78+
Authorizer: MyCognitoAuth
79+
LambdaTokenNoAuth:
80+
Type: Api
81+
Properties:
82+
RestApiId: !Ref MyApiWithLambdaTokenAuth
83+
Method: get
84+
Path: /lambda-token/no-auth
85+
LambdaTokenNoAuthAnyMethod:
86+
Type: Api
87+
Properties:
88+
RestApiId: !Ref MyApiWithLambdaTokenAuth
89+
Method: any
90+
Path: /lambda-token/any/no-auth
91+
LambdaToken:
92+
Type: Api
93+
Properties:
94+
RestApiId: !Ref MyApiWithLambdaTokenAuth
95+
Method: get
96+
Path: /lambda-token
97+
Auth:
98+
Authorizer: MyLambdaTokenAuth
99+
LambdaTokenAnyMethod:
100+
Type: Api
101+
Properties:
102+
RestApiId: !Ref MyApiWithLambdaTokenAuth
103+
Method: any
104+
Path: /any/lambda-token
105+
Auth:
106+
Authorizer: MyLambdaTokenAuth
107+
LambdaRequestNoAuth:
108+
Type: Api
109+
Properties:
110+
RestApiId: !Ref MyApiWithLambdaRequestAuth
111+
Method: get
112+
Path: /lambda-request/no-auth
113+
LambdaRequestNoAuthAnyMethod:
114+
Type: Api
115+
Properties:
116+
RestApiId: !Ref MyApiWithLambdaRequestAuth
117+
Method: any
118+
Path: /lambda-request/any/no-auth
119+
LambdaRequest:
120+
Type: Api
121+
Properties:
122+
RestApiId: !Ref MyApiWithLambdaRequestAuth
123+
Method: get
124+
Path: /lambda-request
125+
Auth:
126+
Authorizer: MyLambdaRequestAuth
127+
LambdaRequestAnyMethod:
128+
Type: Api
129+
Properties:
130+
RestApiId: !Ref MyApiWithLambdaRequestAuth
131+
Method: any
132+
Path: /any/lambda-request
133+
Auth:
134+
Authorizer: MyLambdaRequestAuth
135+
MyUserPool:
136+
Type: AWS::Cognito::UserPool
137+
Properties:
138+
UserPoolName: UserPoolName
139+
Policies:
140+
PasswordPolicy:
141+
MinimumLength: 8
142+
UsernameAttributes:
143+
- email
144+
Schema:
145+
- AttributeDataType: String
146+
Name: email
147+
Required: false

samtranslator/internal/schema_source/aws_serverless_api.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
PassThroughProp,
1212
ResourceAttributes,
1313
SamIntrinsicable,
14+
SamIntrinsicableOrNoValue,
1415
get_prop,
1516
passthrough_prop,
1617
)
@@ -119,7 +120,7 @@ class Auth(BaseModel):
119120
],
120121
]
121122
] = auth("Authorizers")
122-
DefaultAuthorizer: Optional[str] = auth("DefaultAuthorizer")
123+
DefaultAuthorizer: Optional[SamIntrinsicableOrNoValue[str]] = auth("DefaultAuthorizer")
123124
InvokeRole: Optional[str] = auth("InvokeRole")
124125
ResourcePolicy: Optional[ResourcePolicy] = auth("ResourcePolicy")
125126
UsagePlan: Optional[UsagePlan] = auth("UsagePlan")

samtranslator/internal/schema_source/common.py

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class PassThroughProp(pydantic.BaseModel):
2323
T = TypeVar("T")
2424
SamIntrinsicable = Union[Dict[str, Any], T]
2525
SamIntrinsic = Dict[str, Any]
26+
SamIntrinsicNoValue = Dict[Literal["Ref"], Literal["AWS::NoValue"]]
27+
SamIntrinsicableOrNoValue = Union[SamIntrinsicNoValue, T]
2628

2729
# TODO: Get rid of this in favor of proper types
2830
Unknown = Optional[Any]

samtranslator/model/api/api_generator.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
InvalidResourceException,
2424
InvalidTemplateException,
2525
)
26-
from samtranslator.model.intrinsics import fnGetAtt, fnSub, is_intrinsic, make_or_condition, ref
26+
from samtranslator.model.intrinsics import fnGetAtt, fnSub, is_intrinsic, is_intrinsic_no_value, make_or_condition, ref
2727
from samtranslator.model.lambda_ import LambdaPermission
2828
from samtranslator.model.route53 import Route53RecordSetGroup
2929
from samtranslator.model.s3_utils.uri_parser import parse_s3_uri
@@ -1288,7 +1288,7 @@ def _set_default_authorizer(
12881288
default_authorizer: str,
12891289
add_default_auth_to_preflight: bool = True,
12901290
) -> None:
1291-
if not default_authorizer:
1291+
if is_intrinsic_no_value(default_authorizer) or not default_authorizer:
12921292
return
12931293

12941294
if not isinstance(default_authorizer, str):

samtranslator/schema/schema.json

+15-2
Original file line numberDiff line numberDiff line change
@@ -247480,9 +247480,22 @@
247480247480
"type": "object"
247481247481
},
247482247482
"DefaultAuthorizer": {
247483+
"anyOf": [
247484+
{
247485+
"additionalProperties": {
247486+
"enum": [
247487+
"AWS::NoValue"
247488+
],
247489+
"type": "string"
247490+
},
247491+
"type": "object"
247492+
},
247493+
{
247494+
"type": "string"
247495+
}
247496+
],
247483247497
"markdownDescription": "Specify a default authorizer for an API Gateway API, which will be used for authorizing API calls by default\\. \nIf the Api EventSource for the function associated with this API is configured to use IAM Permissions, then this property must be set to `AWS_IAM`, otherwise an error will result\\.\n*Type*: String \n*Required*: No \n*Default*: None \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
247484-
"title": "DefaultAuthorizer",
247485-
"type": "string"
247498+
"title": "DefaultAuthorizer"
247486247499
},
247487247500
"InvokeRole": {
247488247501
"markdownDescription": "Sets integration credentials for all resources and methods to this value\\. \n`CALLER_CREDENTIALS` maps to `arn:aws:iam::*:user/*`, which uses the caller credentials to invoke the endpoint\\. \n*Valid values*: `CALLER_CREDENTIALS`, `NONE`, `IAMRoleArn` \n*Type*: String \n*Required*: No \n*Default*: `CALLER_CREDENTIALS` \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",

schema_source/sam.schema.json

+15-2
Original file line numberDiff line numberDiff line change
@@ -3422,9 +3422,22 @@
34223422
"type": "object"
34233423
},
34243424
"DefaultAuthorizer": {
3425+
"anyOf": [
3426+
{
3427+
"additionalProperties": {
3428+
"enum": [
3429+
"AWS::NoValue"
3430+
],
3431+
"type": "string"
3432+
},
3433+
"type": "object"
3434+
},
3435+
{
3436+
"type": "string"
3437+
}
3438+
],
34253439
"markdownDescription": "Specify a default authorizer for an API Gateway API, which will be used for authorizing API calls by default\\. \nIf the Api EventSource for the function associated with this API is configured to use IAM Permissions, then this property must be set to `AWS_IAM`, otherwise an error will result\\.\n*Type*: String \n*Required*: No \n*Default*: None \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
3426-
"title": "DefaultAuthorizer",
3427-
"type": "string"
3440+
"title": "DefaultAuthorizer"
34283441
},
34293442
"InvokeRole": {
34303443
"markdownDescription": "Sets integration credentials for all resources and methods to this value\\. \n`CALLER_CREDENTIALS` maps to `arn:aws:iam::*:user/*`, which uses the caller credentials to invoke the endpoint\\. \n*Valid values*: `CALLER_CREDENTIALS`, `NONE`, `IAMRoleArn` \n*Type*: String \n*Required*: No \n*Default*: `CALLER_CREDENTIALS` \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
Resources:
2+
MyApiWithCognitoAuth:
3+
Type: AWS::Serverless::Api
4+
Properties:
5+
StageName: Prod
6+
Auth:
7+
DefaultAuthorizer: !Ref AWS::NoValue
8+
Authorizers:
9+
MyCognitoAuth:
10+
UserPoolArn: !GetAtt MyUserPool.Arn
11+
12+
MyApiWithLambdaTokenAuth:
13+
Type: AWS::Serverless::Api
14+
Properties:
15+
StageName: Prod
16+
Auth:
17+
DefaultAuthorizer: !Ref AWS::NoValue
18+
Authorizers:
19+
MyLambdaTokenAuth:
20+
FunctionArn: !GetAtt MyAuthFn.Arn
21+
22+
MyApiWithLambdaRequestAuth:
23+
Type: AWS::Serverless::Api
24+
Properties:
25+
StageName: Prod
26+
Auth:
27+
DefaultAuthorizer: !Ref AWS::NoValue
28+
Authorizers:
29+
MyLambdaRequestAuth:
30+
FunctionPayloadType: REQUEST
31+
FunctionArn: !GetAtt MyAuthFn.Arn
32+
Identity:
33+
Headers:
34+
- Authorization1
35+
MyAuthFn:
36+
Type: AWS::Serverless::Function
37+
Properties:
38+
CodeUri: s3://bucket/key
39+
Handler: index.handler
40+
Runtime: nodejs12.x
41+
MyFn:
42+
Type: AWS::Serverless::Function
43+
Properties:
44+
CodeUri: s3://bucket/key
45+
Handler: index.handler
46+
Runtime: nodejs12.x
47+
Events:
48+
CognitoNoAuth:
49+
Type: Api
50+
Properties:
51+
RestApiId: !Ref MyApiWithCognitoAuth
52+
Method: get
53+
Path: /cognito/no-auth
54+
CognitoNoAuthAnyMethod:
55+
Type: Api
56+
Properties:
57+
RestApiId: !Ref MyApiWithCognitoAuth
58+
Method: any
59+
Path: /cognito/any/no-auth
60+
Cognito:
61+
Type: Api
62+
Properties:
63+
RestApiId: !Ref MyApiWithCognitoAuth
64+
Method: get
65+
Path: /any/cognito
66+
Auth:
67+
Authorizer: MyCognitoAuth
68+
CognitoAnyMethod:
69+
Type: Api
70+
Properties:
71+
RestApiId: !Ref MyApiWithCognitoAuth
72+
Method: any
73+
Path: /any/cognito
74+
Auth:
75+
Authorizer: MyCognitoAuth
76+
LambdaTokenNoAuth:
77+
Type: Api
78+
Properties:
79+
RestApiId: !Ref MyApiWithLambdaTokenAuth
80+
Method: get
81+
Path: /lambda-token/no-auth
82+
LambdaTokenNoAuthAnyMethod:
83+
Type: Api
84+
Properties:
85+
RestApiId: !Ref MyApiWithLambdaTokenAuth
86+
Method: any
87+
Path: /lambda-token/any/no-auth
88+
LambdaToken:
89+
Type: Api
90+
Properties:
91+
RestApiId: !Ref MyApiWithLambdaTokenAuth
92+
Method: get
93+
Path: /lambda-token
94+
Auth:
95+
Authorizer: MyLambdaTokenAuth
96+
LambdaTokenAnyMethod:
97+
Type: Api
98+
Properties:
99+
RestApiId: !Ref MyApiWithLambdaTokenAuth
100+
Method: any
101+
Path: /any/lambda-token
102+
Auth:
103+
Authorizer: MyLambdaTokenAuth
104+
LambdaRequestNoAuth:
105+
Type: Api
106+
Properties:
107+
RestApiId: !Ref MyApiWithLambdaRequestAuth
108+
Method: get
109+
Path: /lambda-request/no-auth
110+
LambdaRequestNoAuthAnyMethod:
111+
Type: Api
112+
Properties:
113+
RestApiId: !Ref MyApiWithLambdaRequestAuth
114+
Method: any
115+
Path: /lambda-request/any/no-auth
116+
LambdaRequest:
117+
Type: Api
118+
Properties:
119+
RestApiId: !Ref MyApiWithLambdaRequestAuth
120+
Method: get
121+
Path: /lambda-request
122+
Auth:
123+
Authorizer: MyLambdaRequestAuth
124+
LambdaRequestAnyMethod:
125+
Type: Api
126+
Properties:
127+
RestApiId: !Ref MyApiWithLambdaRequestAuth
128+
Method: any
129+
Path: /any/lambda-request
130+
Auth:
131+
Authorizer: MyLambdaRequestAuth
132+
MyUserPool:
133+
Type: AWS::Cognito::UserPool
134+
Properties:
135+
UserPoolName: UserPoolName
136+
Policies:
137+
PasswordPolicy:
138+
MinimumLength: 8
139+
UsernameAttributes:
140+
- email
141+
Schema:
142+
- AttributeDataType: String
143+
Name: email
144+
Required: false

0 commit comments

Comments
 (0)