Skip to content

Commit 675fb89

Browse files
authored
feat: openapi support for auth usecases (#949)
1 parent 7859f19 commit 675fb89

20 files changed

+5329
-8
lines changed

samtranslator/model/api/api_generator.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,29 @@ def _add_auth(self):
287287
self._set_default_authorizer(swagger_editor, authorizers, auth_properties.DefaultAuthorizer)
288288

289289
# Assign the Swagger back to template
290-
self.definition_body = swagger_editor.swagger
290+
291+
self.definition_body = self._openapi_auth_postprocess(swagger_editor.swagger)
292+
293+
def _openapi_auth_postprocess(self, definition_body):
294+
"""
295+
Convert auth components to openapi 3 in definition body if OpenApiVersion flag is specified.
296+
297+
If there is swagger defined in the definition body, we treat it as a swagger spec and do not
298+
make any openapi 3 changes to it.
299+
"""
300+
if definition_body.get('swagger') is not None:
301+
return definition_body
302+
303+
if definition_body.get('openapi') is not None:
304+
if self.open_api_version is None:
305+
self.open_api_version = definition_body.get('openapi')
306+
307+
if self.open_api_version and re.match(SwaggerEditor.get_openapi_version_3_regex(), self.open_api_version):
308+
if definition_body.get('securityDefinitions'):
309+
definition_body['components'] = {}
310+
definition_body['components']['securitySchemes'] = definition_body['securityDefinitions']
311+
del definition_body['securityDefinitions']
312+
return definition_body
291313

292314
def _add_gateway_responses(self):
293315
"""

samtranslator/plugins/globals/globals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def fix_openapi_definitions(cls, template):
129129
:param dict template: SAM template
130130
:return: Modified SAM template with corrected swagger doc matching the OpenApiVersion.
131131
"""
132-
resources = template["Resources"]
132+
resources = template.get("Resources", {})
133133

134134
for _, resource in resources.items():
135135
if ("Type" in resource) and (resource["Type"] == cls._API_TYPE):

tests/plugins/globals/test_globals.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,17 @@ class TestGlobalsOpenApi(TestCase):
811811
}
812812
}
813813
},
814-
814+
{
815+
"name": "No Resources",
816+
"input": {
817+
"some": "other",
818+
"swagger": "donottouch"
819+
},
820+
"expected": {
821+
"some": "other",
822+
"swagger": "donottouch"
823+
}
824+
}
815825
]
816826

817827
def test_openapi_postprocess(self):
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
Resources:
2+
MyApi:
3+
Type: "AWS::Serverless::Api"
4+
Properties:
5+
StageName: Prod
6+
OpenApiVersion: '3.0.1'
7+
Auth:
8+
DefaultAuthorizer: MyCognitoAuth
9+
Authorizers:
10+
MyCognitoAuth:
11+
UserPoolArn: arn:aws:1
12+
Identity:
13+
Header: MyAuthorizationHeader
14+
ValidationExpression: myauthvalidationexpression
15+
16+
MyCognitoAuthMultipleUserPools:
17+
UserPoolArn:
18+
- arn:aws:2
19+
- arn:aws:3
20+
Identity:
21+
Header: MyAuthorizationHeader2
22+
ValidationExpression: myauthvalidationexpression2
23+
24+
MyLambdaTokenAuth:
25+
FunctionPayloadType: TOKEN
26+
FunctionArn: arn:aws
27+
FunctionInvokeRole: arn:aws:iam::123456789012:role/S3Access
28+
Identity:
29+
Header: MyCustomAuthHeader
30+
ValidationExpression: mycustomauthexpression
31+
ReauthorizeEvery: 20
32+
33+
MyLambdaTokenAuthNoneFunctionInvokeRole:
34+
FunctionArn: arn:aws
35+
FunctionInvokeRole: NONE
36+
Identity:
37+
ReauthorizeEvery: 0
38+
39+
MyLambdaRequestAuth:
40+
FunctionPayloadType: REQUEST
41+
FunctionArn: arn:aws
42+
FunctionInvokeRole: arn:aws:iam::123456789012:role/S3Access
43+
Identity:
44+
Headers:
45+
- Authorization1
46+
QueryStrings:
47+
- Authorization2
48+
StageVariables:
49+
- Authorization3
50+
Context:
51+
- Authorization4
52+
ReauthorizeEvery: 0
53+
54+
MyFunction:
55+
Type: AWS::Serverless::Function
56+
Properties:
57+
CodeUri: s3://sam-demo-bucket/thumbnails.zip
58+
Handler: index.handler
59+
Runtime: nodejs8.10
60+
Events:
61+
WithNoAuthorizer:
62+
Type: Api
63+
Properties:
64+
RestApiId: !Ref MyApi
65+
Path: /
66+
Method: get
67+
Auth:
68+
Authorizer: NONE
69+
WithCognitoMultipleUserPoolsAuthorizer:
70+
Type: Api
71+
Properties:
72+
RestApiId: !Ref MyApi
73+
Path: /users
74+
Method: post
75+
Auth:
76+
Authorizer: MyCognitoAuthMultipleUserPools
77+
WithLambdaTokenAuthorizer:
78+
Type: Api
79+
Properties:
80+
RestApiId: !Ref MyApi
81+
Path: /users
82+
Method: get
83+
Auth:
84+
Authorizer: MyLambdaTokenAuth
85+
WithLambdaTokenAuthorizer:
86+
Type: Api
87+
Properties:
88+
RestApiId: !Ref MyApi
89+
Path: /users
90+
Method: patch
91+
Auth:
92+
Authorizer: MyLambdaTokenAuthNoneFunctionInvokeRole
93+
WithLambdaRequestAuthorizer:
94+
Type: Api
95+
Properties:
96+
RestApiId: !Ref MyApi
97+
Path: /users
98+
Method: delete
99+
Auth:
100+
Authorizer: MyLambdaRequestAuth
101+
WithDefaultAuthorizer:
102+
Type: Api
103+
Properties:
104+
RestApiId: !Ref MyApi
105+
Path: /users
106+
Method: put
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Globals:
2+
Api:
3+
OpenApiVersion: '3.0.1'
4+
Resources:
5+
MyApiWithCognitoAuth:
6+
Type: "AWS::Serverless::Api"
7+
Properties:
8+
StageName: Prod
9+
Auth:
10+
DefaultAuthorizer: MyCognitoAuth
11+
Authorizers:
12+
MyCognitoAuth:
13+
UserPoolArn: !GetAtt MyUserPool.Arn
14+
15+
MyApiWithLambdaTokenAuth:
16+
Type: "AWS::Serverless::Api"
17+
Properties:
18+
StageName: Prod
19+
Auth:
20+
DefaultAuthorizer: MyLambdaTokenAuth
21+
Authorizers:
22+
MyLambdaTokenAuth:
23+
FunctionArn: !GetAtt MyAuthFn.Arn
24+
25+
MyApiWithLambdaRequestAuth:
26+
Type: "AWS::Serverless::Api"
27+
Properties:
28+
StageName: Prod
29+
Auth:
30+
DefaultAuthorizer: MyLambdaRequestAuth
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://bucketname/thumbnails.zip
42+
Handler: index.handler
43+
Runtime: nodejs8.10
44+
MyFn:
45+
Type: AWS::Serverless::Function
46+
Properties:
47+
CodeUri: s3://bucketname/thumbnails.zip
48+
Handler: index.handler
49+
Runtime: nodejs8.10
50+
Events:
51+
Cognito:
52+
Type: Api
53+
Properties:
54+
RestApiId: !Ref MyApiWithCognitoAuth
55+
Method: get
56+
Path: /cognito
57+
LambdaToken:
58+
Type: Api
59+
Properties:
60+
RestApiId: !Ref MyApiWithLambdaTokenAuth
61+
Method: get
62+
Path: /lambda-token
63+
LambdaRequest:
64+
Type: Api
65+
Properties:
66+
RestApiId: !Ref MyApiWithLambdaRequestAuth
67+
Method: get
68+
Path: /lambda-request
69+
MyUserPool:
70+
Type: AWS::Cognito::UserPool
71+
Properties:
72+
UserPoolName: UserPoolName
73+
Policies:
74+
PasswordPolicy:
75+
MinimumLength: 8
76+
UsernameAttributes:
77+
- email
78+
Schema:
79+
- AttributeDataType: String
80+
Name: email
81+
Required: false
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Globals:
2+
Api:
3+
Name: "some api"
4+
CacheClusterEnabled: True
5+
CacheClusterSize: "1.6"
6+
Auth:
7+
DefaultAuthorizer: MyCognitoAuth
8+
Authorizers:
9+
MyCognitoAuth:
10+
UserPoolArn: !GetAtt MyUserPool.Arn
11+
Variables:
12+
SomeVar: Value
13+
14+
Resources:
15+
ImplicitApiFunction:
16+
Type: AWS::Serverless::Function
17+
Properties:
18+
CodeUri: s3://sam-demo-bucket/member_portal.zip
19+
Handler: index.gethtml
20+
Runtime: nodejs4.3
21+
Events:
22+
GetHtml:
23+
Type: Api
24+
Properties:
25+
Path: /
26+
Method: get
27+
28+
ExplicitApi:
29+
Type: AWS::Serverless::Api
30+
Properties:
31+
StageName: SomeStage
32+
DefinitionBody:
33+
openapi: 3.1.1
34+
info:
35+
version: '1.0'
36+
title: !Ref AWS::StackName
37+
paths:
38+
"/":
39+
get:
40+
x-amazon-apigateway-integration:
41+
httpMethod: POST
42+
type: aws_proxy
43+
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImplicitApiFunction.Arn}/invocations
44+
responses: {}
45+
46+
MyUserPool:
47+
Type: AWS::Cognito::UserPool
48+
Properties:
49+
UserPoolName: UserPoolName
50+
Policies:
51+
PasswordPolicy:
52+
MinimumLength: 8
53+
UsernameAttributes:
54+
- email
55+
Schema:
56+
- AttributeDataType: String
57+
Name: email
58+
Required: false
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Globals:
2+
Api:
3+
Name: "some api"
4+
CacheClusterEnabled: True
5+
CacheClusterSize: "1.6"
6+
Auth:
7+
DefaultAuthorizer: MyCognitoAuth
8+
Authorizers:
9+
MyCognitoAuth:
10+
UserPoolArn: !GetAtt MyUserPool.Arn
11+
Variables:
12+
SomeVar: Value
13+
14+
Resources:
15+
ImplicitApiFunction:
16+
Type: AWS::Serverless::Function
17+
Properties:
18+
CodeUri: s3://sam-demo-bucket/member_portal.zip
19+
Handler: index.gethtml
20+
Runtime: nodejs4.3
21+
Events:
22+
GetHtml:
23+
Type: Api
24+
Properties:
25+
Path: /
26+
Method: get
27+
28+
ExplicitApi:
29+
Type: AWS::Serverless::Api
30+
Properties:
31+
StageName: SomeStage
32+
DefinitionBody:
33+
openapi: 3.1.1
34+
swagger: 2.0
35+
info:
36+
version: '1.0'
37+
title: !Ref AWS::StackName
38+
paths:
39+
"/":
40+
get:
41+
x-amazon-apigateway-integration:
42+
httpMethod: POST
43+
type: aws_proxy
44+
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImplicitApiFunction.Arn}/invocations
45+
responses: {}
46+
47+
MyUserPool:
48+
Type: AWS::Cognito::UserPool
49+
Properties:
50+
UserPoolName: UserPoolName
51+
Policies:
52+
PasswordPolicy:
53+
MinimumLength: 8
54+
UsernameAttributes:
55+
- email
56+
Schema:
57+
- AttributeDataType: String
58+
Name: email
59+
Required: false

0 commit comments

Comments
 (0)