From a668349a70ffce571c74c77074e6270f3cb59dd7 Mon Sep 17 00:00:00 2001 From: ljakimczuk <39192420+ljakimczuk@users.noreply.github.com> Date: Thu, 1 Oct 2020 11:24:03 +0200 Subject: [PATCH] Add `set_default_policy_version` to the IAM backend (#3347) * Adding set_default_policy_version * Adding tests and reformatting * Reformatting tests --- moto/iam/models.py | 26 ++++++++++++++++++- moto/iam/responses.py | 14 ++++++++++ tests/test_iam/test_iam.py | 53 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/moto/iam/models.py b/moto/iam/models.py index 3e7b638b2..6397fd099 100755 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -125,9 +125,10 @@ class Policy(CloudFormationModel): def update_default_version(self, new_default_version_id): for version in self.versions: + if version.version_id == new_default_version_id: + version.is_default = True if version.version_id == self.default_version_id: version.is_default = False - break self.default_version_id = new_default_version_id @property @@ -1544,6 +1545,29 @@ class IAMBackend(BaseBackend): return self._filter_attached_policies(policies, marker, max_items, path_prefix) + def set_default_policy_version(self, policy_arn, version_id): + import re + + if re.match("v[1-9][0-9]*(\.[A-Za-z0-9-]*)?", version_id) is None: + raise ValidationError( + "Value '{0}' at 'versionId' failed to satisfy constraint: Member must satisfy regular expression pattern: v[1-9][0-9]*(\.[A-Za-z0-9-]*)?".format( + version_id + ) + ) + + policy = self.get_policy(policy_arn) + + for version in policy.versions: + if version.version_id == version_id: + policy.update_default_version(version_id) + return True + + raise NoSuchEntity( + "Policy {0} version {1} does not exist or is not attachable.".format( + policy_arn, version_id + ) + ) + def _filter_attached_policies(self, policies, marker, max_items, path_prefix): if path_prefix: policies = [p for p in policies if p.path.startswith(path_prefix)] diff --git a/moto/iam/responses.py b/moto/iam/responses.py index 88ab9aef1..eed610f13 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -175,6 +175,13 @@ class IamResponse(BaseResponse): roles=entity_roles, users=entity_users, groups=entity_groups ) + def set_default_policy_version(self): + policy_arn = self._get_param("PolicyArn") + version_id = self._get_param("VersionId") + iam_backend.set_default_policy_version(policy_arn, version_id) + template = self.response_template(SET_DEFAULT_POLICY_VERSION_TEMPLATE) + return template.render() + def create_role(self): role_name = self._get_param("RoleName") path = self._get_param("Path") @@ -1010,6 +1017,13 @@ LIST_ENTITIES_FOR_POLICY_TEMPLATE = """ """ +SET_DEFAULT_POLICY_VERSION_TEMPLATE = """ + + 35f241af-3ebc-11e4-9d0d-6f969EXAMPLE + +""" + + ATTACH_ROLE_POLICY_TEMPLATE = """ 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index e9d5e8a4d..9cf7decb6 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -549,6 +549,59 @@ def test_set_default_policy_version(): versions.get("Versions")[2].get("Document").should.equal(json.loads(MOCK_POLICY_3)) versions.get("Versions")[2].get("IsDefaultVersion").should.be.ok + conn.set_default_policy_version( + PolicyArn="arn:aws:iam::{}:policy/TestSetDefaultPolicyVersion".format( + ACCOUNT_ID + ), + VersionId="v1", + ) + versions = conn.list_policy_versions( + PolicyArn="arn:aws:iam::{}:policy/TestSetDefaultPolicyVersion".format( + ACCOUNT_ID + ) + ) + versions.get("Versions")[0].get("Document").should.equal(json.loads(MOCK_POLICY)) + versions.get("Versions")[0].get("IsDefaultVersion").should.be.ok + versions.get("Versions")[1].get("Document").should.equal(json.loads(MOCK_POLICY_2)) + versions.get("Versions")[1].get("IsDefaultVersion").shouldnt.be.ok + versions.get("Versions")[2].get("Document").should.equal(json.loads(MOCK_POLICY_3)) + versions.get("Versions")[2].get("IsDefaultVersion").shouldnt.be.ok + + # Set default version for non-existing policy + conn.set_default_policy_version.when.called_with( + PolicyArn="arn:aws:iam::{}:policy/TestNonExistingPolicy".format(ACCOUNT_ID), + VersionId="v1", + ).should.throw( + ClientError, + "Policy arn:aws:iam::{}:policy/TestNonExistingPolicy not found".format( + ACCOUNT_ID + ), + ) + + # Set default version for incorrect version + conn.set_default_policy_version.when.called_with( + PolicyArn="arn:aws:iam::{}:policy/TestSetDefaultPolicyVersion".format( + ACCOUNT_ID + ), + VersionId="wrong_version_id", + ).should.throw( + ClientError, + "Value 'wrong_version_id' at 'versionId' failed to satisfy constraint: Member must satisfy regular expression pattern: v[1-9][0-9]*(\.[A-Za-z0-9-]*)?", + ) + + # Set default version for non-existing version + conn.set_default_policy_version.when.called_with( + PolicyArn="arn:aws:iam::{}:policy/TestSetDefaultPolicyVersion".format( + ACCOUNT_ID + ), + VersionId="v4", + ).should.throw( + ClientError, + "Policy arn:aws:iam::{}:policy/TestSetDefaultPolicyVersion version v4 does not exist or is not attachable.".format( + ACCOUNT_ID + ), + ) + @mock_iam def test_get_policy():