Merge pull request #2268 from acsbendi/policy-version-fixes
IAM policy version fixes
This commit is contained in:
commit
3bafc89b40
@ -26,6 +26,14 @@ class IAMReportNotPresentException(RESTError):
|
|||||||
"ReportNotPresent", message)
|
"ReportNotPresent", message)
|
||||||
|
|
||||||
|
|
||||||
|
class IAMLimitExceededException(RESTError):
|
||||||
|
code = 400
|
||||||
|
|
||||||
|
def __init__(self, message):
|
||||||
|
super(IAMLimitExceededException, self).__init__(
|
||||||
|
"LimitExceeded", message)
|
||||||
|
|
||||||
|
|
||||||
class MalformedCertificate(RESTError):
|
class MalformedCertificate(RESTError):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ from moto.core.utils import iso_8601_datetime_without_milliseconds, iso_8601_dat
|
|||||||
from moto.iam.policy_validation import IAMPolicyDocumentValidator
|
from moto.iam.policy_validation import IAMPolicyDocumentValidator
|
||||||
|
|
||||||
from .aws_managed_policies import aws_managed_policies_data
|
from .aws_managed_policies import aws_managed_policies_data
|
||||||
from .exceptions import IAMNotFoundException, IAMConflictException, IAMReportNotPresentException, MalformedCertificate, \
|
from .exceptions import IAMNotFoundException, IAMConflictException, IAMReportNotPresentException, IAMLimitExceededException, \
|
||||||
DuplicateTags, TagKeyTooBig, InvalidTagCharacters, TooManyTags, TagValueTooBig
|
MalformedCertificate, DuplicateTags, TagKeyTooBig, InvalidTagCharacters, TooManyTags, TagValueTooBig
|
||||||
from .utils import random_access_key, random_alphanumeric, random_resource_id, random_policy_id
|
from .utils import random_access_key, random_alphanumeric, random_resource_id, random_policy_id
|
||||||
|
|
||||||
ACCOUNT_ID = 123456789012
|
ACCOUNT_ID = 123456789012
|
||||||
@ -67,6 +67,13 @@ class Policy(BaseModel):
|
|||||||
self.create_date = create_date if create_date is not None else datetime.utcnow()
|
self.create_date = create_date if create_date is not None else datetime.utcnow()
|
||||||
self.update_date = update_date if update_date is not None else datetime.utcnow()
|
self.update_date = update_date if update_date is not None else datetime.utcnow()
|
||||||
|
|
||||||
|
def update_default_version(self, new_default_version_id):
|
||||||
|
for version in self.versions:
|
||||||
|
if version.version_id == self.default_version_id:
|
||||||
|
version.is_default = False
|
||||||
|
break
|
||||||
|
self.default_version_id = new_default_version_id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def created_iso_8601(self):
|
def created_iso_8601(self):
|
||||||
return iso_8601_datetime_with_milliseconds(self.create_date)
|
return iso_8601_datetime_with_milliseconds(self.create_date)
|
||||||
@ -770,13 +777,15 @@ class IAMBackend(BaseBackend):
|
|||||||
policy = self.get_policy(policy_arn)
|
policy = self.get_policy(policy_arn)
|
||||||
if not policy:
|
if not policy:
|
||||||
raise IAMNotFoundException("Policy not found")
|
raise IAMNotFoundException("Policy not found")
|
||||||
|
if len(policy.versions) >= 5:
|
||||||
|
raise IAMLimitExceededException("A managed policy can have up to 5 versions. Before you create a new version, you must delete an existing version.")
|
||||||
|
set_as_default = (set_as_default == "true") # convert it to python bool
|
||||||
version = PolicyVersion(policy_arn, policy_document, set_as_default)
|
version = PolicyVersion(policy_arn, policy_document, set_as_default)
|
||||||
policy.versions.append(version)
|
policy.versions.append(version)
|
||||||
version.version_id = 'v{0}'.format(policy.next_version_num)
|
version.version_id = 'v{0}'.format(policy.next_version_num)
|
||||||
policy.next_version_num += 1
|
policy.next_version_num += 1
|
||||||
if set_as_default:
|
if set_as_default:
|
||||||
policy.default_version_id = version.version_id
|
policy.update_default_version(version.version_id)
|
||||||
return version
|
return version
|
||||||
|
|
||||||
def get_policy_version(self, policy_arn, version_id):
|
def get_policy_version(self, policy_arn, version_id):
|
||||||
@ -799,8 +808,8 @@ class IAMBackend(BaseBackend):
|
|||||||
if not policy:
|
if not policy:
|
||||||
raise IAMNotFoundException("Policy not found")
|
raise IAMNotFoundException("Policy not found")
|
||||||
if version_id == policy.default_version_id:
|
if version_id == policy.default_version_id:
|
||||||
raise IAMConflictException(
|
raise IAMConflictException(code="DeleteConflict",
|
||||||
"Cannot delete the default version of a policy")
|
message="Cannot delete the default version of a policy.")
|
||||||
for i, v in enumerate(policy.versions):
|
for i, v in enumerate(policy.versions):
|
||||||
if v.version_id == version_id:
|
if v.version_id == version_id:
|
||||||
del policy.versions[i]
|
del policy.versions[i]
|
||||||
|
@ -1144,7 +1144,7 @@ CREATE_POLICY_VERSION_TEMPLATE = """<CreatePolicyVersionResponse xmlns="https://
|
|||||||
<PolicyVersion>
|
<PolicyVersion>
|
||||||
<Document>{{ policy_version.document }}</Document>
|
<Document>{{ policy_version.document }}</Document>
|
||||||
<VersionId>{{ policy_version.version_id }}</VersionId>
|
<VersionId>{{ policy_version.version_id }}</VersionId>
|
||||||
<IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
|
<IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
|
||||||
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
||||||
</PolicyVersion>
|
</PolicyVersion>
|
||||||
</CreatePolicyVersionResult>
|
</CreatePolicyVersionResult>
|
||||||
@ -1158,7 +1158,7 @@ GET_POLICY_VERSION_TEMPLATE = """<GetPolicyVersionResponse xmlns="https://iam.am
|
|||||||
<PolicyVersion>
|
<PolicyVersion>
|
||||||
<Document>{{ policy_version.document }}</Document>
|
<Document>{{ policy_version.document }}</Document>
|
||||||
<VersionId>{{ policy_version.version_id }}</VersionId>
|
<VersionId>{{ policy_version.version_id }}</VersionId>
|
||||||
<IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
|
<IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
|
||||||
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
||||||
</PolicyVersion>
|
</PolicyVersion>
|
||||||
</GetPolicyVersionResult>
|
</GetPolicyVersionResult>
|
||||||
@ -1175,7 +1175,7 @@ LIST_POLICY_VERSIONS_TEMPLATE = """<ListPolicyVersionsResponse xmlns="https://ia
|
|||||||
<member>
|
<member>
|
||||||
<Document>{{ policy_version.document }}</Document>
|
<Document>{{ policy_version.document }}</Document>
|
||||||
<VersionId>{{ policy_version.version_id }}</VersionId>
|
<VersionId>{{ policy_version.version_id }}</VersionId>
|
||||||
<IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
|
<IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
|
||||||
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
||||||
</member>
|
</member>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -1787,7 +1787,7 @@ GET_ACCOUNT_AUTHORIZATION_DETAILS_TEMPLATE = """<GetAccountAuthorizationDetailsR
|
|||||||
{% for policy_version in policy.versions %}
|
{% for policy_version in policy.versions %}
|
||||||
<member>
|
<member>
|
||||||
<Document>{{ policy_version.document }}</Document>
|
<Document>{{ policy_version.document }}</Document>
|
||||||
<IsDefaultVersion>{{ policy_version.is_default }}</IsDefaultVersion>
|
<IsDefaultVersion>{{ policy_version.is_default | lower }}</IsDefaultVersion>
|
||||||
<VersionId>{{ policy_version.version_id }}</VersionId>
|
<VersionId>{{ policy_version.version_id }}</VersionId>
|
||||||
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ policy_version.created_iso_8601 }}</CreateDate>
|
||||||
</member>
|
</member>
|
||||||
|
@ -345,6 +345,7 @@ def test_create_policy_versions():
|
|||||||
SetAsDefault=True)
|
SetAsDefault=True)
|
||||||
version.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
|
version.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
|
||||||
version.get('PolicyVersion').get('VersionId').should.equal("v2")
|
version.get('PolicyVersion').get('VersionId').should.equal("v2")
|
||||||
|
version.get('PolicyVersion').get('IsDefaultVersion').should.be.ok
|
||||||
conn.delete_policy_version(
|
conn.delete_policy_version(
|
||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
||||||
VersionId="v1")
|
VersionId="v1")
|
||||||
@ -352,6 +353,47 @@ def test_create_policy_versions():
|
|||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
||||||
PolicyDocument=MOCK_POLICY)
|
PolicyDocument=MOCK_POLICY)
|
||||||
version.get('PolicyVersion').get('VersionId').should.equal("v3")
|
version.get('PolicyVersion').get('VersionId').should.equal("v3")
|
||||||
|
version.get('PolicyVersion').get('IsDefaultVersion').shouldnt.be.ok
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_create_many_policy_versions():
|
||||||
|
conn = boto3.client('iam', region_name='us-east-1')
|
||||||
|
conn.create_policy(
|
||||||
|
PolicyName="TestCreateManyPolicyVersions",
|
||||||
|
PolicyDocument=MOCK_POLICY)
|
||||||
|
for _ in range(0, 4):
|
||||||
|
conn.create_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
|
||||||
|
PolicyDocument=MOCK_POLICY)
|
||||||
|
with assert_raises(ClientError):
|
||||||
|
conn.create_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
|
||||||
|
PolicyDocument=MOCK_POLICY)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_set_default_policy_version():
|
||||||
|
conn = boto3.client('iam', region_name='us-east-1')
|
||||||
|
conn.create_policy(
|
||||||
|
PolicyName="TestSetDefaultPolicyVersion",
|
||||||
|
PolicyDocument=MOCK_POLICY)
|
||||||
|
conn.create_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
|
||||||
|
PolicyDocument=MOCK_POLICY_2,
|
||||||
|
SetAsDefault=True)
|
||||||
|
conn.create_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
|
||||||
|
PolicyDocument=MOCK_POLICY_3,
|
||||||
|
SetAsDefault=True)
|
||||||
|
versions = conn.list_policy_versions(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion")
|
||||||
|
versions.get('Versions')[0].get('Document').should.equal(json.loads(MOCK_POLICY))
|
||||||
|
versions.get('Versions')[0].get('IsDefaultVersion').shouldnt.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').should.be.ok
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
@ -393,6 +435,7 @@ def test_get_policy_version():
|
|||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
|
PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
|
||||||
VersionId=version.get('PolicyVersion').get('VersionId'))
|
VersionId=version.get('PolicyVersion').get('VersionId'))
|
||||||
retrieved.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
|
retrieved.get('PolicyVersion').get('Document').should.equal(json.loads(MOCK_POLICY))
|
||||||
|
retrieved.get('PolicyVersion').get('IsDefaultVersion').shouldnt.be.ok
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
@ -439,6 +482,7 @@ def test_list_policy_versions():
|
|||||||
versions = conn.list_policy_versions(
|
versions = conn.list_policy_versions(
|
||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
|
||||||
versions.get('Versions')[0].get('VersionId').should.equal('v1')
|
versions.get('Versions')[0].get('VersionId').should.equal('v1')
|
||||||
|
versions.get('Versions')[0].get('IsDefaultVersion').should.be.ok
|
||||||
|
|
||||||
conn.create_policy_version(
|
conn.create_policy_version(
|
||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
|
||||||
@ -448,9 +492,10 @@ def test_list_policy_versions():
|
|||||||
PolicyDocument=MOCK_POLICY_3)
|
PolicyDocument=MOCK_POLICY_3)
|
||||||
versions = conn.list_policy_versions(
|
versions = conn.list_policy_versions(
|
||||||
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
|
||||||
print(versions.get('Versions'))
|
|
||||||
versions.get('Versions')[1].get('Document').should.equal(json.loads(MOCK_POLICY_2))
|
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('Document').should.equal(json.loads(MOCK_POLICY_3))
|
||||||
|
versions.get('Versions')[2].get('IsDefaultVersion').shouldnt.be.ok
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
@ -474,6 +519,21 @@ def test_delete_policy_version():
|
|||||||
len(versions.get('Versions')).should.equal(1)
|
len(versions.get('Versions')).should.equal(1)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_delete_default_policy_version():
|
||||||
|
conn = boto3.client('iam', region_name='us-east-1')
|
||||||
|
conn.create_policy(
|
||||||
|
PolicyName="TestDeletePolicyVersion",
|
||||||
|
PolicyDocument=MOCK_POLICY)
|
||||||
|
conn.create_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
||||||
|
PolicyDocument=MOCK_POLICY_2)
|
||||||
|
with assert_raises(ClientError):
|
||||||
|
conn.delete_policy_version(
|
||||||
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
||||||
|
VersionId='v1')
|
||||||
|
|
||||||
|
|
||||||
@mock_iam_deprecated()
|
@mock_iam_deprecated()
|
||||||
def test_create_user():
|
def test_create_user():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
|
Loading…
Reference in New Issue
Block a user