Skip to content

Commit 7e276c8

Browse files
committed
test
1 parent b6e5912 commit 7e276c8

File tree

4 files changed

+67
-30
lines changed

4 files changed

+67
-30
lines changed

.cfnlintrc.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
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
47
- tests/translator/output/**/error_*.json # Fail by design
58
- tests/translator/output/**/api_http_paths_with_if_condition.json
69
- tests/translator/output/**/api_http_paths_with_if_condition_no_value_else_case.json

samtranslator/model/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ def validate_properties_and_return_model(self, cls: Type[RT]) -> RT:
345345
"""
346346
try:
347347
return cls.parse_obj(self._generate_resource_dict()["Properties"])
348-
except pydantic.error_wrappers.ValidationError as e:
348+
except pydantic.error_wrappers.ValidationError as e: # type: ignore
349349
error_properties: str = ""
350350
with suppress(KeyError):
351351
error_properties = ".".join(str(x) for x in e.errors()[0]["loc"])

samtranslator/model/sam_resources.py

+49-29
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@
132132
from .tags.resource_tagging import get_tag_list
133133

134134
_CONDITION_CHAR_LIMIT = 255
135-
FUNCTION_URL_PUBLIC_PERMISSION_ACTION = "lambda:InvokeFunctionUrl"
136-
FUNCTION_INVOKE_PERMISSION_ACTION = "lambda:InvokeFunction"
137135

138136

139137
class SamFunction(SamResourceMacro):
@@ -322,8 +320,13 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
322320
if self.FunctionUrlConfig:
323321
lambda_url = self._construct_function_url(lambda_function, lambda_alias, self.FunctionUrlConfig)
324322
resources.append(lambda_url)
325-
url_permissions = self._construct_url_permissions(lambda_function, lambda_alias, self.FunctionUrlConfig)
326-
resources.extend(url_permissions)
323+
url_permission = self._construct_url_permission(lambda_function, lambda_alias, self.FunctionUrlConfig)
324+
invoke_dual_auth_permission = self._construct_invoke_dual_auth_permission(
325+
lambda_function, lambda_alias, self.FunctionUrlConfig
326+
)
327+
if url_permission and invoke_dual_auth_permission:
328+
resources.append(url_permission)
329+
resources.append(invoke_dual_auth_permission)
327330

328331
self._validate_deployment_preference_and_add_update_policy(
329332
kwargs.get("deployment_preference_collection", None),
@@ -1198,11 +1201,11 @@ def _validate_cors_config_parameter(
11981201
"{} must be of type {}.".format(prop_name, str(prop_type).split("'")[1]),
11991202
)
12001203

1201-
def _construct_url_permissions(
1204+
def _construct_url_permission(
12021205
self, lambda_function: LambdaFunction, lambda_alias: Optional[LambdaAlias], function_url_config: Dict[str, Any]
1203-
) -> List[LambdaPermission]:
1206+
) -> Optional[LambdaPermission]:
12041207
"""
1205-
Construct the lambda permissions associated with the function url resource in a case
1208+
Construct the lambda permission associated with the function url resource in a case
12061209
for public access when AuthType is NONE
12071210
12081211
Parameters
@@ -1215,45 +1218,62 @@ def _construct_url_permissions(
12151218
12161219
Returns
12171220
-------
1218-
List[LambdaPermission]
1219-
The lambda permission appended to a function url resource with public access and the
1220-
Permission to invoke the function in general.
1221+
LambdaPermission
1222+
The lambda permission appended to a function url resource with public access
12211223
"""
12221224
auth_type = function_url_config.get("AuthType")
12231225

12241226
if auth_type not in ["NONE"] or is_intrinsic(function_url_config):
1225-
return []
1226-
1227-
url_public_permission_logical_id = f"{lambda_function.logical_id}UrlPublicPermissions"
1227+
return None
12281228

1229+
logical_id = f"{lambda_function.logical_id}UrlPublicPermissions"
12291230
lambda_permission_attributes = self.get_passthrough_resource_attributes()
1230-
1231-
lambda_url_public_permission = LambdaPermission(
1232-
logical_id=url_public_permission_logical_id, attributes=lambda_permission_attributes
1233-
)
1234-
lambda_url_public_permission.Action = FUNCTION_URL_PUBLIC_PERMISSION_ACTION
1235-
lambda_url_public_permission.Principal = "*"
1236-
lambda_url_public_permission.FunctionName = (
1231+
lambda_permission = LambdaPermission(logical_id=logical_id, attributes=lambda_permission_attributes)
1232+
lambda_permission.Action = "lambda:InvokeFunctionUrl"
1233+
lambda_permission.FunctionName = (
12371234
lambda_alias.get_runtime_attr("arn") if lambda_alias else lambda_function.get_runtime_attr("name")
12381235
)
1239-
lambda_url_public_permission.FunctionUrlAuthType = auth_type
1236+
lambda_permission.Principal = "*"
1237+
lambda_permission.FunctionUrlAuthType = auth_type
1238+
return lambda_permission
12401239

1241-
url_invoke_permission_logical_id = f"{lambda_function.logical_id}URLInvokeAllowPublicAccess"
1240+
def _construct_invoke_dual_auth_permission(
1241+
self, lambda_function: LambdaFunction, lambda_alias: Optional[LambdaAlias], function_url_config: Dict[str, Any]
1242+
) -> Optional[LambdaPermission]:
1243+
"""
1244+
Construct the lambda permission associated with the function invoke resource in a case
1245+
for public access when AuthType is NONE
12421246
1243-
lambda_permission_attributes = self.get_passthrough_resource_attributes()
1247+
Parameters
1248+
----------
1249+
lambda_function : LambdaUrl
1250+
Lambda Function resource
12441251
1245-
lambda_invoke_permission = LambdaPermission(
1246-
logical_id=url_invoke_permission_logical_id, attributes=lambda_permission_attributes
1247-
)
1248-
lambda_invoke_permission.Action = FUNCTION_INVOKE_PERMISSION_ACTION
1252+
lambda_alias : LambdaAlias
1253+
Lambda Alias resource
1254+
1255+
Returns
1256+
-------
1257+
LambdaPermission
1258+
The lambda permission appended to a function that allow function invoke only from Function URL
1259+
"""
1260+
# create lambda:InvokeFunction with InvokedViaFunctionUrl=True
1261+
auth_type = function_url_config.get("AuthType")
1262+
1263+
if auth_type not in ["NONE"] or is_intrinsic(function_url_config):
1264+
return None
1265+
1266+
logical_id = f"{lambda_function.logical_id}URLInvokeAllowPublicAccess"
1267+
lambda_permission_attributes = self.get_passthrough_resource_attributes()
1268+
lambda_invoke_permission = LambdaPermission(logical_id=logical_id, attributes=lambda_permission_attributes)
1269+
lambda_invoke_permission.Action = "lambda:InvokeFunction"
12491270
lambda_invoke_permission.Principal = "*"
12501271
lambda_invoke_permission.FunctionName = (
12511272
lambda_alias.get_runtime_attr("arn") if lambda_alias else lambda_function.get_runtime_attr("name")
12521273
)
1253-
12541274
lambda_invoke_permission.InvokedViaFunctionUrl = True
12551275

1256-
return [lambda_url_public_permission, lambda_invoke_permission]
1276+
return lambda_invoke_permission
12571277

12581278

12591279
class SamApi(SamResourceMacro):

tests/model/test_sam_resources.py

+14
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,20 @@ def test_with_valid_function_url_config_with_lambda_permission(self):
593593
if permission.Action == "lambda:InvokeFunction":
594594
self.assertEqual(permission.InvokedViaFunctionUrl, True)
595595

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)
609+
596610
@patch("boto3.session.Session.region_name", "ap-southeast-1")
597611
def test_with_invalid_function_url_config_with_authorization_type_value_as_None(self):
598612
function = SamFunction("foo")

0 commit comments

Comments
 (0)