diff --git a/moto/iam/models.py b/moto/iam/models.py index 4a115999c..81c7d09ca 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -733,6 +733,10 @@ class IAMBackend(BaseBackend): policy = ManagedPolicy( policy_name, description=description, document=policy_document, path=path ) + if policy.arn in self.managed_policies: + raise EntityAlreadyExists( + f"A policy called {policy_name} already exists. Duplicate names are not allowed." + ) self.managed_policies[policy.arn] = policy return policy diff --git a/tests/test_core/test_auth.py b/tests/test_core/test_auth.py index 7dc632188..c5e043ae5 100644 --- a/tests/test_core/test_auth.py +++ b/tests/test_core/test_auth.py @@ -402,10 +402,10 @@ def test_s3_access_denied_with_denying_attached_group_policy(): "Statement": [{"Effect": "Deny", "Action": "s3:List*", "Resource": "*"}], } access_key = create_user_with_access_key_and_attached_policy( - user_name, attached_policy_document + user_name, attached_policy_document, policy_name="policy1" ) create_group_with_attached_policy_and_add_user( - user_name, group_attached_policy_document + user_name, group_attached_policy_document, policy_name="policy2" ) client = boto3.client( "s3", @@ -476,10 +476,16 @@ def test_access_denied_with_many_irrelevant_policies(): "Statement": [{"Effect": "Deny", "Action": "lambda:*", "Resource": "*"}], } access_key = create_user_with_access_key_and_multiple_policies( - user_name, inline_policy_document, attached_policy_document + user_name, + inline_policy_document, + attached_policy_document, + attached_policy_name="policy1", ) create_group_with_multiple_policies_and_add_user( - user_name, group_inline_policy_document, group_attached_policy_document + user_name, + group_inline_policy_document, + group_attached_policy_document, + attached_policy_name="policy2", ) client = boto3.client( "ec2", diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index c4fcda317..9a34bbf6a 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -400,6 +400,21 @@ def test_create_policy(): ) +@mock_iam +def test_create_policy_already_exists(): + conn = boto3.client("iam", region_name="us-east-1") + response = conn.create_policy( + PolicyName="TestCreatePolicy", PolicyDocument=MOCK_POLICY + ) + with assert_raises(conn.exceptions.EntityAlreadyExistsException) as ex: + response = conn.create_policy( + PolicyName="TestCreatePolicy", PolicyDocument=MOCK_POLICY + ) + ex.exception.response["Error"]["Code"].should.equal("EntityAlreadyExists") + ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(409) + ex.exception.response["Error"]["Message"].should.contain("TestCreatePolicy") + + @mock_iam def test_delete_policy(): conn = boto3.client("iam", region_name="us-east-1")