From 009d0191f9591c4d4b44c3b94f54bb69bb3c05b2 Mon Sep 17 00:00:00 2001 From: rafcio19 Date: Tue, 19 Mar 2024 22:49:46 +0100 Subject: [PATCH] Lambda: throw error on empty resource policy (#7491) --- moto/awslambda/exceptions.py | 2 +- moto/awslambda/models.py | 4 +- moto/awslambda/policy.py | 3 ++ tests/test_awslambda/test_lambda_policy.py | 47 +++++++++++++++++++--- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/moto/awslambda/exceptions.py b/moto/awslambda/exceptions.py index 85c91ecf6..fef642838 100644 --- a/moto/awslambda/exceptions.py +++ b/moto/awslambda/exceptions.py @@ -64,7 +64,7 @@ class UnknownFunctionException(LambdaClientError): super().__init__("ResourceNotFoundException", f"Function not found: {arn}") -class FunctionUrlConfigNotFound(LambdaClientError): +class GenericResourcNotFound(LambdaClientError): code = 404 def __init__(self) -> None: diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py index 46ac998f4..5df47ebd5 100644 --- a/moto/awslambda/models.py +++ b/moto/awslambda/models.py @@ -45,7 +45,7 @@ from moto.utilities.utils import load_resource_as_bytes from .exceptions import ( ConflictException, CrossAccountNotAllowed, - FunctionUrlConfigNotFound, + GenericResourcNotFound, InvalidParameterValueException, InvalidRoleFormat, UnknownAliasException, @@ -1216,7 +1216,7 @@ class LambdaFunction(CloudFormationModel, DockerModel): def get_url_config(self) -> "FunctionUrlConfig": if not self.url_config: - raise FunctionUrlConfigNotFound() + raise GenericResourcNotFound() return self.url_config def update_url_config(self, config: Dict[str, Any]) -> "FunctionUrlConfig": diff --git a/moto/awslambda/policy.py b/moto/awslambda/policy.py index 20f56fedb..6facc06ac 100644 --- a/moto/awslambda/policy.py +++ b/moto/awslambda/policy.py @@ -2,6 +2,7 @@ import json from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, TypeVar from moto.awslambda.exceptions import ( + GenericResourcNotFound, PreconditionFailedException, UnknownPolicyException, ) @@ -26,6 +27,8 @@ class Policy: return json.dumps(p) def get_policy(self) -> Dict[str, Any]: + if not self.statements: + raise GenericResourcNotFound() return { "Policy": { "Version": "2012-10-17", diff --git a/tests/test_awslambda/test_lambda_policy.py b/tests/test_awslambda/test_lambda_policy.py index 524f28254..8f477fcb5 100644 --- a/tests/test_awslambda/test_lambda_policy.py +++ b/tests/test_awslambda/test_lambda_policy.py @@ -230,9 +230,13 @@ def test_remove_function_permission(key): remove = conn.remove_permission(FunctionName=name_or_arn, StatementId="1") assert remove["ResponseMetadata"]["HTTPStatusCode"] == 204 - policy = conn.get_policy(FunctionName=name_or_arn)["Policy"] - policy = json.loads(policy) - assert policy["Statement"] == [] + + with pytest.raises(ClientError) as exc: + conn.get_policy(FunctionName=name_or_arn)["Policy"] + + err = exc.value.response["Error"] + assert err["Code"] == "ResourceNotFoundException" + assert err["Message"] == "The resource you requested does not exist." @pytest.mark.parametrize("key", ["FunctionName", "FunctionArn"]) @@ -275,9 +279,12 @@ def test_remove_function_permission__with_qualifier(key): FunctionName=name_or_arn, StatementId="1", Qualifier="2" ) assert remove["ResponseMetadata"]["HTTPStatusCode"] == 204 - policy = conn.get_policy(FunctionName=name_or_arn, Qualifier="2")["Policy"] - policy = json.loads(policy) - assert policy["Statement"] == [] + with pytest.raises(ClientError) as exc: + conn.get_policy(FunctionName=name_or_arn, Qualifier="2") + + err = exc.value.response["Error"] + assert err["Code"] == "ResourceNotFoundException" + assert err["Message"] == "The resource you requested does not exist." @mock_aws @@ -292,3 +299,31 @@ def test_get_unknown_policy(): err["Message"] == "Function not found: arn:aws:lambda:us-west-2:123456789012:function:unknown" ) + + +@mock_aws +def test_policy_error_if_blank_resource_policy(): + # Setup + conn = boto3.client("lambda", _lambda_region) + zip_content = get_test_zip_file1() + function_name = str(uuid4())[0:6] + conn.create_function( + FunctionName=function_name, + Runtime=PYTHON_VERSION, + Role=(get_role_name()), + Handler="lambda_function.handler", + Code={"ZipFile": zip_content}, + Description="test lambda function", + Timeout=3, + MemorySize=128, + Publish=True, + ) + + # Execute + with pytest.raises(ClientError) as exc: + conn.get_policy(FunctionName=function_name) + + # Verify + err = exc.value.response["Error"] + assert err["Code"] == "ResourceNotFoundException" + assert err["Message"] == "The resource you requested does not exist."