Skip to content

Commit 6ee36f6

Browse files
committed
Add integ test for Dual auth
1 parent 8fd1cdc commit 6ee36f6

5 files changed

+179
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"LogicalResourceId": "MyLambdaFunction",
4+
"ResourceType": "AWS::Lambda::Function"
5+
},
6+
{
7+
"LogicalResourceId": "MyLambdaFunctionUrl",
8+
"ResourceType": "AWS::Lambda::Url"
9+
},
10+
{
11+
"LogicalResourceId": "MyLambdaFunctionUrlPublicPermissions",
12+
"ResourceType": "AWS::Lambda::Permission"
13+
},
14+
{
15+
"LogicalResourceId": "MyLambdaFunctionURLInvokeAllowPublicAccess",
16+
"ResourceType": "AWS::Lambda::Permission"
17+
},
18+
{
19+
"LogicalResourceId": "MyLambdaFunctionRole",
20+
"ResourceType": "AWS::IAM::Role"
21+
}
22+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[
2+
{
3+
"LogicalResourceId": "MyLambdaFunction",
4+
"ResourceType": "AWS::Lambda::Function"
5+
},
6+
{
7+
"LogicalResourceId": "MyLambdaFunctionRole",
8+
"ResourceType": "AWS::IAM::Role"
9+
},
10+
{
11+
"LogicalResourceId": "MyLambdaFunctionVersion",
12+
"ResourceType": "AWS::Lambda::Version"
13+
},
14+
{
15+
"LogicalResourceId": "MyLambdaFunctionAliaslive",
16+
"ResourceType": "AWS::Lambda::Alias"
17+
},
18+
{
19+
"LogicalResourceId": "MyLambdaFunctionUrlPublicPermissions",
20+
"ResourceType": "AWS::Lambda::Permission"
21+
},
22+
{
23+
"LogicalResourceId": "MyLambdaFunctionURLInvokeAllowPublicAccess",
24+
"ResourceType": "AWS::Lambda::Permission"
25+
},
26+
{
27+
"LogicalResourceId": "MyLambdaFunctionUrl",
28+
"ResourceType": "AWS::Lambda::Url"
29+
}
30+
]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Resources:
2+
MyLambdaFunction:
3+
Type: AWS::Serverless::Function
4+
Properties:
5+
Handler: index.handler
6+
Runtime: nodejs18.x
7+
CodeUri: ${codeuri}
8+
MemorySize: 128
9+
FunctionUrlConfig:
10+
AuthType: NONE
11+
Cors:
12+
AllowOrigins:
13+
- https://foo.com
14+
AllowMethods:
15+
- POST
16+
AllowCredentials: true
17+
AllowHeaders:
18+
- x-Custom-Header
19+
ExposeHeaders:
20+
- x-amzn-header
21+
MaxAge: 10
22+
Outputs:
23+
FunctionUrl:
24+
Description: "URL of the Lambda function"
25+
Value: !GetAtt MyLambdaFunctionUrl.FunctionUrl
26+
Metadata:
27+
SamTransformTest: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Resources:
2+
MyLambdaFunction:
3+
Type: AWS::Serverless::Function
4+
Properties:
5+
Handler: index.handler
6+
Runtime: nodejs18.x
7+
CodeUri: ${codeuri}
8+
MemorySize: 128
9+
AutoPublishAlias: live
10+
FunctionUrlConfig:
11+
AuthType: NONE
12+
Cors:
13+
AllowOrigins:
14+
- https://foo.com
15+
AllowMethods:
16+
- POST
17+
AllowCredentials: true
18+
AllowHeaders:
19+
- x-Custom-Header
20+
ExposeHeaders:
21+
- x-amzn-header
22+
MaxAge: 10
23+
Outputs:
24+
FunctionUrl:
25+
Description: "URL of the Lambda function alias"
26+
Value: !GetAtt MyLambdaFunctionUrl.FunctionUrl
27+
Metadata:
28+
SamTransformTest: true

integration/single/test_basic_function.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,78 @@ def test_basic_function_with_url_config(self, file_name, qualifier):
130130
self.assertEqual(function_url_config["Cors"], cors_config)
131131
self._assert_invoke(lambda_client, function_name, qualifier, 200)
132132

133+
134+
@parameterized.expand(
135+
[
136+
("single/basic_function_with_function_url_dual_auth", None),
137+
("single/basic_function_with_function_url_with_autopuplishalias_dual_auth", "live"),
138+
]
139+
)
140+
@skipIf(current_region_does_not_support([LAMBDA_URL]), "Lambda Url is not supported in this testing region")
141+
def test_basic_function_with_url_dual_auth(self, file_name, qualifier):
142+
"""
143+
Creates a basic lambda function with Function Url with authtype: None
144+
Verifies that 2 AWS::Lambda::Permission resources are created:
145+
- lambda:InvokeFunctionUrl
146+
- lambda:InvokeFunction with InvokedViaFunctionUrl: True
147+
"""
148+
self.create_and_verify_stack(file_name)
149+
150+
# Get Lambda permissions
151+
lambda_permissions = self.get_stack_resources("AWS::Lambda::Permission")
152+
153+
# Verify we have exactly 2 permissions
154+
self.assertEqual(len(lambda_permissions), 2, "Expected exactly 2 Lambda permissions")
155+
156+
# Check for the expected permission logical IDs
157+
invoke_function_url_permission = None
158+
invoke_permission = None
159+
160+
for permission in lambda_permissions:
161+
logical_id = permission["LogicalResourceId"]
162+
if "MyLambdaFunctionUrlPublicPermissions" in logical_id:
163+
invoke_function_url_permission = permission
164+
elif "MyLambdaFunctionURLInvokeAllowPublicAccess" in logical_id:
165+
invoke_permission = permission
166+
167+
# Verify both permissions exist
168+
self.assertIsNotNone(invoke_function_url_permission, "Expected MyLambdaFunctionUrlPublicPermissions to exist")
169+
self.assertIsNotNone(invoke_permission, "Expected MyLambdaFunctionURLInvokeAllowPublicAccess to exist")
170+
171+
# Get the function name and URL
172+
function_name = self.get_physical_id_by_type("AWS::Lambda::Function")
173+
lambda_client = self.client_provider.lambda_client
174+
175+
176+
177+
# Get the function URL configuration to verify auth type
178+
function_url_config = (
179+
lambda_client.get_function_url_config(FunctionName=function_name, Qualifier=qualifier)
180+
if qualifier
181+
else lambda_client.get_function_url_config(FunctionName=function_name)
182+
)
183+
184+
# Verify the auth type is NONE
185+
self.assertEqual(function_url_config["AuthType"], "NONE", "Expected AuthType to be NONE")
186+
187+
# Get the template to check for InvokedViaFunctionUrl property
188+
cfn_client = self.client_provider.cfn_client
189+
template = cfn_client.get_template(StackName=self.stack_name)
190+
template_body = template["TemplateBody"]
191+
192+
# Check if the InvokePermission has InvokedViaFunctionUrl: True
193+
# This is a bit hacky but we don't have direct access to the resource properties
194+
# We're checking if the string representation of the template contains this property
195+
template_str = str(template_body)
196+
self.assertIn("InvokedViaFunctionUrl", template_str,
197+
"Expected InvokedViaFunctionUrl property in the template")
198+
199+
# Get the function URL from stack outputs
200+
function_url = self.get_stack_output("FunctionUrl")["OutputValue"]
201+
# Invoke the function URL and verify the response
202+
self._verify_get_request(function_url, self.FUNCTION_OUTPUT)
203+
204+
133205
@skipIf(current_region_does_not_support([CODE_DEPLOY]), "CodeDeploy is not supported in this testing region")
134206
def test_function_with_deployment_preference_alarms_intrinsic_if(self):
135207
self.create_and_verify_stack("single/function_with_deployment_preference_alarms_intrinsic_if")

0 commit comments

Comments
 (0)