2018-10-17 00:14:23 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
2017-03-05 03:56:36 +00:00
|
|
|
import boto3
|
2021-10-18 19:44:29 +00:00
|
|
|
import sure # noqa # pylint: disable=unused-import
|
2021-09-22 19:42:42 +00:00
|
|
|
import json
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2020-10-06 05:54:49 +00:00
|
|
|
import pytest
|
2019-11-08 09:19:45 +00:00
|
|
|
from botocore.exceptions import ClientError
|
2022-01-18 15:18:57 +00:00
|
|
|
from moto import mock_iam
|
2022-08-13 09:49:43 +00:00
|
|
|
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
2015-04-30 23:32:53 +00:00
|
|
|
|
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"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2015-04-30 23:32:53 +00:00
|
|
|
|
2021-09-22 19:42:42 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_create_group_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("Group my-group already exists")
|
|
|
|
err["Message"].should.equal(None)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_group_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
created = conn.create_group(GroupName="my-group")["Group"]
|
|
|
|
created["Path"].should.equal("/")
|
|
|
|
created["GroupName"].should.equal("my-group")
|
|
|
|
created.should.have.key("GroupId")
|
|
|
|
created["Arn"].should.equal("arn:aws:iam::{}:group/my-group".format(ACCOUNT_ID))
|
|
|
|
created["CreateDate"].should.be.a(datetime)
|
|
|
|
|
|
|
|
retrieved = conn.get_group(GroupName="my-group")["Group"]
|
|
|
|
retrieved.should.equal(created)
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.get_group(GroupName="not-group")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("Group not-group not found")
|
|
|
|
|
|
|
|
|
2018-10-17 00:14:23 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_get_group_current():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
result = conn.get_group(GroupName="my-group")
|
|
|
|
|
|
|
|
assert result["Group"]["Path"] == "/"
|
|
|
|
assert result["Group"]["GroupName"] == "my-group"
|
|
|
|
assert isinstance(result["Group"]["CreateDate"], datetime)
|
|
|
|
assert result["Group"]["GroupId"]
|
2019-12-16 00:22:26 +00:00
|
|
|
assert result["Group"]["Arn"] == "arn:aws:iam::{}:group/my-group".format(ACCOUNT_ID)
|
2018-10-17 00:14:23 +00:00
|
|
|
assert not result["Users"]
|
|
|
|
|
|
|
|
# Make a group with a different path:
|
|
|
|
other_group = conn.create_group(GroupName="my-other-group", Path="some/location")
|
|
|
|
assert other_group["Group"]["Path"] == "some/location"
|
2019-12-17 02:25:20 +00:00
|
|
|
assert other_group["Group"][
|
|
|
|
"Arn"
|
|
|
|
] == "arn:aws:iam::{}:group/some/location/my-other-group".format(ACCOUNT_ID)
|
2018-10-17 00:14:23 +00:00
|
|
|
|
|
|
|
|
2021-09-22 19:42:42 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_all_groups_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group1")
|
|
|
|
conn.create_group(GroupName="my-group2")
|
|
|
|
groups = conn.list_groups()["Groups"]
|
|
|
|
groups.should.have.length_of(2)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_add_unknown_user_to_group():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.add_user_to_group(GroupName="my-group", UserName="my-user")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("The user with name my-user cannot be found.")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_add_user_to_unknown_group():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.add_user_to_group(GroupName="my-group", UserName="my-user")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("Group my-group not found")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_add_user_to_group_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.add_user_to_group(GroupName="my-group", UserName="my-user")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_remove_user_from_unknown_group():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.remove_user_from_group(GroupName="my-group", UserName="my-user")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("Group my-group not found")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_remove_nonattached_user_from_group():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.remove_user_from_group(GroupName="my-group", UserName="my-user")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("User my-user not in group my-group")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_remove_user_from_group_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.add_user_to_group(GroupName="my-group", UserName="my-user")
|
|
|
|
conn.remove_user_from_group(GroupName="my-group", UserName="my-user")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_get_groups_for_user_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group1")
|
|
|
|
conn.create_group(GroupName="my-group2")
|
|
|
|
conn.create_group(GroupName="other-group")
|
|
|
|
conn.create_user(UserName="my-user")
|
|
|
|
conn.add_user_to_group(GroupName="my-group1", UserName="my-user")
|
|
|
|
conn.add_user_to_group(GroupName="my-group2", UserName="my-user")
|
|
|
|
|
|
|
|
groups = conn.list_groups_for_user(UserName="my-user")["Groups"]
|
|
|
|
groups.should.have.length_of(2)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_put_group_policy_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
conn.put_group_policy(
|
|
|
|
GroupName="my-group", PolicyName="my-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2017-10-01 22:02:00 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_attach_group_policies():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
conn.list_attached_group_policies(GroupName="my-group")[
|
|
|
|
"AttachedPolicies"
|
|
|
|
].should.be.empty
|
|
|
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforEC2Role"
|
|
|
|
conn.list_attached_group_policies(GroupName="my-group")[
|
|
|
|
"AttachedPolicies"
|
|
|
|
].should.be.empty
|
|
|
|
conn.attach_group_policy(GroupName="my-group", PolicyArn=policy_arn)
|
|
|
|
conn.list_attached_group_policies(GroupName="my-group")[
|
|
|
|
"AttachedPolicies"
|
|
|
|
].should.equal(
|
|
|
|
[{"PolicyName": "AmazonElasticMapReduceforEC2Role", "PolicyArn": policy_arn}]
|
|
|
|
)
|
2019-10-31 15:44:26 +00:00
|
|
|
|
2017-10-01 22:04:59 +00:00
|
|
|
conn.detach_group_policy(GroupName="my-group", PolicyArn=policy_arn)
|
|
|
|
conn.list_attached_group_policies(GroupName="my-group")[
|
|
|
|
"AttachedPolicies"
|
|
|
|
].should.be.empty
|
|
|
|
|
2017-10-01 22:02:00 +00:00
|
|
|
|
2021-09-22 19:42:42 +00:00
|
|
|
@mock_iam
|
|
|
|
def test_get_group_policy_boto3():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
with pytest.raises(ClientError) as ex:
|
|
|
|
conn.get_group_policy(GroupName="my-group", PolicyName="my-policy")
|
|
|
|
err = ex.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("Policy my-policy not found")
|
|
|
|
|
|
|
|
conn.put_group_policy(
|
|
|
|
GroupName="my-group", PolicyName="my-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
|
|
|
policy = conn.get_group_policy(GroupName="my-group", PolicyName="my-policy")
|
|
|
|
policy["GroupName"].should.equal("my-group")
|
|
|
|
policy["PolicyName"].should.equal("my-policy")
|
|
|
|
policy["PolicyDocument"].should.equal(json.loads(MOCK_POLICY))
|
|
|
|
|
|
|
|
|
2017-03-05 03:56:36 +00:00
|
|
|
@mock_iam()
|
|
|
|
def test_list_group_policies():
|
2017-03-05 15:09:19 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2017-03-05 03:56:36 +00:00
|
|
|
conn.create_group(GroupName="my-group")
|
2017-10-01 22:02:06 +00:00
|
|
|
conn.list_group_policies(GroupName="my-group")["PolicyNames"].should.be.empty
|
2019-06-30 15:57:50 +00:00
|
|
|
conn.put_group_policy(
|
|
|
|
GroupName="my-group", PolicyName="my-policy", PolicyDocument=MOCK_POLICY
|
|
|
|
)
|
2017-10-01 22:02:06 +00:00
|
|
|
conn.list_group_policies(GroupName="my-group")["PolicyNames"].should.equal(
|
|
|
|
["my-policy"]
|
|
|
|
)
|
2019-04-20 21:50:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_delete_group():
|
2019-11-08 09:19:45 +00:00
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
2019-04-20 21:50:28 +00:00
|
|
|
groups = conn.list_groups()
|
2019-11-08 09:19:45 +00:00
|
|
|
assert groups["Groups"][0]["GroupName"] == "my-group"
|
|
|
|
assert len(groups["Groups"]) == 1
|
|
|
|
conn.delete_group(GroupName="my-group")
|
|
|
|
conn.list_groups()["Groups"].should.be.empty
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_delete_unknown_group():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
2020-10-06 06:04:09 +00:00
|
|
|
with pytest.raises(ClientError) as err:
|
2019-11-08 09:19:45 +00:00
|
|
|
conn.delete_group(GroupName="unknown-group")
|
2020-10-06 06:04:09 +00:00
|
|
|
err.value.response["Error"]["Code"].should.equal("NoSuchEntity")
|
|
|
|
err.value.response["Error"]["Message"].should.equal(
|
2019-11-08 09:19:45 +00:00
|
|
|
"The group with name unknown-group cannot be found."
|
|
|
|
)
|
2021-11-29 20:35:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_group_name():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group")
|
|
|
|
initial_group = conn.get_group(GroupName="my-group")["Group"]
|
|
|
|
|
|
|
|
conn.update_group(GroupName="my-group", NewGroupName="new-group")
|
|
|
|
|
|
|
|
# The old group-name should no longer exist
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
conn.get_group(GroupName="my-group")
|
|
|
|
exc.value.response["Error"]["Code"].should.equal("NoSuchEntity")
|
|
|
|
|
|
|
|
result = conn.get_group(GroupName="new-group")["Group"]
|
|
|
|
result["Path"].should.equal("/")
|
|
|
|
result["GroupName"].should.equal("new-group")
|
|
|
|
result["GroupId"].should.equal(initial_group["GroupId"])
|
|
|
|
result["Arn"].should.match(":group/new-group")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_group_name_that_has_a_path():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group", Path="/path")
|
|
|
|
|
|
|
|
conn.update_group(GroupName="my-group", NewGroupName="new-group")
|
|
|
|
|
|
|
|
# Verify the path hasn't changed
|
|
|
|
new = conn.get_group(GroupName="new-group")["Group"]
|
|
|
|
new["Path"].should.equal("/path")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_group_path():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="my-group", Path="/path")
|
|
|
|
|
|
|
|
conn.update_group(
|
|
|
|
GroupName="my-group", NewGroupName="new-group", NewPath="/new-path"
|
|
|
|
)
|
|
|
|
|
|
|
|
# Verify the path has changed
|
|
|
|
new = conn.get_group(GroupName="new-group")["Group"]
|
|
|
|
new["Path"].should.equal("/new-path")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_group_that_does_not_exist():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
conn.update_group(GroupName="nonexisting", NewGroupName="..")
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
err["Code"].should.equal("NoSuchEntity")
|
|
|
|
err["Message"].should.equal("The group with name nonexisting cannot be found.")
|
|
|
|
|
|
|
|
|
|
|
|
@mock_iam
|
|
|
|
def test_update_group_with_existing_name():
|
|
|
|
conn = boto3.client("iam", region_name="us-east-1")
|
|
|
|
conn.create_group(GroupName="existing1")
|
|
|
|
conn.create_group(GroupName="existing2")
|
|
|
|
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
|
|
conn.update_group(GroupName="existing1", NewGroupName="existing2")
|
|
|
|
err = exc.value.response["Error"]
|
|
|
|
err["Code"].should.equal("Conflict")
|
|
|
|
err["Message"].should.equal("Group existing2 already exists")
|