Skip to content

Commit 79cf186

Browse files
authored
Revert "feat: refactor Function URL permissions (#3735)" (#3761)
1 parent f8c3688 commit 79cf186

21 files changed

+8
-387
lines changed

.cfnlintrc.yaml

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
templates:
22
- tests/translator/output/**/*.json
33
ignore_templates:
4-
- tests/translator/output/**/function_with_function_url_config.json
5-
- tests/translator/output/**/function_with_function_url_config_and_autopublishalias.json
6-
- tests/translator/output/**/function_with_function_url_config_without_cors_config.json
74
- tests/translator/output/**/error_*.json # Fail by design
85
- tests/translator/output/**/api_http_paths_with_if_condition.json
96
- tests/translator/output/**/api_http_paths_with_if_condition_no_value_else_case.json

integration/resources/expected/single/basic_function_with_function_url_dual_auth.json

-22
This file was deleted.

integration/resources/expected/single/basic_function_with_function_url_with_autopuplishalias_dual_auth.json

-30
This file was deleted.

integration/resources/templates/single/basic_function_with_function_url_dual_auth.yaml

-27
This file was deleted.

integration/resources/templates/single/basic_function_with_function_url_with_autopuplishalias_dual_auth.yaml

-28
This file was deleted.

integration/single/test_basic_function.py

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

samtranslator/model/lambda_.py

-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ class LambdaPermission(Resource):
139139
"SourceArn": GeneratedProperty(),
140140
"EventSourceToken": GeneratedProperty(),
141141
"FunctionUrlAuthType": GeneratedProperty(),
142-
"InvokedViaFunctionUrl": GeneratedProperty(),
143142
}
144143

145144

samtranslator/model/sam_resources.py

+3-51
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,8 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
321321
lambda_url = self._construct_function_url(lambda_function, lambda_alias, self.FunctionUrlConfig)
322322
resources.append(lambda_url)
323323
url_permission = self._construct_url_permission(lambda_function, lambda_alias, self.FunctionUrlConfig)
324-
invoke_dual_auth_permission = self._construct_invoke_permission(
325-
lambda_function, lambda_alias, self.FunctionUrlConfig
326-
)
327-
if url_permission and invoke_dual_auth_permission:
324+
if url_permission:
328325
resources.append(url_permission)
329-
resources.append(invoke_dual_auth_permission)
330326

331327
self._validate_deployment_preference_and_add_update_policy(
332328
kwargs.get("deployment_preference_collection"),
@@ -336,6 +332,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
336332
self.get_passthrough_resource_attributes(),
337333
feature_toggle,
338334
)
335+
339336
event_invoke_policies: List[Dict[str, Any]] = []
340337
if self.EventInvokeConfig:
341338
function_name = lambda_function.logical_id
@@ -1228,13 +1225,9 @@ def _construct_url_permission(
12281225
lambda_function : LambdaUrl
12291226
Lambda Function resource
12301227
1231-
lambda_alias : LambdaAlias
1228+
llambda_alias : LambdaAlias
12321229
Lambda Alias resource
12331230
1234-
1235-
function_url_config: Dict
1236-
Function url config used to create FURL
1237-
12381231
Returns
12391232
-------
12401233
LambdaPermission
@@ -1256,47 +1249,6 @@ def _construct_url_permission(
12561249
lambda_permission.FunctionUrlAuthType = auth_type
12571250
return lambda_permission
12581251

1259-
def _construct_invoke_permission(
1260-
self, lambda_function: LambdaFunction, lambda_alias: Optional[LambdaAlias], function_url_config: Dict[str, Any]
1261-
) -> Optional[LambdaPermission]:
1262-
"""
1263-
Construct the lambda permission associated with the function invoke resource in a case
1264-
for public access when AuthType is NONE
1265-
1266-
Parameters
1267-
----------
1268-
lambda_function : LambdaUrl
1269-
Lambda Function resource
1270-
1271-
lambda_alias : LambdaAlias
1272-
Lambda Alias resource
1273-
1274-
function_url_config: Dict
1275-
Function url config used to create FURL
1276-
1277-
Returns
1278-
-------
1279-
LambdaPermission
1280-
The lambda permission appended to a function that allow function invoke only from Function URL
1281-
"""
1282-
# create lambda:InvokeFunction with InvokedViaFunctionUrl=True
1283-
auth_type = function_url_config.get("AuthType")
1284-
1285-
if auth_type not in ["NONE"] or is_intrinsic(function_url_config):
1286-
return None
1287-
1288-
logical_id = f"{lambda_function.logical_id}URLInvokeAllowPublicAccess"
1289-
lambda_permission_attributes = self.get_passthrough_resource_attributes()
1290-
lambda_invoke_permission = LambdaPermission(logical_id=logical_id, attributes=lambda_permission_attributes)
1291-
lambda_invoke_permission.Action = "lambda:InvokeFunction"
1292-
lambda_invoke_permission.Principal = "*"
1293-
lambda_invoke_permission.FunctionName = (
1294-
lambda_alias.get_runtime_attr("arn") if lambda_alias else lambda_function.get_runtime_attr("name")
1295-
)
1296-
lambda_invoke_permission.InvokedViaFunctionUrl = True
1297-
1298-
return lambda_invoke_permission
1299-
13001252

13011253
class SamApi(SamResourceMacro):
13021254
"""SAM rest API macro."""

tests/model/test_sam_resources.py

+5-23
Original file line numberDiff line numberDiff line change
@@ -583,29 +583,11 @@ def test_with_valid_function_url_config_with_lambda_permission(self):
583583

584584
cfnResources = function.to_cloudformation(**self.kwargs)
585585
generatedUrlList = [x for x in cfnResources if isinstance(x, LambdaPermission)]
586-
self.assertEqual(generatedUrlList.__len__(), 2)
587-
for permission in generatedUrlList:
588-
self.assertEqual(permission.FunctionName, {"Ref": "foo"})
589-
self.assertEqual(permission.Principal, "*")
590-
self.assertTrue(permission.Action in ["lambda:InvokeFunctionUrl", "lambda:InvokeFunction"])
591-
if permission.Action == "lambda:InvokeFunctionUrl":
592-
self.assertEqual(permission.FunctionUrlAuthType, "NONE")
593-
if permission.Action == "lambda:InvokeFunction":
594-
self.assertEqual(permission.InvokedViaFunctionUrl, True)
595-
596-
@patch("boto3.session.Session.region_name", "ap-southeast-1")
597-
def test_with_aws_iam_function_url_config_with_lambda_permission(self):
598-
function = SamFunction("foo")
599-
function.CodeUri = "s3://foobar/foo.zip"
600-
function.Runtime = "foo"
601-
function.Handler = "bar"
602-
# When create FURL with AWS_IAM
603-
function.FunctionUrlConfig = {"AuthType": "AWS_IAM"}
604-
605-
cfnResources = function.to_cloudformation(**self.kwargs)
606-
generatedUrlList = [x for x in cfnResources if isinstance(x, LambdaPermission)]
607-
# Then no permisssion should be auto created
608-
self.assertEqual(generatedUrlList.__len__(), 0)
586+
self.assertEqual(generatedUrlList.__len__(), 1)
587+
self.assertEqual(generatedUrlList[0].Action, "lambda:InvokeFunctionUrl")
588+
self.assertEqual(generatedUrlList[0].FunctionName, {"Ref": "foo"})
589+
self.assertEqual(generatedUrlList[0].Principal, "*")
590+
self.assertEqual(generatedUrlList[0].FunctionUrlAuthType, "NONE")
609591

610592
@patch("boto3.session.Session.region_name", "ap-southeast-1")
611593
def test_with_invalid_function_url_config_with_authorization_type_value_as_None(self):

tests/translator/output/aws-cn/function_with_function_url_config.json

-11
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@
5858
},
5959
"Type": "AWS::IAM::Role"
6060
},
61-
"MyFunctionURLInvokeAllowPublicAccess": {
62-
"Properties": {
63-
"Action": "lambda:InvokeFunction",
64-
"FunctionName": {
65-
"Ref": "MyFunction"
66-
},
67-
"InvokedViaFunctionUrl": true,
68-
"Principal": "*"
69-
},
70-
"Type": "AWS::Lambda::Permission"
71-
},
7261
"MyFunctionUrl": {
7362
"Properties": {
7463
"AuthType": "NONE",

tests/translator/output/aws-cn/function_with_function_url_config_and_autopublishalias.json

-11
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,6 @@
7373
},
7474
"Type": "AWS::IAM::Role"
7575
},
76-
"MyFunctionURLInvokeAllowPublicAccess": {
77-
"Properties": {
78-
"Action": "lambda:InvokeFunction",
79-
"FunctionName": {
80-
"Ref": "MyFunctionAliaslive"
81-
},
82-
"InvokedViaFunctionUrl": true,
83-
"Principal": "*"
84-
},
85-
"Type": "AWS::Lambda::Permission"
86-
},
8776
"MyFunctionUrl": {
8877
"Properties": {
8978
"AuthType": "NONE",

tests/translator/output/aws-cn/function_with_function_url_config_conditions.json

-12
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,6 @@
6868
},
6969
"Type": "AWS::IAM::Role"
7070
},
71-
"MyFunctionURLInvokeAllowPublicAccess": {
72-
"Condition": "MyCondition",
73-
"Properties": {
74-
"Action": "lambda:InvokeFunction",
75-
"FunctionName": {
76-
"Ref": "MyFunction"
77-
},
78-
"InvokedViaFunctionUrl": true,
79-
"Principal": "*"
80-
},
81-
"Type": "AWS::Lambda::Permission"
82-
},
8371
"MyFunctionUrl": {
8472
"Condition": "MyCondition",
8573
"Properties": {

tests/translator/output/aws-cn/function_with_function_url_config_without_cors_config.json

-11
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@
5858
},
5959
"Type": "AWS::IAM::Role"
6060
},
61-
"MyFunctionURLInvokeAllowPublicAccess": {
62-
"Properties": {
63-
"Action": "lambda:InvokeFunction",
64-
"FunctionName": {
65-
"Ref": "MyFunction"
66-
},
67-
"InvokedViaFunctionUrl": true,
68-
"Principal": "*"
69-
},
70-
"Type": "AWS::Lambda::Permission"
71-
},
7261
"MyFunctionUrl": {
7362
"Properties": {
7463
"AuthType": "NONE",

0 commit comments

Comments
 (0)