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():