2014-08-27 15:17:06 +00:00
|
|
|
from __future__ import unicode_literals
|
2016-10-17 22:09:46 +00:00
|
|
|
import base64
|
2019-06-30 15:57:50 +00:00
|
|
|
import json
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2014-03-27 23:12:53 +00:00
|
|
|
import boto
|
2016-07-20 22:12:02 +00:00
|
|
|
import boto3
|
2018-11-19 23:47:21 +00:00
|
|
|
import os
|
2014-03-27 23:12:53 +00:00
|
|
|
import sure # noqa
|
2018-11-19 23:47:21 +00:00
|
|
|
import sys
|
2014-08-19 21:30:11 +00:00
|
|
|
from boto.exception import BotoServerError
|
2016-11-11 22:05:02 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2019-10-18 18:37:35 +00:00
|
|
|
from dateutil.tz import tzutc
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
from moto import mock_iam, mock_iam_deprecated
|
2016-10-17 22:09:46 +00:00
|
|
|
from moto.iam.models import aws_managed_policies
|
2017-05-18 17:37:00 +00:00
|
|
|
from nose.tools import assert_raises, assert_equals
|
2015-06-29 14:46:05 +00:00
|
|
|
from nose.tools import raises
|
2014-03-27 23:12:53 +00:00
|
|
|
|
2018-11-27 16:12:41 +00:00
|
|
|
from datetime import datetime
|
2016-10-17 22:09:46 +00:00
|
|
|
from tests.helpers import requires_boto_gte
|
|
|
|
|
2014-03-27 23:12:53 +00:00
|
|
|
|
2018-10-25 01:00:52 +00:00
|
|
|
MOCK_CERT = """-----BEGIN CERTIFICATE-----
|
|
|
|
MIIBpzCCARACCQCY5yOdxCTrGjANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKDAxt
|
|
|
|
b3RvIHRlc3RpbmcwIBcNMTgxMTA1MTkwNTIwWhgPMjI5MjA4MTkxOTA1MjBaMBcx
|
|
|
|
FTATBgNVBAoMDG1vdG8gdGVzdGluZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
|
|
|
|
gYEA1Jn3g2h7LD3FLqdpcYNbFXCS4V4eDpuTCje9vKFcC3pi/01147X3zdfPy8Mt
|
|
|
|
ZhKxcREOwm4NXykh23P9KW7fBovpNwnbYsbPqj8Hf1ZaClrgku1arTVhEnKjx8zO
|
|
|
|
vaR/bVLCss4uE0E0VM1tJn/QGQsfthFsjuHtwx8uIWz35tUCAwEAATANBgkqhkiG
|
|
|
|
9w0BAQsFAAOBgQBWdOQ7bDc2nWkUhFjZoNIZrqjyNdjlMUndpwREVD7FQ/DuxJMj
|
|
|
|
FyDHrtlrS80dPUQWNYHw++oACDpWO01LGLPPrGmuO/7cOdojPEd852q5gd+7W9xt
|
|
|
|
8vUH+pBa6IBLbvBp+szli51V3TLSWcoyy4ceJNQU2vCkTLoFdS0RLd/7tQ==
|
|
|
|
-----END CERTIFICATE-----"""
|
|
|
|
|
2019-06-30 15:57:50 +00:00
|
|
|
MOCK_POLICY = """
|
|
|
|
{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement":
|
|
|
|
{
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Action": "s3:ListBucket",
|
|
|
|
"Resource": "arn:aws:s3:::example_bucket"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
MOCK_POLICY_2 = """
|
|
|
|
{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Id": "2",
|
|
|
|
"Statement":
|
|
|
|
{
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Action": "s3:ListBucket",
|
|
|
|
"Resource": "arn:aws:s3:::example_bucket"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
MOCK_POLICY_3 = """
|
|
|
|
{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Id": "3",
|
|
|
|
"Statement":
|
|
|
|
{
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Action": "s3:ListBucket",
|
|
|
|
"Resource": "arn:aws:s3:::example_bucket"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2018-10-25 01:00:52 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-07-19 00:31:57 +00:00
|
|
|
def test_get_all_server_certs():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
|
|
|
conn.upload_server_cert("certname", "certbody", "privatekey")
|
2019-10-31 15:44:26 +00:00
|
|
|
certs = conn.get_all_server_certs()["list_server_certificates_response"][
|
|
|
|
"list_server_certificates_result"
|
|
|
|
]["server_certificate_metadata_list"]
|
2014-07-19 00:31:57 +00:00
|
|
|
certs.should.have.length_of(1)
|
|
|
|
cert1 = certs[0]
|
|
|
|
cert1.server_certificate_name.should.equal("certname")
|
2019-10-31 15:44:26 +00:00
|
|
|
cert1.arn.should.equal("arn:aws:iam::123456789012:server-certificate/certname")
|
2014-07-19 00:31:57 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2016-08-15 00:40:39 +00:00
|
|
|
def test_get_server_cert_doesnt_exist():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.get_server_certificate("NonExistant")
|
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-07-19 00:31:57 +00:00
|
|
|
def test_get_server_cert():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
|
|
|
conn.upload_server_cert("certname", "certbody", "privatekey")
|
|
|
|
cert = conn.get_server_certificate("certname")
|
|
|
|
cert.server_certificate_name.should.equal("certname")
|
2019-10-31 15:44:26 +00:00
|
|
|
cert.arn.should.equal("arn:aws:iam::123456789012:server-certificate/certname")
|
2014-07-19 00:31:57 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-07-19 00:31:57 +00:00
|
|
|
def test_upload_server_cert():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
|
|
|
conn.upload_server_cert("certname", "certbody", "privatekey")
|
|
|
|
cert = conn.get_server_certificate("certname")
|
|
|
|
cert.server_certificate_name.should.equal("certname")
|
2019-10-31 15:44:26 +00:00
|
|
|
cert.arn.should.equal("arn:aws:iam::123456789012:server-certificate/certname")
|
2014-07-19 00:31:57 +00:00
|
|
|
|
2016-05-05 02:25:46 +00:00
|
|
|
|
2017-12-08 10:43:09 +00:00
|
|
|
@mock_iam_deprecated()
|
|
|
|
def test_delete_server_cert():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
|
|
|
conn.upload_server_cert("certname", "certbody", "privatekey")
|
|
|
|
conn.get_server_certificate("certname")
|
|
|
|
conn.delete_server_cert("certname")
|
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.get_server_certificate("certname")
|
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.delete_server_cert("certname")
|
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2015-06-29 14:46:05 +00:00
|
|
|
@raises(BotoServerError)
|
|
|
|
def test_get_role__should_throw__when_role_does_not_exist():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_role("unexisting_role")
|
2014-07-19 00:31:57 +00:00
|
|
|
|
2016-05-05 02:25:46 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2017-01-19 02:36:50 +00:00
|
|
|
@raises(BotoServerError)
|
|
|
|
def test_get_instance_profile__should_throw__when_instance_profile_does_not_exist():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_instance_profile("unexisting_instance_profile")
|
2017-01-19 02:36:50 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-03-27 23:12:53 +00:00
|
|
|
def test_create_role_and_instance_profile():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
conn.create_instance_profile("my-profile", path="my-path")
|
2017-02-24 02:37:43 +00:00
|
|
|
conn.create_role(
|
2019-10-31 15:44:26 +00:00
|
|
|
"my-role", assume_role_policy_document="some policy", path="my-path"
|
|
|
|
)
|
2014-03-27 23:12:53 +00:00
|
|
|
|
|
|
|
conn.add_role_to_instance_profile("my-profile", "my-role")
|
|
|
|
|
|
|
|
role = conn.get_role("my-role")
|
|
|
|
role.path.should.equal("my-path")
|
|
|
|
role.assume_role_policy_document.should.equal("some policy")
|
|
|
|
|
|
|
|
profile = conn.get_instance_profile("my-profile")
|
|
|
|
profile.path.should.equal("my-path")
|
2014-08-26 17:25:50 +00:00
|
|
|
role_from_profile = list(profile.roles.values())[0]
|
2019-10-31 15:44:26 +00:00
|
|
|
role_from_profile["role_id"].should.equal(role.role_id)
|
|
|
|
role_from_profile["role_name"].should.equal("my-role")
|
2014-03-27 23:12:53 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.list_roles().roles[0].role_name.should.equal("my-role")
|
2016-03-10 09:27:52 +00:00
|
|
|
|
2018-10-19 23:40:58 +00:00
|
|
|
# Test with an empty path:
|
2019-10-31 15:44:26 +00:00
|
|
|
profile = conn.create_instance_profile("my-other-profile")
|
|
|
|
profile.path.should.equal("/")
|
|
|
|
|
2018-10-19 23:40:58 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2016-05-05 02:25:46 +00:00
|
|
|
def test_remove_role_from_instance_profile():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
conn.create_instance_profile("my-profile", path="my-path")
|
2017-02-24 02:37:43 +00:00
|
|
|
conn.create_role(
|
2019-10-31 15:44:26 +00:00
|
|
|
"my-role", assume_role_policy_document="some policy", path="my-path"
|
|
|
|
)
|
2016-05-05 02:25:46 +00:00
|
|
|
conn.add_role_to_instance_profile("my-profile", "my-role")
|
|
|
|
|
|
|
|
profile = conn.get_instance_profile("my-profile")
|
|
|
|
role_from_profile = list(profile.roles.values())[0]
|
2019-10-31 15:44:26 +00:00
|
|
|
role_from_profile["role_name"].should.equal("my-role")
|
2016-05-05 02:25:46 +00:00
|
|
|
|
|
|
|
conn.remove_role_from_instance_profile("my-profile", "my-role")
|
|
|
|
|
|
|
|
profile = conn.get_instance_profile("my-profile")
|
|
|
|
dict(profile.roles).should.be.empty
|
|
|
|
|
|
|
|
|
2017-07-24 05:31:58 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_get_login_profile():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.create_login_profile(UserName="my-user", Password="my-pass")
|
2017-07-24 05:31:58 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = conn.get_login_profile(UserName="my-user")
|
|
|
|
response["LoginProfile"]["UserName"].should.equal("my-user")
|
2017-07-24 05:31:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam()
|
|
|
|
def test_update_login_profile():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.create_login_profile(UserName="my-user", Password="my-pass")
|
|
|
|
response = conn.get_login_profile(UserName="my-user")
|
|
|
|
response["LoginProfile"].get("PasswordResetRequired").should.equal(None)
|
2017-07-24 05:31:58 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.update_login_profile(
|
|
|
|
UserName="my-user", Password="new-pass", PasswordResetRequired=True
|
|
|
|
)
|
|
|
|
response = conn.get_login_profile(UserName="my-user")
|
|
|
|
response["LoginProfile"].get("PasswordResetRequired").should.equal(True)
|
2017-07-24 05:31:58 +00:00
|
|
|
|
|
|
|
|
2017-05-18 17:37:00 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_delete_role():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2017-05-18 17:37:00 +00:00
|
|
|
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2017-05-18 17:37:00 +00:00
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
|
2019-10-22 13:27:49 +00:00
|
|
|
# Test deletion failure with a managed policy
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
|
|
|
response = conn.create_policy(
|
|
|
|
PolicyName="my-managed-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
conn.attach_role_policy(PolicyArn=response["Policy"]["Arn"], RoleName="my-role")
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.DeleteConflictException):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.detach_role_policy(PolicyArn=response["Policy"]["Arn"], RoleName="my-role")
|
|
|
|
conn.delete_policy(PolicyArn=response["Policy"]["Arn"])
|
2017-05-18 17:37:00 +00:00
|
|
|
conn.delete_role(RoleName="my-role")
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
|
|
|
conn.get_role(RoleName="my-role")
|
2017-05-18 17:37:00 +00:00
|
|
|
|
2019-10-22 13:27:49 +00:00
|
|
|
# Test deletion failure with an inline policy
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
|
|
|
conn.put_role_policy(
|
|
|
|
RoleName="my-role", PolicyName="my-role-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.DeleteConflictException):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
conn.delete_role_policy(RoleName="my-role", PolicyName="my-role-policy")
|
2019-10-22 14:28:59 +00:00
|
|
|
conn.delete_role(RoleName="my-role")
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
|
|
|
conn.get_role(RoleName="my-role")
|
2017-05-18 17:37:00 +00:00
|
|
|
|
2019-10-22 13:27:49 +00:00
|
|
|
# Test deletion failure with attachment to an instance profile
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
2019-10-22 14:28:59 +00:00
|
|
|
conn.create_instance_profile(InstanceProfileName="my-profile")
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.add_role_to_instance_profile(
|
|
|
|
InstanceProfileName="my-profile", RoleName="my-role"
|
|
|
|
)
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.DeleteConflictException):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.remove_role_from_instance_profile(
|
|
|
|
InstanceProfileName="my-profile", RoleName="my-role"
|
|
|
|
)
|
2017-05-18 17:37:00 +00:00
|
|
|
conn.delete_role(RoleName="my-role")
|
2019-10-22 13:27:49 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2017-05-18 17:37:00 +00:00
|
|
|
conn.get_role(RoleName="my-role")
|
|
|
|
|
2019-10-22 14:28:59 +00:00
|
|
|
# Test deletion with no conflicts
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
2019-10-22 14:28:59 +00:00
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2017-05-18 17:37:00 +00:00
|
|
|
conn.get_role(RoleName="my-role")
|
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2016-03-10 09:27:52 +00:00
|
|
|
def test_list_instance_profiles():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
conn.create_instance_profile("my-profile", path="my-path")
|
|
|
|
conn.create_role("my-role", path="my-path")
|
|
|
|
|
|
|
|
conn.add_role_to_instance_profile("my-profile", "my-role")
|
|
|
|
|
|
|
|
profiles = conn.list_instance_profiles().instance_profiles
|
|
|
|
|
|
|
|
len(profiles).should.equal(1)
|
|
|
|
profiles[0].instance_profile_name.should.equal("my-profile")
|
|
|
|
profiles[0].roles.role_name.should.equal("my-role")
|
2014-08-19 21:30:11 +00:00
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2015-02-27 00:08:54 +00:00
|
|
|
def test_list_instance_profiles_for_role():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
role_name="my-role", assume_role_policy_document="some policy", path="my-path"
|
|
|
|
)
|
|
|
|
conn.create_role(
|
|
|
|
role_name="my-role2",
|
|
|
|
assume_role_policy_document="some policy2",
|
|
|
|
path="my-path2",
|
|
|
|
)
|
2015-02-27 00:08:54 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_name_list = ["my-profile", "my-profile2"]
|
|
|
|
profile_path_list = ["my-path", "my-path2"]
|
2015-04-30 23:32:53 +00:00
|
|
|
for profile_count in range(0, 2):
|
2017-02-24 02:37:43 +00:00
|
|
|
conn.create_instance_profile(
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_name_list[profile_count], path=profile_path_list[profile_count]
|
|
|
|
)
|
2015-02-27 00:08:54 +00:00
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
for profile_count in range(0, 2):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.add_role_to_instance_profile(profile_name_list[profile_count], "my-role")
|
2015-02-27 00:08:54 +00:00
|
|
|
|
|
|
|
profile_dump = conn.list_instance_profiles_for_role(role_name="my-role")
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_list = profile_dump["list_instance_profiles_for_role_response"][
|
|
|
|
"list_instance_profiles_for_role_result"
|
|
|
|
]["instance_profiles"]
|
2015-04-30 23:32:53 +00:00
|
|
|
for profile_count in range(0, len(profile_list)):
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_name_list.remove(profile_list[profile_count]["instance_profile_name"])
|
2015-02-27 00:08:54 +00:00
|
|
|
profile_path_list.remove(profile_list[profile_count]["path"])
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_list[profile_count]["roles"]["member"]["role_name"].should.equal(
|
|
|
|
"my-role"
|
|
|
|
)
|
2015-02-27 00:08:54 +00:00
|
|
|
|
|
|
|
len(profile_name_list).should.equal(0)
|
|
|
|
len(profile_path_list).should.equal(0)
|
|
|
|
|
|
|
|
profile_dump2 = conn.list_instance_profiles_for_role(role_name="my-role2")
|
2019-10-31 15:44:26 +00:00
|
|
|
profile_list = profile_dump2["list_instance_profiles_for_role_response"][
|
|
|
|
"list_instance_profiles_for_role_result"
|
|
|
|
]["instance_profiles"]
|
2015-02-27 00:08:54 +00:00
|
|
|
len(profile_list).should.equal(0)
|
2014-12-01 04:11:13 +00:00
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-12-01 04:11:13 +00:00
|
|
|
def test_list_role_policies():
|
2014-11-30 19:16:29 +00:00
|
|
|
conn = boto.connect_iam()
|
2014-12-01 04:11:13 +00:00
|
|
|
conn.create_role("my-role")
|
2019-06-30 15:57:50 +00:00
|
|
|
conn.put_role_policy("my-role", "test policy", MOCK_POLICY)
|
2014-12-01 04:11:13 +00:00
|
|
|
role = conn.list_role_policies("my-role")
|
2017-08-14 04:58:11 +00:00
|
|
|
role.policy_names.should.have.length_of(1)
|
2014-12-01 04:11:13 +00:00
|
|
|
role.policy_names[0].should.equal("test policy")
|
|
|
|
|
2019-06-30 15:57:50 +00:00
|
|
|
conn.put_role_policy("my-role", "test policy 2", MOCK_POLICY)
|
2017-08-14 04:58:11 +00:00
|
|
|
role = conn.list_role_policies("my-role")
|
|
|
|
role.policy_names.should.have.length_of(2)
|
|
|
|
|
|
|
|
conn.delete_role_policy("my-role", "test policy")
|
|
|
|
role = conn.list_role_policies("my-role")
|
|
|
|
role.policy_names.should.have.length_of(1)
|
|
|
|
role.policy_names[0].should.equal("test policy 2")
|
|
|
|
|
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.delete_role_policy("my-role", "test policy")
|
|
|
|
|
2014-12-01 04:11:13 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-12-01 04:11:13 +00:00
|
|
|
def test_put_role_policy():
|
|
|
|
conn = boto.connect_iam()
|
2017-02-24 02:37:43 +00:00
|
|
|
conn.create_role(
|
2019-10-31 15:44:26 +00:00
|
|
|
"my-role", assume_role_policy_document="some policy", path="my-path"
|
|
|
|
)
|
2019-06-30 15:57:50 +00:00
|
|
|
conn.put_role_policy("my-role", "test policy", MOCK_POLICY)
|
2019-10-31 15:44:26 +00:00
|
|
|
policy = conn.get_role_policy("my-role", "test policy")["get_role_policy_response"][
|
|
|
|
"get_role_policy_result"
|
|
|
|
]["policy_name"]
|
2014-12-01 04:11:13 +00:00
|
|
|
policy.should.equal("test policy")
|
|
|
|
|
|
|
|
|
2019-07-07 19:45:51 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_role_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-07-07 19:45:51 +00:00
|
|
|
conn.create_role(
|
2019-10-31 15:44:26 +00:00
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="my-path"
|
|
|
|
)
|
2019-07-07 19:45:51 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
|
|
|
conn.get_role_policy(RoleName="my-role", PolicyName="does-not-exist")
|
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-12-01 04:11:13 +00:00
|
|
|
def test_update_assume_role_policy():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
role = conn.create_role("my-role")
|
|
|
|
conn.update_assume_role_policy(role.role_name, "my-policy")
|
|
|
|
role = conn.get_role("my-role")
|
|
|
|
role.assume_role_policy_document.should.equal("my-policy")
|
|
|
|
|
2014-08-19 21:30:11 +00:00
|
|
|
|
2018-07-13 14:41:22 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_create_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-07-13 14:41:22 +00:00
|
|
|
response = conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="TestCreatePolicy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
response["Policy"]["Arn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:policy/TestCreatePolicy"
|
|
|
|
)
|
2018-07-13 14:41:22 +00:00
|
|
|
|
|
|
|
|
2019-10-17 08:28:19 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_delete_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
response = conn.create_policy(
|
|
|
|
PolicyName="TestCreatePolicy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
[
|
|
|
|
pol["PolicyName"] for pol in conn.list_policies(Scope="Local")["Policies"]
|
|
|
|
].should.equal(["TestCreatePolicy"])
|
|
|
|
conn.delete_policy(PolicyArn=response["Policy"]["Arn"])
|
|
|
|
assert conn.list_policies(Scope="Local")["Policies"].should.be.empty
|
2019-10-17 08:28:19 +00:00
|
|
|
|
|
|
|
|
2017-05-15 21:56:30 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_create_policy_versions():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2017-05-15 21:56:30 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.create_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument='{"some":"policy"}',
|
|
|
|
)
|
|
|
|
conn.create_policy(PolicyName="TestCreatePolicyVersion", PolicyDocument=MOCK_POLICY)
|
2017-05-15 21:56:30 +00:00
|
|
|
version = conn.create_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
2019-06-30 15:57:50 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
2019-10-31 15:44:26 +00:00
|
|
|
SetAsDefault=True,
|
|
|
|
)
|
|
|
|
version.get("PolicyVersion").get("Document").should.equal(json.loads(MOCK_POLICY))
|
|
|
|
version.get("PolicyVersion").get("VersionId").should.equal("v2")
|
|
|
|
version.get("PolicyVersion").get("IsDefaultVersion").should.be.ok
|
2019-04-16 19:29:48 +00:00
|
|
|
conn.delete_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId="v1",
|
|
|
|
)
|
2019-04-16 19:29:48 +00:00
|
|
|
version = conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreatePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
)
|
|
|
|
version.get("PolicyVersion").get("VersionId").should.equal("v3")
|
|
|
|
version.get("PolicyVersion").get("IsDefaultVersion").shouldnt.be.ok
|
2019-06-29 16:15:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_create_many_policy_versions():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-06-29 16:15:01 +00:00
|
|
|
conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="TestCreateManyPolicyVersions", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
for _ in range(0, 4):
|
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestCreateManyPolicyVersions",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_set_default_policy_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-06-29 16:15:01 +00:00
|
|
|
conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="TestSetDefaultPolicyVersion", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
|
2019-07-02 10:24:19 +00:00
|
|
|
PolicyDocument=MOCK_POLICY_2,
|
2019-10-31 15:44:26 +00:00
|
|
|
SetAsDefault=True,
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestSetDefaultPolicyVersion",
|
2019-07-02 10:24:19 +00:00
|
|
|
PolicyDocument=MOCK_POLICY_3,
|
2019-10-31 15:44:26 +00:00
|
|
|
SetAsDefault=True,
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
versions = conn.list_policy_versions(
|
2019-10-31 15:44:26 +00:00
|
|
|
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
|
2017-05-15 21:56:30 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-08-07 20:59:15 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-08-07 20:59:15 +00:00
|
|
|
response = conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="TestGetPolicy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
policy = conn.get_policy(PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicy")
|
|
|
|
policy["Policy"]["Arn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:policy/TestGetPolicy"
|
|
|
|
)
|
2019-06-06 12:36:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_aws_managed_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
managed_policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"
|
|
|
|
managed_policy_create_date = datetime.strptime(
|
|
|
|
"2016-11-15T00:25:16+00:00", "%Y-%m-%dT%H:%M:%S+00:00"
|
|
|
|
)
|
|
|
|
policy = conn.get_policy(PolicyArn=managed_policy_arn)
|
|
|
|
policy["Policy"]["Arn"].should.equal(managed_policy_arn)
|
|
|
|
policy["Policy"]["CreateDate"].replace(tzinfo=None).should.equal(
|
|
|
|
managed_policy_create_date
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
|
2018-08-07 21:24:15 +00:00
|
|
|
|
2017-05-15 21:56:30 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_policy_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_policy(PolicyName="TestGetPolicyVersion", PolicyDocument=MOCK_POLICY)
|
2017-05-15 21:56:30 +00:00
|
|
|
version = conn.create_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.get_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId="v2-does-not-exist",
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
retrieved = conn.get_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestGetPolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId=version.get("PolicyVersion").get("VersionId"),
|
|
|
|
)
|
|
|
|
retrieved.get("PolicyVersion").get("Document").should.equal(json.loads(MOCK_POLICY))
|
|
|
|
retrieved.get("PolicyVersion").get("IsDefaultVersion").shouldnt.be.ok
|
2017-05-15 21:56:30 +00:00
|
|
|
|
|
|
|
|
2019-06-06 12:36:39 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_aws_managed_policy_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
managed_policy_arn = (
|
|
|
|
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
|
|
)
|
|
|
|
managed_policy_version_create_date = datetime.strptime(
|
|
|
|
"2015-04-09T15:03:43+00:00", "%Y-%m-%dT%H:%M:%S+00:00"
|
|
|
|
)
|
2019-06-06 12:36:39 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.get_policy_version(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn=managed_policy_arn, VersionId="v2-does-not-exist"
|
|
|
|
)
|
|
|
|
retrieved = conn.get_policy_version(PolicyArn=managed_policy_arn, VersionId="v1")
|
|
|
|
retrieved["PolicyVersion"]["CreateDate"].replace(tzinfo=None).should.equal(
|
|
|
|
managed_policy_version_create_date
|
|
|
|
)
|
|
|
|
retrieved["PolicyVersion"]["Document"].should.be.an(dict)
|
2019-06-06 12:36:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_aws_managed_policy_v4_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
managed_policy_arn = "arn:aws:iam::aws:policy/job-function/SystemAdministrator"
|
|
|
|
managed_policy_version_create_date = datetime.strptime(
|
|
|
|
"2018-10-08T21:33:45+00:00", "%Y-%m-%dT%H:%M:%S+00:00"
|
|
|
|
)
|
2019-06-06 12:36:39 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.get_policy_version(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn=managed_policy_arn, VersionId="v2-does-not-exist"
|
|
|
|
)
|
|
|
|
retrieved = conn.get_policy_version(PolicyArn=managed_policy_arn, VersionId="v4")
|
|
|
|
retrieved["PolicyVersion"]["CreateDate"].replace(tzinfo=None).should.equal(
|
|
|
|
managed_policy_version_create_date
|
|
|
|
)
|
|
|
|
retrieved["PolicyVersion"]["Document"].should.be.an(dict)
|
2019-06-06 12:36:39 +00:00
|
|
|
|
|
|
|
|
2017-05-15 21:56:30 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_list_policy_versions():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2017-05-15 21:56:30 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
versions = conn.list_policy_versions(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions"
|
|
|
|
)
|
|
|
|
conn.create_policy(PolicyName="TestListPolicyVersions", PolicyDocument=MOCK_POLICY)
|
2018-08-07 21:24:15 +00:00
|
|
|
versions = conn.list_policy_versions(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions"
|
|
|
|
)
|
|
|
|
versions.get("Versions")[0].get("VersionId").should.equal("v1")
|
|
|
|
versions.get("Versions")[0].get("IsDefaultVersion").should.be.ok
|
2019-05-21 16:44:06 +00:00
|
|
|
|
2017-05-15 21:56:30 +00:00
|
|
|
conn.create_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY_2,
|
|
|
|
)
|
2018-08-07 21:24:15 +00:00
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY_3,
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
versions = conn.list_policy_versions(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions"
|
|
|
|
)
|
|
|
|
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
|
2017-05-15 21:56:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_delete_policy_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_policy(PolicyName="TestDeletePolicyVersion", PolicyDocument=MOCK_POLICY)
|
2017-05-15 21:56:30 +00:00
|
|
|
conn.create_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.delete_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId="v2-nope-this-does-not-exist",
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
conn.delete_policy_version(
|
2018-07-13 14:41:22 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId="v2",
|
|
|
|
)
|
2017-05-15 21:56:30 +00:00
|
|
|
versions = conn.list_policy_versions(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion"
|
|
|
|
)
|
|
|
|
len(versions.get("Versions")).should.equal(1)
|
2017-05-15 21:56:30 +00:00
|
|
|
|
|
|
|
|
2019-06-29 16:15:01 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_delete_default_policy_version():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_policy(PolicyName="TestDeletePolicyVersion", PolicyDocument=MOCK_POLICY)
|
2019-06-29 16:15:01 +00:00
|
|
|
conn.create_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyDocument=MOCK_POLICY_2,
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.delete_policy_version(
|
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/TestDeletePolicyVersion",
|
2019-10-31 15:44:26 +00:00
|
|
|
VersionId="v1",
|
|
|
|
)
|
2019-06-29 16:15:01 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-08-19 21:30:11 +00:00
|
|
|
def test_create_user():
|
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
2014-09-03 23:24:05 +00:00
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
2014-08-19 21:30:11 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-08-20 18:56:30 +00:00
|
|
|
def test_get_user():
|
|
|
|
conn = boto.connect_iam()
|
2014-09-03 23:24:05 +00:00
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_user("my-user")
|
|
|
|
conn.create_user("my-user")
|
|
|
|
conn.get_user("my-user")
|
2014-08-20 18:56:30 +00:00
|
|
|
|
2016-11-11 22:05:02 +00:00
|
|
|
|
2019-03-12 16:27:37 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_update_user():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-03-12 16:27:37 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.update_user(UserName="my-user")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.update_user(UserName="my-user", NewPath="/new-path/", NewUserName="new-user")
|
|
|
|
response = conn.get_user(UserName="new-user")
|
|
|
|
response["User"].get("Path").should.equal("/new-path/")
|
2019-03-12 16:27:37 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_user(UserName="my-user")
|
2019-03-12 16:27:37 +00:00
|
|
|
|
|
|
|
|
2017-03-19 15:09:30 +00:00
|
|
|
@mock_iam_deprecated()
|
|
|
|
def test_get_current_user():
|
|
|
|
"""If no user is specific, IAM returns the current user"""
|
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
user = conn.get_user()["get_user_response"]["get_user_result"]["user"]
|
|
|
|
user["user_name"].should.equal("default_user")
|
2017-03-19 15:09:30 +00:00
|
|
|
|
|
|
|
|
2016-07-20 22:12:02 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_list_users():
|
2019-10-31 15:44:26 +00:00
|
|
|
path_prefix = "/"
|
2016-07-20 22:12:02 +00:00
|
|
|
max_items = 10
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
2016-07-25 15:59:57 +00:00
|
|
|
response = conn.list_users(PathPrefix=path_prefix, MaxItems=max_items)
|
2019-10-31 15:44:26 +00:00
|
|
|
user = response["Users"][0]
|
|
|
|
user["UserName"].should.equal("my-user")
|
|
|
|
user["Path"].should.equal("/")
|
|
|
|
user["Arn"].should.equal("arn:aws:iam::123456789012:user/my-user")
|
2016-07-25 15:59:57 +00:00
|
|
|
|
2014-08-20 18:56:30 +00:00
|
|
|
|
2017-04-13 21:09:23 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_user_policies():
|
2019-10-31 15:44:26 +00:00
|
|
|
policy_name = "UserManagedPolicy"
|
|
|
|
user_name = "my-user"
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2017-04-13 21:09:23 +00:00
|
|
|
conn.create_user(UserName=user_name)
|
|
|
|
conn.put_user_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
UserName=user_name, PolicyName=policy_name, PolicyDocument=MOCK_POLICY
|
2017-04-13 21:09:23 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
policy_doc = conn.get_user_policy(UserName=user_name, PolicyName=policy_name)
|
|
|
|
policy_doc["PolicyDocument"].should.equal(json.loads(MOCK_POLICY))
|
2017-04-13 21:09:23 +00:00
|
|
|
|
|
|
|
policies = conn.list_user_policies(UserName=user_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(policies["PolicyNames"]).should.equal(1)
|
|
|
|
policies["PolicyNames"][0].should.equal(policy_name)
|
2017-04-13 21:09:23 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_user_policy(UserName=user_name, PolicyName=policy_name)
|
2017-04-13 21:09:23 +00:00
|
|
|
|
|
|
|
policies = conn.list_user_policies(UserName=user_name)
|
2019-10-31 15:44:26 +00:00
|
|
|
len(policies["PolicyNames"]).should.equal(0)
|
2017-04-13 21:09:23 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-10-29 19:31:49 +00:00
|
|
|
def test_create_login_profile():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_login_profile("my-user", "my-pass")
|
|
|
|
conn.create_user("my-user")
|
|
|
|
conn.create_login_profile("my-user", "my-pass")
|
2014-10-29 19:31:49 +00:00
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_login_profile("my-user", "my-pass")
|
2014-10-29 19:31:49 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2016-11-11 22:05:02 +00:00
|
|
|
def test_delete_login_profile():
|
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
2016-11-11 22:05:02 +00:00
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_login_profile("my-user")
|
|
|
|
conn.create_login_profile("my-user", "my-pass")
|
|
|
|
conn.delete_login_profile("my-user")
|
2016-11-11 22:05:02 +00:00
|
|
|
|
|
|
|
|
2019-07-04 18:04:27 +00:00
|
|
|
@mock_iam()
|
2014-08-19 21:30:11 +00:00
|
|
|
def test_create_access_key():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-07-04 18:04:27 +00:00
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_access_key(UserName="my-user")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
access_key = conn.create_access_key(UserName="my-user")["AccessKey"]
|
|
|
|
(
|
|
|
|
datetime.utcnow() - access_key["CreateDate"].replace(tzinfo=None)
|
|
|
|
).seconds.should.be.within(0, 10)
|
2019-07-04 18:04:27 +00:00
|
|
|
access_key["AccessKeyId"].should.have.length_of(20)
|
2019-07-04 18:20:08 +00:00
|
|
|
access_key["SecretAccessKey"].should.have.length_of(40)
|
2019-07-04 18:04:27 +00:00
|
|
|
assert access_key["AccessKeyId"].startswith("AKIA")
|
2014-08-19 21:30:11 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-08-19 21:30:11 +00:00
|
|
|
def test_get_all_access_keys():
|
2017-05-07 15:02:53 +00:00
|
|
|
"""If no access keys exist there should be none in the response,
|
|
|
|
if an access key is present it should have the correct fields present"""
|
2014-08-19 21:30:11 +00:00
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
|
|
|
response = conn.get_all_access_keys("my-user")
|
2014-08-19 21:30:11 +00:00
|
|
|
assert_equals(
|
2019-10-31 15:44:26 +00:00
|
|
|
response["list_access_keys_response"]["list_access_keys_result"][
|
|
|
|
"access_key_metadata"
|
|
|
|
],
|
|
|
|
[],
|
2014-08-19 21:30:11 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_access_key("my-user")
|
|
|
|
response = conn.get_all_access_keys("my-user")
|
2017-05-07 15:02:53 +00:00
|
|
|
assert_equals(
|
2019-10-31 15:44:26 +00:00
|
|
|
sorted(
|
|
|
|
response["list_access_keys_response"]["list_access_keys_result"][
|
|
|
|
"access_key_metadata"
|
|
|
|
][0].keys()
|
|
|
|
),
|
|
|
|
sorted(["status", "create_date", "user_name", "access_key_id"]),
|
2014-08-19 21:30:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2014-08-20 18:56:30 +00:00
|
|
|
def test_delete_access_key():
|
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
|
|
|
access_key_id = conn.create_access_key("my-user")["create_access_key_response"][
|
|
|
|
"create_access_key_result"
|
|
|
|
]["access_key"]["access_key_id"]
|
|
|
|
conn.delete_access_key(access_key_id, "my-user")
|
2014-08-20 18:56:30 +00:00
|
|
|
|
2014-08-19 21:30:11 +00:00
|
|
|
|
2017-03-27 18:08:57 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_mfa_devices():
|
|
|
|
# Test enable device
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
2017-03-27 18:08:57 +00:00
|
|
|
conn.enable_mfa_device(
|
2019-10-31 15:44:26 +00:00
|
|
|
UserName="my-user",
|
|
|
|
SerialNumber="123456789",
|
|
|
|
AuthenticationCode1="234567",
|
|
|
|
AuthenticationCode2="987654",
|
2017-03-27 18:08:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# Test list mfa devices
|
2019-10-31 15:44:26 +00:00
|
|
|
response = conn.list_mfa_devices(UserName="my-user")
|
|
|
|
device = response["MFADevices"][0]
|
|
|
|
device["SerialNumber"].should.equal("123456789")
|
2017-03-27 18:08:57 +00:00
|
|
|
|
|
|
|
# Test deactivate mfa device
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.deactivate_mfa_device(UserName="my-user", SerialNumber="123456789")
|
|
|
|
response = conn.list_mfa_devices(UserName="my-user")
|
|
|
|
len(response["MFADevices"]).should.equal(0)
|
2017-03-27 18:08:57 +00:00
|
|
|
|
|
|
|
|
2019-10-20 20:39:57 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_create_virtual_mfa_device():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
|
|
|
device = response["VirtualMFADevice"]
|
2019-10-20 20:39:57 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
device["SerialNumber"].should.equal("arn:aws:iam::123456789012:mfa/test-device")
|
|
|
|
device["Base32StringSeed"].decode("ascii").should.match("[A-Z234567]")
|
|
|
|
device["QRCodePNG"].should_not.be.empty
|
2019-10-20 20:39:57 +00:00
|
|
|
|
|
|
|
response = client.create_virtual_mfa_device(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path="/", VirtualMFADeviceName="test-device-2"
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
device = response["VirtualMFADevice"]
|
2019-10-20 20:39:57 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
device["SerialNumber"].should.equal("arn:aws:iam::123456789012:mfa/test-device-2")
|
|
|
|
device["Base32StringSeed"].decode("ascii").should.match("[A-Z234567]")
|
|
|
|
device["QRCodePNG"].should_not.be.empty
|
2019-10-20 20:39:57 +00:00
|
|
|
|
|
|
|
response = client.create_virtual_mfa_device(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path="/test/", VirtualMFADeviceName="test-device"
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
device = response["VirtualMFADevice"]
|
2019-10-20 20:39:57 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
device["SerialNumber"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:mfa/test/test-device"
|
|
|
|
)
|
|
|
|
device["Base32StringSeed"].decode("ascii").should.match("[A-Z234567]")
|
|
|
|
device["QRCodePNG"].should_not.be.empty
|
2019-10-20 20:39:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_create_virtual_mfa_device_errors():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
2019-10-20 20:39:57 +00:00
|
|
|
|
|
|
|
client.create_virtual_mfa_device.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
VirtualMFADeviceName="test-device"
|
2019-10-20 20:39:57 +00:00
|
|
|
).should.throw(
|
2019-10-31 15:44:26 +00:00
|
|
|
ClientError, "MFADevice entity at the same path and name already exists."
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
client.create_virtual_mfa_device.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path="test", VirtualMFADeviceName="test-device"
|
2019-10-20 20:39:57 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"The specified value for path is invalid. "
|
|
|
|
"It must begin and end with / and contain only alphanumeric characters and/or / characters.",
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
client.create_virtual_mfa_device.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path="/test//test/", VirtualMFADeviceName="test-device"
|
2019-10-20 20:39:57 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"The specified value for path is invalid. "
|
|
|
|
"It must begin and end with / and contain only alphanumeric characters and/or / characters.",
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
too_long_path = "/{}/".format("b" * 511)
|
2019-10-20 20:39:57 +00:00
|
|
|
client.create_virtual_mfa_device.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path=too_long_path, VirtualMFADeviceName="test-device"
|
2019-10-20 20:39:57 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"1 validation error detected: "
|
2019-10-20 20:39:57 +00:00
|
|
|
'Value "{}" at "path" failed to satisfy constraint: '
|
2019-10-31 15:44:26 +00:00
|
|
|
"Member must have length less than or equal to 512",
|
2019-10-20 20:39:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-10-20 21:03:20 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_delete_virtual_mfa_device():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
|
|
|
serial_number = response["VirtualMFADevice"]["SerialNumber"]
|
2019-10-20 21:03:20 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
client.delete_virtual_mfa_device(SerialNumber=serial_number)
|
2019-10-20 21:03:20 +00:00
|
|
|
|
2019-10-21 19:48:50 +00:00
|
|
|
response = client.list_virtual_mfa_devices()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.have.length_of(0)
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-20 21:03:20 +00:00
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_delete_virtual_mfa_device_errors():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-20 21:03:20 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
serial_number = "arn:aws:iam::123456789012:mfa/not-existing"
|
2019-10-20 21:03:20 +00:00
|
|
|
client.delete_virtual_mfa_device.when.called_with(
|
|
|
|
SerialNumber=serial_number
|
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"VirtualMFADevice with serial number {0} doesn't exist.".format(serial_number),
|
2019-10-20 21:03:20 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-10-21 19:48:50 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_list_virtual_mfa_devices():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
|
|
|
serial_number_1 = response["VirtualMFADevice"]["SerialNumber"]
|
2019-10-21 19:48:50 +00:00
|
|
|
|
|
|
|
response = client.create_virtual_mfa_device(
|
2019-10-31 15:44:26 +00:00
|
|
|
Path="/test/", VirtualMFADeviceName="test-device"
|
2019-10-21 19:48:50 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
serial_number_2 = response["VirtualMFADevice"]["SerialNumber"]
|
2019-10-21 19:48:50 +00:00
|
|
|
|
|
|
|
response = client.list_virtual_mfa_devices()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.equal(
|
|
|
|
[{"SerialNumber": serial_number_1}, {"SerialNumber": serial_number_2}]
|
2019-10-21 19:48:50 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Assigned")
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.have.length_of(0)
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Unassigned")
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.equal(
|
|
|
|
[{"SerialNumber": serial_number_1}, {"SerialNumber": serial_number_2}]
|
2019-10-21 19:48:50 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Any", MaxItems=1)
|
|
|
|
|
|
|
|
response["VirtualMFADevices"].should.equal([{"SerialNumber": serial_number_1}])
|
|
|
|
response["IsTruncated"].should.be.ok
|
|
|
|
response["Marker"].should.equal("1")
|
2019-10-21 19:48:50 +00:00
|
|
|
|
|
|
|
response = client.list_virtual_mfa_devices(
|
2019-10-31 15:44:26 +00:00
|
|
|
AssignmentStatus="Any", Marker=response["Marker"]
|
2019-10-21 19:48:50 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.equal([{"SerialNumber": serial_number_2}])
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 19:48:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_list_virtual_mfa_devices_errors():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
2019-10-21 19:48:50 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
client.list_virtual_mfa_devices.when.called_with(Marker="100").should.throw(
|
|
|
|
ClientError, "Invalid Marker."
|
2019-10-21 19:48:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-10-21 20:51:00 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_enable_virtual_mfa_device():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
|
|
|
serial_number = response["VirtualMFADevice"]["SerialNumber"]
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
client.create_user(UserName="test-user")
|
2019-10-21 20:51:00 +00:00
|
|
|
client.enable_mfa_device(
|
2019-10-31 15:44:26 +00:00
|
|
|
UserName="test-user",
|
2019-10-21 20:51:00 +00:00
|
|
|
SerialNumber=serial_number,
|
2019-10-31 15:44:26 +00:00
|
|
|
AuthenticationCode1="234567",
|
|
|
|
AuthenticationCode2="987654",
|
2019-10-21 20:51:00 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Unassigned")
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.have.length_of(0)
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Assigned")
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
device = response["VirtualMFADevices"][0]
|
|
|
|
device["SerialNumber"].should.equal(serial_number)
|
|
|
|
device["User"]["Path"].should.equal("/")
|
|
|
|
device["User"]["UserName"].should.equal("test-user")
|
|
|
|
device["User"]["UserId"].should_not.be.empty
|
|
|
|
device["User"]["Arn"].should.equal("arn:aws:iam::123456789012:user/test-user")
|
|
|
|
device["User"]["CreateDate"].should.be.a(datetime)
|
|
|
|
device["EnableDate"].should.be.a(datetime)
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
client.deactivate_mfa_device(UserName="test-user", SerialNumber=serial_number)
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Assigned")
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.have.length_of(0)
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.list_virtual_mfa_devices(AssignmentStatus="Unassigned")
|
2019-10-21 20:51:00 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["VirtualMFADevices"].should.equal([{"SerialNumber": serial_number}])
|
|
|
|
response["IsTruncated"].should_not.be.ok
|
2019-10-21 20:51:00 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2019-10-17 08:28:19 +00:00
|
|
|
def test_delete_user_deprecated():
|
2014-08-19 21:30:11 +00:00
|
|
|
conn = boto.connect_iam()
|
2014-09-03 23:24:05 +00:00
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_user("my-user")
|
|
|
|
conn.create_user("my-user")
|
|
|
|
conn.delete_user("my-user")
|
2015-02-02 22:42:57 +00:00
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2019-10-17 08:28:19 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_delete_user():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-10-22 14:28:59 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_user(UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
|
|
|
|
# Test deletion failure with a managed policy
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
response = conn.create_policy(
|
|
|
|
PolicyName="my-managed-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
conn.attach_user_policy(PolicyArn=response["Policy"]["Arn"], UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
with assert_raises(conn.exceptions.DeleteConflictException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_user(UserName="my-user")
|
|
|
|
conn.detach_user_policy(PolicyArn=response["Policy"]["Arn"], UserName="my-user")
|
|
|
|
conn.delete_policy(PolicyArn=response["Policy"]["Arn"])
|
|
|
|
conn.delete_user(UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_user(UserName="my-user")
|
2019-10-22 13:27:49 +00:00
|
|
|
|
2019-10-22 14:28:59 +00:00
|
|
|
# Test deletion failure with an inline policy
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user(UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
conn.put_user_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
UserName="my-user", PolicyName="my-user-policy", PolicyDocument=MOCK_POLICY
|
2019-10-22 14:28:59 +00:00
|
|
|
)
|
|
|
|
with assert_raises(conn.exceptions.DeleteConflictException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_user(UserName="my-user")
|
|
|
|
conn.delete_user_policy(UserName="my-user", PolicyName="my-user-policy")
|
|
|
|
conn.delete_user(UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_user(UserName="my-user")
|
2019-10-22 13:27:49 +00:00
|
|
|
|
2019-10-22 14:28:59 +00:00
|
|
|
# Test deletion with no conflicts
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.delete_user(UserName="my-user")
|
2019-10-22 14:28:59 +00:00
|
|
|
with assert_raises(conn.exceptions.NoSuchEntityException):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.get_user(UserName="my-user")
|
2019-10-17 08:28:19 +00:00
|
|
|
|
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2015-02-02 22:42:57 +00:00
|
|
|
def test_generate_credential_report():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
result["generate_credential_report_response"]["generate_credential_report_result"][
|
|
|
|
"state"
|
|
|
|
].should.equal("STARTED")
|
2015-02-02 22:42:57 +00:00
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
result["generate_credential_report_response"]["generate_credential_report_result"][
|
|
|
|
"state"
|
|
|
|
].should.equal("COMPLETE")
|
|
|
|
|
2015-02-02 22:42:57 +00:00
|
|
|
|
2018-11-01 19:51:17 +00:00
|
|
|
@mock_iam
|
2018-11-01 19:58:09 +00:00
|
|
|
def test_boto3_generate_credential_report():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-11-01 19:51:17 +00:00
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
result["State"].should.equal("STARTED")
|
2018-11-01 19:51:17 +00:00
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
result["State"].should.equal("COMPLETE")
|
2018-11-01 19:51:17 +00:00
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2015-02-02 22:42:57 +00:00
|
|
|
def test_get_credential_report():
|
|
|
|
conn = boto.connect_iam()
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user("my-user")
|
2015-02-02 22:42:57 +00:00
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.get_credential_report()
|
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
while (
|
|
|
|
result["generate_credential_report_response"][
|
|
|
|
"generate_credential_report_result"
|
|
|
|
]["state"]
|
|
|
|
!= "COMPLETE"
|
|
|
|
):
|
2015-02-02 22:42:57 +00:00
|
|
|
result = conn.generate_credential_report()
|
|
|
|
result = conn.get_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
report = base64.b64decode(
|
|
|
|
result["get_credential_report_response"]["get_credential_report_result"][
|
|
|
|
"content"
|
|
|
|
].encode("ascii")
|
|
|
|
).decode("ascii")
|
|
|
|
report.should.match(r".*my-user.*")
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-11-01 19:51:17 +00:00
|
|
|
@mock_iam
|
2018-11-01 19:58:09 +00:00
|
|
|
def test_boto3_get_credential_report():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
2018-11-01 19:51:17 +00:00
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.get_credential_report()
|
|
|
|
result = conn.generate_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
while result["State"] != "COMPLETE":
|
2018-11-01 19:51:17 +00:00
|
|
|
result = conn.generate_credential_report()
|
|
|
|
result = conn.get_credential_report()
|
2019-10-31 15:44:26 +00:00
|
|
|
report = result["Content"].decode("utf-8")
|
|
|
|
report.should.match(r".*my-user.*")
|
2018-11-01 19:51:17 +00:00
|
|
|
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
@requires_boto_gte("2.39")
|
2017-02-16 03:35:45 +00:00
|
|
|
@mock_iam_deprecated()
|
2016-10-17 22:09:46 +00:00
|
|
|
def test_managed_policy():
|
|
|
|
conn = boto.connect_iam()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_policy(
|
|
|
|
policy_name="UserManagedPolicy",
|
|
|
|
policy_document=MOCK_POLICY,
|
|
|
|
path="/mypolicy/",
|
|
|
|
description="my user managed policy",
|
|
|
|
)
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2017-09-19 21:01:08 +00:00
|
|
|
marker = 0
|
|
|
|
aws_policies = []
|
|
|
|
while marker is not None:
|
2019-10-31 15:44:26 +00:00
|
|
|
response = conn.list_policies(scope="AWS", marker=marker)[
|
|
|
|
"list_policies_response"
|
|
|
|
]["list_policies_result"]
|
|
|
|
for policy in response["policies"]:
|
2017-09-19 21:01:08 +00:00
|
|
|
aws_policies.append(policy)
|
2019-10-31 15:44:26 +00:00
|
|
|
marker = response.get("marker")
|
2017-02-24 02:37:43 +00:00
|
|
|
set(p.name for p in aws_managed_policies).should.equal(
|
2019-10-31 15:44:26 +00:00
|
|
|
set(p["policy_name"] for p in aws_policies)
|
|
|
|
)
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
user_policies = conn.list_policies(scope="Local")["list_policies_response"][
|
|
|
|
"list_policies_result"
|
|
|
|
]["policies"]
|
|
|
|
set(["UserManagedPolicy"]).should.equal(
|
|
|
|
set(p["policy_name"] for p in user_policies)
|
|
|
|
)
|
2016-10-17 22:09:46 +00:00
|
|
|
|
2017-09-19 21:01:08 +00:00
|
|
|
marker = 0
|
|
|
|
all_policies = []
|
|
|
|
while marker is not None:
|
2019-10-31 15:44:26 +00:00
|
|
|
response = conn.list_policies(marker=marker)["list_policies_response"][
|
|
|
|
"list_policies_result"
|
|
|
|
]
|
|
|
|
for policy in response["policies"]:
|
2017-09-19 21:01:08 +00:00
|
|
|
all_policies.append(policy)
|
2019-10-31 15:44:26 +00:00
|
|
|
marker = response.get("marker")
|
|
|
|
set(p["policy_name"] for p in aws_policies + user_policies).should.equal(
|
|
|
|
set(p["policy_name"] for p in all_policies)
|
|
|
|
)
|
|
|
|
|
|
|
|
role_name = "my-role"
|
|
|
|
conn.create_role(
|
|
|
|
role_name, assume_role_policy_document={"policy": "test"}, path="my-path"
|
|
|
|
)
|
|
|
|
for policy_name in [
|
|
|
|
"AmazonElasticMapReduceRole",
|
|
|
|
"AmazonElasticMapReduceforEC2Role",
|
|
|
|
]:
|
|
|
|
policy_arn = "arn:aws:iam::aws:policy/service-role/" + policy_name
|
2016-10-17 22:09:46 +00:00
|
|
|
conn.attach_role_policy(policy_arn, role_name)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
rows = conn.list_policies(only_attached=True)["list_policies_response"][
|
|
|
|
"list_policies_result"
|
|
|
|
]["policies"]
|
2016-10-17 22:09:46 +00:00
|
|
|
rows.should.have.length_of(2)
|
|
|
|
for x in rows:
|
2019-10-31 15:44:26 +00:00
|
|
|
int(x["attachment_count"]).should.be.greater_than(0)
|
2016-10-17 22:09:46 +00:00
|
|
|
|
|
|
|
# boto has not implemented this end point but accessible this way
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = conn.get_response(
|
|
|
|
"ListAttachedRolePolicies",
|
|
|
|
{"RoleName": role_name},
|
|
|
|
list_marker="AttachedPolicies",
|
|
|
|
)
|
|
|
|
resp["list_attached_role_policies_response"]["list_attached_role_policies_result"][
|
|
|
|
"attached_policies"
|
|
|
|
].should.have.length_of(2)
|
2016-11-11 22:05:02 +00:00
|
|
|
|
2017-08-14 04:58:11 +00:00
|
|
|
conn.detach_role_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole", role_name
|
|
|
|
)
|
|
|
|
rows = conn.list_policies(only_attached=True)["list_policies_response"][
|
|
|
|
"list_policies_result"
|
|
|
|
]["policies"]
|
2017-08-14 04:58:11 +00:00
|
|
|
rows.should.have.length_of(1)
|
|
|
|
for x in rows:
|
2019-10-31 15:44:26 +00:00
|
|
|
int(x["attachment_count"]).should.be.greater_than(0)
|
2017-08-14 04:58:11 +00:00
|
|
|
|
|
|
|
# boto has not implemented this end point but accessible this way
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = conn.get_response(
|
|
|
|
"ListAttachedRolePolicies",
|
|
|
|
{"RoleName": role_name},
|
|
|
|
list_marker="AttachedPolicies",
|
|
|
|
)
|
|
|
|
resp["list_attached_role_policies_response"]["list_attached_role_policies_result"][
|
|
|
|
"attached_policies"
|
|
|
|
].should.have.length_of(1)
|
2017-08-14 04:58:11 +00:00
|
|
|
|
|
|
|
with assert_raises(BotoServerError):
|
|
|
|
conn.detach_role_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
"arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceRole", role_name
|
|
|
|
)
|
2017-08-14 04:58:11 +00:00
|
|
|
|
|
|
|
with assert_raises(BotoServerError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.detach_role_policy("arn:aws:iam::aws:policy/Nonexistent", role_name)
|
2017-08-14 04:58:11 +00:00
|
|
|
|
2016-11-11 22:05:02 +00:00
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_boto3_create_login_profile():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2016-11-11 22:05:02 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_login_profile(UserName="my-user", Password="Password")
|
2016-11-11 22:05:02 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.create_login_profile(UserName="my-user", Password="Password")
|
2016-11-11 22:05:02 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_login_profile(UserName="my-user", Password="Password")
|
2017-08-12 00:57:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam()
|
|
|
|
def test_attach_detach_user_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
iam = boto3.resource("iam", region_name="us-east-1")
|
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2017-08-12 00:57:06 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
user = iam.create_user(UserName="test-user")
|
2017-08-12 00:57:06 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
policy_name = "UserAttachedPolicy"
|
|
|
|
policy = iam.create_policy(
|
|
|
|
PolicyName=policy_name,
|
|
|
|
PolicyDocument=MOCK_POLICY,
|
|
|
|
Path="/mypolicy/",
|
|
|
|
Description="my user attached policy",
|
|
|
|
)
|
2017-08-12 00:57:06 +00:00
|
|
|
|
|
|
|
client.attach_user_policy(UserName=user.name, PolicyArn=policy.arn)
|
|
|
|
|
|
|
|
resp = client.list_attached_user_policies(UserName=user.name)
|
2019-10-31 15:44:26 +00:00
|
|
|
resp["AttachedPolicies"].should.have.length_of(1)
|
|
|
|
attached_policy = resp["AttachedPolicies"][0]
|
|
|
|
attached_policy["PolicyArn"].should.equal(policy.arn)
|
|
|
|
attached_policy["PolicyName"].should.equal(policy_name)
|
2017-08-12 00:57:06 +00:00
|
|
|
|
|
|
|
client.detach_user_policy(UserName=user.name, PolicyArn=policy.arn)
|
|
|
|
|
|
|
|
resp = client.list_attached_user_policies(UserName=user.name)
|
2019-10-31 15:44:26 +00:00
|
|
|
resp["AttachedPolicies"].should.have.length_of(0)
|
2018-01-10 23:29:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_access_key():
|
2019-10-31 15:44:26 +00:00
|
|
|
iam = boto3.resource("iam", region_name="us-east-1")
|
2018-01-10 23:29:08 +00:00
|
|
|
client = iam.meta.client
|
2019-10-31 15:44:26 +00:00
|
|
|
username = "test-user"
|
2018-01-10 23:29:08 +00:00
|
|
|
iam.create_user(UserName=username)
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.update_access_key(
|
|
|
|
UserName=username, AccessKeyId="non-existent-key", Status="Inactive"
|
|
|
|
)
|
|
|
|
key = client.create_access_key(UserName=username)["AccessKey"]
|
|
|
|
client.update_access_key(
|
|
|
|
UserName=username, AccessKeyId=key["AccessKeyId"], Status="Inactive"
|
|
|
|
)
|
2018-01-10 23:29:08 +00:00
|
|
|
resp = client.list_access_keys(UserName=username)
|
2019-10-31 15:44:26 +00:00
|
|
|
resp["AccessKeyMetadata"][0]["Status"].should.equal("Inactive")
|
2018-08-07 17:31:36 +00:00
|
|
|
|
|
|
|
|
2018-11-27 11:28:09 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_access_key_last_used():
|
2019-10-31 15:44:26 +00:00
|
|
|
iam = boto3.resource("iam", region_name="us-east-1")
|
2018-11-27 11:28:09 +00:00
|
|
|
client = iam.meta.client
|
2019-10-31 15:44:26 +00:00
|
|
|
username = "test-user"
|
2018-11-27 11:28:09 +00:00
|
|
|
iam.create_user(UserName=username)
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.get_access_key_last_used(AccessKeyId="non-existent-key-id")
|
|
|
|
create_key_response = client.create_access_key(UserName=username)["AccessKey"]
|
|
|
|
resp = client.get_access_key_last_used(
|
|
|
|
AccessKeyId=create_key_response["AccessKeyId"]
|
|
|
|
)
|
|
|
|
|
|
|
|
datetime.strftime(
|
|
|
|
resp["AccessKeyLastUsed"]["LastUsedDate"], "%Y-%m-%d"
|
|
|
|
).should.equal(datetime.strftime(datetime.utcnow(), "%Y-%m-%d"))
|
2018-11-27 16:12:41 +00:00
|
|
|
resp["UserName"].should.equal(create_key_response["UserName"])
|
2018-11-27 11:28:09 +00:00
|
|
|
|
|
|
|
|
2018-08-07 17:31:36 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_account_authorization_details():
|
2019-10-31 15:44:26 +00:00
|
|
|
test_policy = json.dumps(
|
|
|
|
{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{"Action": "s3:ListBucket", "Resource": "*", "Effect": "Allow"}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
)
|
2019-02-04 21:44:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
boundary = "arn:aws:iam::123456789012:policy/boundary"
|
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
AssumeRolePolicyDocument="some policy",
|
|
|
|
Path="/my-path/",
|
|
|
|
Description="testing",
|
|
|
|
PermissionsBoundary=boundary,
|
|
|
|
)
|
|
|
|
conn.create_user(Path="/", UserName="testUser")
|
|
|
|
conn.create_group(Path="/", GroupName="testGroup")
|
2018-08-07 17:31:36 +00:00
|
|
|
conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="testPolicy",
|
|
|
|
Path="/",
|
2019-02-04 21:44:01 +00:00
|
|
|
PolicyDocument=test_policy,
|
2019-10-31 15:44:26 +00:00
|
|
|
Description="Test Policy",
|
2018-08-07 17:31:36 +00:00
|
|
|
)
|
|
|
|
|
2019-02-04 21:44:01 +00:00
|
|
|
# Attach things to the user and group:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.put_user_policy(
|
|
|
|
UserName="testUser", PolicyName="testPolicy", PolicyDocument=test_policy
|
|
|
|
)
|
|
|
|
conn.put_group_policy(
|
|
|
|
GroupName="testGroup", PolicyName="testPolicy", PolicyDocument=test_policy
|
|
|
|
)
|
2019-02-04 21:44:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.attach_user_policy(
|
|
|
|
UserName="testUser", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
conn.attach_group_policy(
|
|
|
|
GroupName="testGroup", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
2019-02-04 21:44:01 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.add_user_to_group(UserName="testUser", GroupName="testGroup")
|
2019-02-04 21:44:01 +00:00
|
|
|
|
|
|
|
# Add things to the role:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_instance_profile(InstanceProfileName="ipn")
|
|
|
|
conn.add_role_to_instance_profile(InstanceProfileName="ipn", RoleName="my-role")
|
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[
|
|
|
|
{"Key": "somekey", "Value": "somevalue"},
|
|
|
|
{"Key": "someotherkey", "Value": "someothervalue"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
conn.put_role_policy(
|
|
|
|
RoleName="my-role", PolicyName="test-policy", PolicyDocument=test_policy
|
|
|
|
)
|
|
|
|
conn.attach_role_policy(
|
|
|
|
RoleName="my-role", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.get_account_authorization_details(Filter=["Role"])
|
|
|
|
assert len(result["RoleDetailList"]) == 1
|
|
|
|
assert len(result["UserDetailList"]) == 0
|
|
|
|
assert len(result["GroupDetailList"]) == 0
|
|
|
|
assert len(result["Policies"]) == 0
|
|
|
|
assert len(result["RoleDetailList"][0]["InstanceProfileList"]) == 1
|
|
|
|
assert (
|
|
|
|
result["RoleDetailList"][0]["InstanceProfileList"][0]["Roles"][0]["Description"]
|
|
|
|
== "testing"
|
|
|
|
)
|
|
|
|
assert result["RoleDetailList"][0]["InstanceProfileList"][0]["Roles"][0][
|
|
|
|
"PermissionsBoundary"
|
|
|
|
] == {
|
|
|
|
"PermissionsBoundaryType": "PermissionsBoundaryPolicy",
|
|
|
|
"PermissionsBoundaryArn": "arn:aws:iam::123456789012:policy/boundary",
|
2019-08-21 19:24:23 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
assert len(result["RoleDetailList"][0]["Tags"]) == 2
|
|
|
|
assert len(result["RoleDetailList"][0]["RolePolicyList"]) == 1
|
|
|
|
assert len(result["RoleDetailList"][0]["AttachedManagedPolicies"]) == 1
|
|
|
|
assert (
|
|
|
|
result["RoleDetailList"][0]["AttachedManagedPolicies"][0]["PolicyName"]
|
|
|
|
== "testPolicy"
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
result["RoleDetailList"][0]["AttachedManagedPolicies"][0]["PolicyArn"]
|
|
|
|
== "arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.get_account_authorization_details(Filter=["User"])
|
|
|
|
assert len(result["RoleDetailList"]) == 0
|
|
|
|
assert len(result["UserDetailList"]) == 1
|
|
|
|
assert len(result["UserDetailList"][0]["GroupList"]) == 1
|
|
|
|
assert len(result["UserDetailList"][0]["AttachedManagedPolicies"]) == 1
|
|
|
|
assert len(result["GroupDetailList"]) == 0
|
|
|
|
assert len(result["Policies"]) == 0
|
|
|
|
assert (
|
|
|
|
result["UserDetailList"][0]["AttachedManagedPolicies"][0]["PolicyName"]
|
|
|
|
== "testPolicy"
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
result["UserDetailList"][0]["AttachedManagedPolicies"][0]["PolicyArn"]
|
|
|
|
== "arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.get_account_authorization_details(Filter=["Group"])
|
|
|
|
assert len(result["RoleDetailList"]) == 0
|
|
|
|
assert len(result["UserDetailList"]) == 0
|
|
|
|
assert len(result["GroupDetailList"]) == 1
|
|
|
|
assert len(result["GroupDetailList"][0]["GroupPolicyList"]) == 1
|
|
|
|
assert len(result["GroupDetailList"][0]["AttachedManagedPolicies"]) == 1
|
|
|
|
assert len(result["Policies"]) == 0
|
|
|
|
assert (
|
|
|
|
result["GroupDetailList"][0]["AttachedManagedPolicies"][0]["PolicyName"]
|
|
|
|
== "testPolicy"
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
result["GroupDetailList"][0]["AttachedManagedPolicies"][0]["PolicyArn"]
|
|
|
|
== "arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = conn.get_account_authorization_details(Filter=["LocalManagedPolicy"])
|
|
|
|
assert len(result["RoleDetailList"]) == 0
|
|
|
|
assert len(result["UserDetailList"]) == 0
|
|
|
|
assert len(result["GroupDetailList"]) == 0
|
|
|
|
assert len(result["Policies"]) == 1
|
|
|
|
assert len(result["Policies"][0]["PolicyVersionList"]) == 1
|
2018-08-07 17:31:36 +00:00
|
|
|
|
|
|
|
# Check for greater than 1 since this should always be greater than one but might change.
|
|
|
|
# See iam/aws_managed_policies.py
|
2019-10-31 15:44:26 +00:00
|
|
|
result = conn.get_account_authorization_details(Filter=["AWSManagedPolicy"])
|
|
|
|
assert len(result["RoleDetailList"]) == 0
|
|
|
|
assert len(result["UserDetailList"]) == 0
|
|
|
|
assert len(result["GroupDetailList"]) == 0
|
|
|
|
assert len(result["Policies"]) > 1
|
2018-08-07 17:31:36 +00:00
|
|
|
|
|
|
|
result = conn.get_account_authorization_details()
|
2019-10-31 15:44:26 +00:00
|
|
|
assert len(result["RoleDetailList"]) == 1
|
|
|
|
assert len(result["UserDetailList"]) == 1
|
|
|
|
assert len(result["GroupDetailList"]) == 1
|
|
|
|
assert len(result["Policies"]) > 1
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_signing_certs():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Create the IAM user first:
|
2019-10-31 15:44:26 +00:00
|
|
|
client.create_user(UserName="testing")
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Upload the cert:
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = client.upload_signing_certificate(
|
|
|
|
UserName="testing", CertificateBody=MOCK_CERT
|
|
|
|
)["Certificate"]
|
|
|
|
cert_id = resp["CertificateId"]
|
2018-10-25 01:00:52 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert resp["UserName"] == "testing"
|
|
|
|
assert resp["Status"] == "Active"
|
|
|
|
assert resp["CertificateBody"] == MOCK_CERT
|
|
|
|
assert resp["CertificateId"]
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Upload a the cert with an invalid body:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
client.upload_signing_certificate(
|
|
|
|
UserName="testing", CertificateBody="notacert"
|
|
|
|
)
|
|
|
|
assert ce.exception.response["Error"]["Code"] == "MalformedCertificate"
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Upload with an invalid user:
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.upload_signing_certificate(
|
|
|
|
UserName="notauser", CertificateBody=MOCK_CERT
|
|
|
|
)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Update:
|
2019-10-31 15:44:26 +00:00
|
|
|
client.update_signing_certificate(
|
|
|
|
UserName="testing", CertificateId=cert_id, Status="Inactive"
|
|
|
|
)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.update_signing_certificate(
|
|
|
|
UserName="notauser", CertificateId=cert_id, Status="Inactive"
|
|
|
|
)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
client.update_signing_certificate(
|
|
|
|
UserName="testing", CertificateId="x" * 32, Status="Inactive"
|
|
|
|
)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert ce.exception.response["Error"][
|
|
|
|
"Message"
|
|
|
|
] == "The Certificate with id {id} cannot be found.".format(id="x" * 32)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# List the certs:
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = client.list_signing_certificates(UserName="testing")["Certificates"]
|
2018-10-25 01:00:52 +00:00
|
|
|
assert len(resp) == 1
|
2019-10-31 15:44:26 +00:00
|
|
|
assert resp[0]["CertificateBody"] == MOCK_CERT
|
|
|
|
assert resp[0]["Status"] == "Inactive" # Changed with the update call above.
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.list_signing_certificates(UserName="notauser")
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Delete:
|
2019-10-31 15:44:26 +00:00
|
|
|
client.delete_signing_certificate(UserName="testing", CertificateId=cert_id)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
client.delete_signing_certificate(UserName="notauser", CertificateId=cert_id)
|
2018-08-07 17:31:36 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-11-19 23:47:21 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_create_saml_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-11-19 23:47:21 +00:00
|
|
|
response = conn.create_saml_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Name="TestSAMLProvider", SAMLMetadataDocument="a" * 1024
|
|
|
|
)
|
|
|
|
response["SAMLProviderArn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:saml-provider/TestSAMLProvider"
|
2018-11-19 23:47:21 +00:00
|
|
|
)
|
2018-08-07 17:31:36 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-11-19 23:47:21 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_get_saml_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-11-19 23:47:21 +00:00
|
|
|
saml_provider_create = conn.create_saml_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Name="TestSAMLProvider", SAMLMetadataDocument="a" * 1024
|
2018-11-19 23:47:21 +00:00
|
|
|
)
|
|
|
|
response = conn.get_saml_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
SAMLProviderArn=saml_provider_create["SAMLProviderArn"]
|
2018-11-19 23:47:21 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
response["SAMLMetadataDocument"].should.equal("a" * 1024)
|
2018-08-07 17:31:36 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-11-19 23:47:21 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_list_saml_providers():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_saml_provider(Name="TestSAMLProvider", SAMLMetadataDocument="a" * 1024)
|
2018-11-19 23:47:21 +00:00
|
|
|
response = conn.list_saml_providers()
|
2019-10-31 15:44:26 +00:00
|
|
|
response["SAMLProviderList"][0]["Arn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:saml-provider/TestSAMLProvider"
|
|
|
|
)
|
2018-11-19 23:47:21 +00:00
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
|
2018-11-19 23:47:21 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_delete_saml_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2018-11-19 23:47:21 +00:00
|
|
|
saml_provider_create = conn.create_saml_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Name="TestSAMLProvider", SAMLMetadataDocument="a" * 1024
|
2018-11-19 23:47:21 +00:00
|
|
|
)
|
|
|
|
response = conn.list_saml_providers()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["SAMLProviderList"]).should.equal(1)
|
|
|
|
conn.delete_saml_provider(SAMLProviderArn=saml_provider_create["SAMLProviderArn"])
|
2018-11-19 23:47:21 +00:00
|
|
|
response = conn.list_saml_providers()
|
2019-10-31 15:44:26 +00:00
|
|
|
len(response["SAMLProviderList"]).should.equal(0)
|
|
|
|
conn.create_user(UserName="testing")
|
2018-12-29 01:57:47 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
cert_id = "123456789012345678901234"
|
2018-10-25 01:00:52 +00:00
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.delete_signing_certificate(UserName="testing", CertificateId=cert_id)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert ce.exception.response["Error"][
|
|
|
|
"Message"
|
|
|
|
] == "The Certificate with id {id} cannot be found.".format(id=cert_id)
|
2018-10-25 01:00:52 +00:00
|
|
|
|
|
|
|
# Verify that it's not in the list:
|
2019-10-31 15:44:26 +00:00
|
|
|
resp = conn.list_signing_certificates(UserName="testing")
|
|
|
|
assert not resp["Certificates"]
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
|
2019-08-21 19:24:23 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_create_role_with_tags():
|
|
|
|
"""Tests both the tag_role and get_role_tags capability"""
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[
|
|
|
|
{"Key": "somekey", "Value": "somevalue"},
|
|
|
|
{"Key": "someotherkey", "Value": "someothervalue"},
|
|
|
|
],
|
|
|
|
Description="testing",
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# Get role:
|
2019-10-31 15:44:26 +00:00
|
|
|
role = conn.get_role(RoleName="my-role")["Role"]
|
|
|
|
assert len(role["Tags"]) == 2
|
|
|
|
assert role["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert role["Tags"][0]["Value"] == "somevalue"
|
|
|
|
assert role["Tags"][1]["Key"] == "someotherkey"
|
|
|
|
assert role["Tags"][1]["Value"] == "someothervalue"
|
|
|
|
assert role["Description"] == "testing"
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# Empty is good:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role2",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "somekey", "Value": ""}],
|
|
|
|
)
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role2")
|
|
|
|
assert len(tags["Tags"]) == 1
|
|
|
|
assert tags["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert tags["Tags"][0]["Value"] == ""
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# Test creating tags with invalid values:
|
|
|
|
# With more than 50 tags:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
too_many_tags = list(
|
|
|
|
map(lambda x: {"Key": str(x), "Value": str(x)}, range(0, 51))
|
|
|
|
)
|
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3", AssumeRolePolicyDocument="{}", Tags=too_many_tags
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"failed to satisfy constraint: Member must have length less than or equal to 50."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# With a duplicate tag:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "0", "Value": ""}, {"Key": "0", "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Duplicate tag keys found. Please note that Tag keys are case insensitive."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# Duplicate tag with different casing:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "a", "Value": ""}, {"Key": "A", "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Duplicate tag keys found. Please note that Tag keys are case insensitive."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# With a really big key:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "0" * 129, "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Member must have length less than or equal to 128."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# With a really big value:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "0", "Value": "0" * 257}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Member must have length less than or equal to 256."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
# With an invalid character:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role3",
|
|
|
|
AssumeRolePolicyDocument="{}",
|
|
|
|
Tags=[{"Key": "NOWAY!", "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Member must satisfy regular expression pattern: [\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]+"
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-08-21 19:24:23 +00:00
|
|
|
|
|
|
|
|
2019-01-30 02:09:31 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_tag_role():
|
|
|
|
"""Tests both the tag_role and get_role_tags capability"""
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-01-30 02:09:31 +00:00
|
|
|
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="{}")
|
|
|
|
|
|
|
|
# Get without tags:
|
2019-10-31 15:44:26 +00:00
|
|
|
role = conn.get_role(RoleName="my-role")["Role"]
|
|
|
|
assert not role.get("Tags")
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With proper tag values:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[
|
|
|
|
{"Key": "somekey", "Value": "somevalue"},
|
|
|
|
{"Key": "someotherkey", "Value": "someothervalue"},
|
|
|
|
],
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Get role:
|
2019-10-31 15:44:26 +00:00
|
|
|
role = conn.get_role(RoleName="my-role")["Role"]
|
|
|
|
assert len(role["Tags"]) == 2
|
|
|
|
assert role["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert role["Tags"][0]["Value"] == "somevalue"
|
|
|
|
assert role["Tags"][1]["Key"] == "someotherkey"
|
|
|
|
assert role["Tags"][1]["Value"] == "someothervalue"
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Same -- but for list_role_tags:
|
2019-10-31 15:44:26 +00:00
|
|
|
tags = conn.list_role_tags(RoleName="my-role")
|
|
|
|
assert len(tags["Tags"]) == 2
|
|
|
|
assert role["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert role["Tags"][0]["Value"] == "somevalue"
|
|
|
|
assert role["Tags"][1]["Key"] == "someotherkey"
|
|
|
|
assert role["Tags"][1]["Value"] == "someothervalue"
|
|
|
|
assert not tags["IsTruncated"]
|
|
|
|
assert not tags.get("Marker")
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Test pagination:
|
2019-10-31 15:44:26 +00:00
|
|
|
tags = conn.list_role_tags(RoleName="my-role", MaxItems=1)
|
|
|
|
assert len(tags["Tags"]) == 1
|
|
|
|
assert tags["IsTruncated"]
|
|
|
|
assert tags["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert tags["Tags"][0]["Value"] == "somevalue"
|
|
|
|
assert tags["Marker"] == "1"
|
|
|
|
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role", Marker=tags["Marker"])
|
|
|
|
assert len(tags["Tags"]) == 1
|
|
|
|
assert tags["Tags"][0]["Key"] == "someotherkey"
|
|
|
|
assert tags["Tags"][0]["Value"] == "someothervalue"
|
|
|
|
assert not tags["IsTruncated"]
|
|
|
|
assert not tags.get("Marker")
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Test updating an existing tag:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role", Tags=[{"Key": "somekey", "Value": "somenewvalue"}]
|
|
|
|
)
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role")
|
|
|
|
assert len(tags["Tags"]) == 2
|
|
|
|
assert tags["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert tags["Tags"][0]["Value"] == "somenewvalue"
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Empty is good:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(RoleName="my-role", Tags=[{"Key": "somekey", "Value": ""}])
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role")
|
|
|
|
assert len(tags["Tags"]) == 2
|
|
|
|
assert tags["Tags"][0]["Key"] == "somekey"
|
|
|
|
assert tags["Tags"][0]["Value"] == ""
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Test creating tags with invalid values:
|
|
|
|
# With more than 50 tags:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
too_many_tags = list(
|
|
|
|
map(lambda x: {"Key": str(x), "Value": str(x)}, range(0, 51))
|
|
|
|
)
|
|
|
|
conn.tag_role(RoleName="my-role", Tags=too_many_tags)
|
|
|
|
assert (
|
|
|
|
"failed to satisfy constraint: Member must have length less than or equal to 50."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a duplicate tag:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[{"Key": "0", "Value": ""}, {"Key": "0", "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Duplicate tag keys found. Please note that Tag keys are case insensitive."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Duplicate tag with different casing:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[{"Key": "a", "Value": ""}, {"Key": "A", "Value": ""}],
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"Duplicate tag keys found. Please note that Tag keys are case insensitive."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a really big key:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(RoleName="my-role", Tags=[{"Key": "0" * 129, "Value": ""}])
|
|
|
|
assert (
|
|
|
|
"Member must have length less than or equal to 128."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a really big value:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(RoleName="my-role", Tags=[{"Key": "0", "Value": "0" * 257}])
|
|
|
|
assert (
|
|
|
|
"Member must have length less than or equal to 256."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With an invalid character:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(RoleName="my-role", Tags=[{"Key": "NOWAY!", "Value": ""}])
|
|
|
|
assert (
|
|
|
|
"Member must satisfy regular expression pattern: [\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]+"
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a role that doesn't exist:
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(RoleName="notarole", Tags=[{"Key": "some", "Value": "value"}])
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_untag_role():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-01-30 02:09:31 +00:00
|
|
|
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="{}")
|
|
|
|
|
|
|
|
# With proper tag values:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[
|
|
|
|
{"Key": "somekey", "Value": "somevalue"},
|
|
|
|
{"Key": "someotherkey", "Value": "someothervalue"},
|
|
|
|
],
|
|
|
|
)
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Remove them:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="my-role", TagKeys=["somekey"])
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role")
|
|
|
|
assert len(tags["Tags"]) == 1
|
|
|
|
assert tags["Tags"][0]["Key"] == "someotherkey"
|
|
|
|
assert tags["Tags"][0]["Value"] == "someothervalue"
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# And again:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="my-role", TagKeys=["someotherkey"])
|
|
|
|
tags = conn.list_role_tags(RoleName="my-role")
|
|
|
|
assert not tags["Tags"]
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# Test removing tags with invalid values:
|
|
|
|
# With more than 50 tags:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="my-role", TagKeys=[str(x) for x in range(0, 51)])
|
|
|
|
assert (
|
|
|
|
"failed to satisfy constraint: Member must have length less than or equal to 50."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
|
|
|
assert "tagKeys" in ce.exception.response["Error"]["Message"]
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a really big key:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="my-role", TagKeys=["0" * 129])
|
|
|
|
assert (
|
|
|
|
"Member must have length less than or equal to 128."
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
|
|
|
assert "tagKeys" in ce.exception.response["Error"]["Message"]
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With an invalid character:
|
|
|
|
with assert_raises(ClientError) as ce:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="my-role", TagKeys=["NOWAY!"])
|
|
|
|
assert (
|
|
|
|
"Member must satisfy regular expression pattern: [\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]+"
|
|
|
|
in ce.exception.response["Error"]["Message"]
|
|
|
|
)
|
|
|
|
assert "tagKeys" in ce.exception.response["Error"]["Message"]
|
2019-01-30 02:09:31 +00:00
|
|
|
|
|
|
|
# With a role that doesn't exist:
|
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.untag_role(RoleName="notarole", TagKeys=["somevalue"])
|
2019-02-17 20:36:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam()
|
|
|
|
def test_update_role_description():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-02-17 20:36:53 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
2019-02-17 20:36:53 +00:00
|
|
|
response = conn.update_role_description(RoleName="my-role", Description="test")
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["Role"]["RoleName"] == "my-role"
|
2019-02-17 20:36:53 +00:00
|
|
|
|
2019-08-21 19:24:23 +00:00
|
|
|
|
2019-02-17 20:36:53 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_update_role():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-02-17 20:36:53 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
2019-02-17 20:36:53 +00:00
|
|
|
response = conn.update_role_description(RoleName="my-role", Description="test")
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["Role"]["RoleName"] == "my-role"
|
2019-02-17 22:04:28 +00:00
|
|
|
|
2019-08-21 19:24:23 +00:00
|
|
|
|
2019-02-17 23:12:27 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_update_role():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2019-02-17 23:12:27 +00:00
|
|
|
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
conn.delete_role(RoleName="my-role")
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
2019-02-17 23:12:27 +00:00
|
|
|
response = conn.update_role(RoleName="my-role", Description="test")
|
2019-02-18 03:37:33 +00:00
|
|
|
assert len(response.keys()) == 1
|
2019-02-17 23:12:27 +00:00
|
|
|
|
2019-02-19 03:20:29 +00:00
|
|
|
|
2019-02-17 22:04:28 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_list_entities_for_policy():
|
2019-10-31 15:44:26 +00:00
|
|
|
test_policy = json.dumps(
|
|
|
|
{
|
|
|
|
"Version": "2012-10-17",
|
|
|
|
"Statement": [
|
|
|
|
{"Action": "s3:ListBucket", "Resource": "*", "Effect": "Allow"}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
)
|
2019-02-19 03:20:29 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/"
|
|
|
|
)
|
|
|
|
conn.create_user(Path="/", UserName="testUser")
|
|
|
|
conn.create_group(Path="/", GroupName="testGroup")
|
2019-02-19 03:20:29 +00:00
|
|
|
conn.create_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyName="testPolicy",
|
|
|
|
Path="/",
|
2019-02-19 03:20:29 +00:00
|
|
|
PolicyDocument=test_policy,
|
2019-10-31 15:44:26 +00:00
|
|
|
Description="Test Policy",
|
2019-02-19 03:20:29 +00:00
|
|
|
)
|
2019-02-17 22:04:28 +00:00
|
|
|
|
2019-02-19 03:20:29 +00:00
|
|
|
# Attach things to the user and group:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.put_user_policy(
|
|
|
|
UserName="testUser", PolicyName="testPolicy", PolicyDocument=test_policy
|
|
|
|
)
|
|
|
|
conn.put_group_policy(
|
|
|
|
GroupName="testGroup", PolicyName="testPolicy", PolicyDocument=test_policy
|
|
|
|
)
|
2019-02-17 22:04:28 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.attach_user_policy(
|
|
|
|
UserName="testUser", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
|
|
|
conn.attach_group_policy(
|
|
|
|
GroupName="testGroup", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
2019-02-17 22:04:28 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.add_user_to_group(UserName="testUser", GroupName="testGroup")
|
2019-02-19 03:20:29 +00:00
|
|
|
|
|
|
|
# Add things to the role:
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_instance_profile(InstanceProfileName="ipn")
|
|
|
|
conn.add_role_to_instance_profile(InstanceProfileName="ipn", RoleName="my-role")
|
|
|
|
conn.tag_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
Tags=[
|
|
|
|
{"Key": "somekey", "Value": "somevalue"},
|
|
|
|
{"Key": "someotherkey", "Value": "someothervalue"},
|
|
|
|
],
|
|
|
|
)
|
|
|
|
conn.put_role_policy(
|
|
|
|
RoleName="my-role", PolicyName="test-policy", PolicyDocument=test_policy
|
|
|
|
)
|
|
|
|
conn.attach_role_policy(
|
|
|
|
RoleName="my-role", PolicyArn="arn:aws:iam::123456789012:policy/testPolicy"
|
|
|
|
)
|
2019-02-19 03:20:29 +00:00
|
|
|
|
|
|
|
response = conn.list_entities_for_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/testPolicy", EntityFilter="Role"
|
2019-02-19 03:20:29 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["PolicyRoles"] == [{"RoleName": "my-role"}]
|
2019-02-17 22:04:28 +00:00
|
|
|
|
|
|
|
response = conn.list_entities_for_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/testPolicy", EntityFilter="User"
|
2019-02-17 22:04:28 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["PolicyUsers"] == [{"UserName": "testUser"}]
|
2019-02-19 03:20:29 +00:00
|
|
|
|
|
|
|
response = conn.list_entities_for_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/testPolicy", EntityFilter="Group"
|
2019-02-19 03:20:29 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["PolicyGroups"] == [{"GroupName": "testGroup"}]
|
2019-02-19 03:20:29 +00:00
|
|
|
|
|
|
|
response = conn.list_entities_for_policy(
|
2019-10-31 15:44:26 +00:00
|
|
|
PolicyArn="arn:aws:iam::123456789012:policy/testPolicy",
|
|
|
|
EntityFilter="LocalManagedPolicy",
|
2019-02-19 03:20:29 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
assert response["PolicyGroups"] == [{"GroupName": "testGroup"}]
|
|
|
|
assert response["PolicyUsers"] == [{"UserName": "testUser"}]
|
|
|
|
assert response["PolicyRoles"] == [{"RoleName": "my-role"}]
|
2019-02-19 03:20:29 +00:00
|
|
|
|
|
|
|
|
2019-04-21 23:23:00 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_create_role_no_path():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
resp = conn.create_role(
|
|
|
|
RoleName="my-role", AssumeRolePolicyDocument="some policy", Description="test"
|
|
|
|
)
|
|
|
|
resp.get("Role").get("Arn").should.equal("arn:aws:iam::123456789012:role/my-role")
|
|
|
|
resp.get("Role").should_not.have.key("PermissionsBoundary")
|
|
|
|
resp.get("Role").get("Description").should.equal("test")
|
2019-08-21 19:24:23 +00:00
|
|
|
|
2019-05-21 16:44:06 +00:00
|
|
|
|
|
|
|
@mock_iam()
|
|
|
|
def test_create_role_with_permissions_boundary():
|
2019-10-31 15:44:26 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
boundary = "arn:aws:iam::123456789012:policy/boundary"
|
|
|
|
resp = conn.create_role(
|
|
|
|
RoleName="my-role",
|
|
|
|
AssumeRolePolicyDocument="some policy",
|
|
|
|
Description="test",
|
|
|
|
PermissionsBoundary=boundary,
|
|
|
|
)
|
2019-05-21 16:44:06 +00:00
|
|
|
expected = {
|
2019-10-31 15:44:26 +00:00
|
|
|
"PermissionsBoundaryType": "PermissionsBoundaryPolicy",
|
|
|
|
"PermissionsBoundaryArn": boundary,
|
2019-05-21 16:44:06 +00:00
|
|
|
}
|
2019-10-31 15:44:26 +00:00
|
|
|
resp.get("Role").get("PermissionsBoundary").should.equal(expected)
|
|
|
|
resp.get("Role").get("Description").should.equal("test")
|
2019-05-21 16:44:06 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
invalid_boundary_arn = "arn:aws:iam::123456789:not_a_boundary"
|
2019-05-21 16:44:06 +00:00
|
|
|
with assert_raises(ClientError):
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.create_role(
|
|
|
|
RoleName="bad-boundary",
|
|
|
|
AssumeRolePolicyDocument="some policy",
|
|
|
|
Description="test",
|
|
|
|
PermissionsBoundary=invalid_boundary_arn,
|
|
|
|
)
|
2019-02-19 03:20:29 +00:00
|
|
|
|
2019-05-21 16:44:06 +00:00
|
|
|
# Ensure the PermissionsBoundary is included in role listing as well
|
2019-10-31 15:44:26 +00:00
|
|
|
conn.list_roles().get("Roles")[0].get("PermissionsBoundary").should.equal(expected)
|
2019-10-18 15:29:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_create_open_id_connect_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-18 15:29:15 +00:00
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com",
|
|
|
|
ThumbprintList=[], # even it is required to provide at least one thumbprint, AWS accepts an empty list
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["OpenIDConnectProviderArn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:oidc-provider/example.com"
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org", ThumbprintList=["b" * 40], ClientIDList=["b"]
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["OpenIDConnectProviderArn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:oidc-provider/example.org"
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org/oidc", ThumbprintList=[]
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["OpenIDConnectProviderArn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:oidc-provider/example.org/oidc"
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org/oidc-query?test=true", ThumbprintList=[]
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["OpenIDConnectProviderArn"].should.equal(
|
|
|
|
"arn:aws:iam::123456789012:oidc-provider/example.org/oidc-query"
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_create_open_id_connect_provider_errors():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
|
|
|
client.create_open_id_connect_provider(Url="https://example.com", ThumbprintList=[])
|
2019-10-18 15:29:15 +00:00
|
|
|
|
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com", ThumbprintList=[]
|
|
|
|
).should.throw(ClientError, "Unknown")
|
2019-10-18 15:29:15 +00:00
|
|
|
|
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="example.org", ThumbprintList=[]
|
|
|
|
).should.throw(ClientError, "Invalid Open ID Connect Provider URL")
|
2019-10-18 15:29:15 +00:00
|
|
|
|
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="example", ThumbprintList=[]
|
|
|
|
).should.throw(ClientError, "Invalid Open ID Connect Provider URL")
|
2019-10-18 15:29:15 +00:00
|
|
|
|
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org",
|
|
|
|
ThumbprintList=["a" * 40, "b" * 40, "c" * 40, "d" * 40, "e" * 40, "f" * 40],
|
|
|
|
).should.throw(ClientError, "Thumbprint list must contain fewer than 5 entries.")
|
2019-10-18 15:29:15 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
too_many_client_ids = ["{}".format(i) for i in range(101)]
|
2019-10-18 15:29:15 +00:00
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org", ThumbprintList=[], ClientIDList=too_many_client_ids
|
2019-10-18 15:29:15 +00:00
|
|
|
).should.throw(
|
2019-10-31 15:44:26 +00:00
|
|
|
ClientError, "Cannot exceed quota for ClientIdsPerOpenIdConnectProvider: 100"
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
too_long_url = "b" * 256
|
|
|
|
too_long_thumbprint = "b" * 41
|
|
|
|
too_long_client_id = "b" * 256
|
2019-10-18 15:29:15 +00:00
|
|
|
client.create_open_id_connect_provider.when.called_with(
|
|
|
|
Url=too_long_url,
|
2019-10-31 15:44:26 +00:00
|
|
|
ThumbprintList=[too_long_thumbprint],
|
|
|
|
ClientIDList=[too_long_client_id],
|
2019-10-18 15:29:15 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"3 validation errors detected: "
|
2019-10-18 15:29:15 +00:00
|
|
|
'Value "{0}" at "clientIDList" failed to satisfy constraint: '
|
2019-10-31 15:44:26 +00:00
|
|
|
"Member must satisfy constraint: "
|
|
|
|
"[Member must have length less than or equal to 255, "
|
|
|
|
"Member must have length greater than or equal to 1]; "
|
2019-10-18 15:29:15 +00:00
|
|
|
'Value "{1}" at "thumbprintList" failed to satisfy constraint: '
|
2019-10-31 15:44:26 +00:00
|
|
|
"Member must satisfy constraint: "
|
|
|
|
"[Member must have length less than or equal to 40, "
|
|
|
|
"Member must have length greater than or equal to 40]; "
|
2019-10-18 15:29:15 +00:00
|
|
|
'Value "{2}" at "url" failed to satisfy constraint: '
|
2019-10-31 15:44:26 +00:00
|
|
|
"Member must have length less than or equal to 255".format(
|
|
|
|
[too_long_client_id], [too_long_thumbprint], too_long_url
|
|
|
|
),
|
2019-10-18 15:29:15 +00:00
|
|
|
)
|
2019-10-18 18:37:35 +00:00
|
|
|
|
|
|
|
|
2019-10-18 18:51:22 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_delete_open_id_connect_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-18 18:51:22 +00:00
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com", ThumbprintList=[]
|
2019-10-18 18:51:22 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn = response["OpenIDConnectProviderArn"]
|
2019-10-18 18:51:22 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
client.delete_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn)
|
2019-10-18 18:51:22 +00:00
|
|
|
|
|
|
|
client.get_open_id_connect_provider.when.called_with(
|
|
|
|
OpenIDConnectProviderArn=open_id_arn
|
|
|
|
).should.throw(
|
2019-10-31 15:44:26 +00:00
|
|
|
ClientError, "OpenIDConnect Provider not found for arn {}".format(open_id_arn)
|
2019-10-18 18:51:22 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# deleting a non existing provider should be successful
|
2019-10-31 15:44:26 +00:00
|
|
|
client.delete_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn)
|
2019-10-18 18:51:22 +00:00
|
|
|
|
|
|
|
|
2019-10-18 18:37:35 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_open_id_connect_provider():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-18 18:37:35 +00:00
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com", ThumbprintList=["b" * 40], ClientIDList=["b"]
|
2019-10-18 18:37:35 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn = response["OpenIDConnectProviderArn"]
|
2019-10-18 18:37:35 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response = client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn)
|
2019-10-18 18:37:35 +00:00
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
response["Url"].should.equal("example.com")
|
|
|
|
response["ThumbprintList"].should.equal(["b" * 40])
|
|
|
|
response["ClientIDList"].should.equal(["b"])
|
|
|
|
response.should.have.key("CreateDate").should.be.a(datetime)
|
2019-10-18 18:37:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_open_id_connect_provider_errors():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-18 18:37:35 +00:00
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com", ThumbprintList=["b" * 40], ClientIDList=["b"]
|
2019-10-18 18:37:35 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn = response["OpenIDConnectProviderArn"]
|
2019-10-18 18:37:35 +00:00
|
|
|
|
|
|
|
client.get_open_id_connect_provider.when.called_with(
|
2019-10-31 15:44:26 +00:00
|
|
|
OpenIDConnectProviderArn=open_id_arn + "-not-existing"
|
2019-10-18 18:37:35 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
2019-10-31 15:44:26 +00:00
|
|
|
"OpenIDConnect Provider not found for arn {}".format(
|
|
|
|
open_id_arn + "-not-existing"
|
|
|
|
),
|
2019-10-18 18:37:35 +00:00
|
|
|
)
|
2019-10-18 19:12:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_list_open_id_connect_providers():
|
2019-10-31 15:44:26 +00:00
|
|
|
client = boto3.client("iam", region_name="us-east-1")
|
2019-10-18 19:12:44 +00:00
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="https://example.com", ThumbprintList=[]
|
2019-10-18 19:12:44 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn_1 = response["OpenIDConnectProviderArn"]
|
2019-10-18 19:12:44 +00:00
|
|
|
|
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org", ThumbprintList=["b" * 40], ClientIDList=["b"]
|
2019-10-18 19:12:44 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn_2 = response["OpenIDConnectProviderArn"]
|
2019-10-18 19:12:44 +00:00
|
|
|
|
|
|
|
response = client.create_open_id_connect_provider(
|
2019-10-31 15:44:26 +00:00
|
|
|
Url="http://example.org/oidc", ThumbprintList=[]
|
2019-10-18 19:12:44 +00:00
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
open_id_arn_3 = response["OpenIDConnectProviderArn"]
|
2019-10-18 19:12:44 +00:00
|
|
|
|
|
|
|
response = client.list_open_id_connect_providers()
|
|
|
|
|
2019-10-31 15:44:26 +00:00
|
|
|
sorted(response["OpenIDConnectProviderList"], key=lambda i: i["Arn"]).should.equal(
|
|
|
|
[{"Arn": open_id_arn_1}, {"Arn": open_id_arn_2}, {"Arn": open_id_arn_3}]
|
2019-10-19 12:23:35 +00:00
|
|
|
)
|
2019-10-28 22:16:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_account_password_policy():
|
|
|
|
client = boto3.client('iam', region_name='us-east-1')
|
2019-10-28 22:50:17 +00:00
|
|
|
|
2019-10-28 22:16:19 +00:00
|
|
|
client.update_account_password_policy()
|
|
|
|
|
2019-10-28 22:50:17 +00:00
|
|
|
response = client.get_account_password_policy()
|
|
|
|
response['PasswordPolicy'].should.equal({
|
|
|
|
'AllowUsersToChangePassword': False,
|
|
|
|
'ExpirePasswords': False,
|
|
|
|
'MinimumPasswordLength': 6,
|
|
|
|
'RequireLowercaseCharacters': False,
|
|
|
|
'RequireNumbers': False,
|
|
|
|
'RequireSymbols': False,
|
|
|
|
'RequireUppercaseCharacters': False
|
|
|
|
})
|
|
|
|
|
2019-10-28 22:16:19 +00:00
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_account_password_policy_errors():
|
|
|
|
client = boto3.client('iam', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.update_account_password_policy.when.called_with(
|
2019-10-28 22:50:17 +00:00
|
|
|
MaxPasswordAge=1096,
|
|
|
|
MinimumPasswordLength=129,
|
|
|
|
PasswordReusePrevention=25
|
2019-10-28 22:16:19 +00:00
|
|
|
).should.throw(
|
|
|
|
ClientError,
|
|
|
|
'3 validation errors detected: '
|
|
|
|
'Value "129" at "minimumPasswordLength" failed to satisfy constraint: '
|
|
|
|
'Member must have value less than or equal to 128; '
|
|
|
|
'Value "25" at "passwordReusePrevention" failed to satisfy constraint: '
|
|
|
|
'Member must have value less than or equal to 24; '
|
|
|
|
'Value "1096" at "maxPasswordAge" failed to satisfy constraint: '
|
|
|
|
'Member must have value less than or equal to 1095'
|
|
|
|
)
|
2019-10-28 22:50:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_account_password_policy():
|
|
|
|
client = boto3.client('iam', region_name='us-east-1')
|
|
|
|
client.update_account_password_policy(
|
|
|
|
AllowUsersToChangePassword=True,
|
|
|
|
HardExpiry=True,
|
|
|
|
MaxPasswordAge=60,
|
|
|
|
MinimumPasswordLength=10,
|
|
|
|
PasswordReusePrevention=3,
|
|
|
|
RequireLowercaseCharacters=True,
|
|
|
|
RequireNumbers=True,
|
|
|
|
RequireSymbols=True,
|
|
|
|
RequireUppercaseCharacters=True
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.get_account_password_policy()
|
|
|
|
|
|
|
|
response['PasswordPolicy'].should.equal({
|
|
|
|
'AllowUsersToChangePassword': True,
|
|
|
|
'ExpirePasswords': True,
|
|
|
|
'HardExpiry': True,
|
|
|
|
'MaxPasswordAge': 60,
|
|
|
|
'MinimumPasswordLength': 10,
|
|
|
|
'PasswordReusePrevention': 3,
|
|
|
|
'RequireLowercaseCharacters': True,
|
|
|
|
'RequireNumbers': True,
|
|
|
|
'RequireSymbols': True,
|
|
|
|
'RequireUppercaseCharacters': True
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_account_password_policy_errors():
|
|
|
|
client = boto3.client('iam', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.get_account_password_policy.when.called_with().should.throw(
|
|
|
|
ClientError,
|
|
|
|
'The Password Policy with domain name 123456789012 cannot be found.'
|
|
|
|
)
|