second first commit
This commit is contained in:
@@ -0,0 +1,410 @@
|
||||
"""IAM integration tests."""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
TRUST_POLICY = json.dumps(
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {"Service": "lambda.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole",
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
POLICY_DOC = json.dumps(
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{"Effect": "Allow", "Action": "s3:GetObject", "Resource": "*"}],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class TestIAMUser:
|
||||
"""Test IAM user operations."""
|
||||
|
||||
def test_create_user(self, iam_client, unique_name):
|
||||
"""Test CreateUser creates a user."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
try:
|
||||
response = iam_client.create_user(UserName=user_name, Path="/")
|
||||
assert response["User"]["UserName"] == user_name
|
||||
assert response["User"]["Arn"].endswith(user_name)
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_get_user(self, iam_client, unique_name):
|
||||
"""Test GetUser returns user details."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
try:
|
||||
response = iam_client.get_user(UserName=user_name)
|
||||
assert response["User"]["UserName"] == user_name
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_list_users(self, iam_client, unique_name):
|
||||
"""Test ListUsers includes created user."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
try:
|
||||
response = iam_client.list_users()
|
||||
assert any(u["UserName"] == user_name for u in response["Users"])
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_get_user_not_found(self, iam_client):
|
||||
"""Test GetUser returns 404 for non-existent user."""
|
||||
with pytest.raises(ClientError) as exc_info:
|
||||
iam_client.get_user(UserName="nonexistent-user-pytest-xyz")
|
||||
assert exc_info.value.response["ResponseMetadata"]["HTTPStatusCode"] == 404
|
||||
|
||||
|
||||
class TestIAMUserTags:
|
||||
"""Test IAM user tagging operations."""
|
||||
|
||||
def test_tag_user(self, iam_client, unique_name):
|
||||
"""Test TagUser adds tags to user."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
try:
|
||||
iam_client.tag_user(
|
||||
UserName=user_name, Tags=[{"Key": "env", "Value": "sdk-test"}]
|
||||
)
|
||||
# If no exception, test passes
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_list_user_tags(self, iam_client, unique_name):
|
||||
"""Test ListUserTags returns user tags."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.tag_user(
|
||||
UserName=user_name, Tags=[{"Key": "env", "Value": "sdk-test"}]
|
||||
)
|
||||
try:
|
||||
response = iam_client.list_user_tags(UserName=user_name)
|
||||
assert any(t["Key"] == "env" for t in response["Tags"])
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_untag_user(self, iam_client, unique_name):
|
||||
"""Test UntagUser removes tags from user."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.tag_user(
|
||||
UserName=user_name, Tags=[{"Key": "env", "Value": "sdk-test"}]
|
||||
)
|
||||
try:
|
||||
iam_client.untag_user(UserName=user_name, TagKeys=["env"])
|
||||
# If no exception, test passes
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
|
||||
class TestIAMAccessKey:
|
||||
"""Test IAM access key operations."""
|
||||
|
||||
def test_create_access_key(self, iam_client, unique_name):
|
||||
"""Test CreateAccessKey creates access key."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
try:
|
||||
response = iam_client.create_access_key(UserName=user_name)
|
||||
key_id = response["AccessKey"]["AccessKeyId"]
|
||||
assert key_id.startswith("AKIA")
|
||||
assert response["AccessKey"]["Status"] == "Active"
|
||||
|
||||
# Cleanup
|
||||
iam_client.delete_access_key(UserName=user_name, AccessKeyId=key_id)
|
||||
finally:
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_list_access_keys(self, iam_client, unique_name):
|
||||
"""Test ListAccessKeys returns access keys."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
response = iam_client.create_access_key(UserName=user_name)
|
||||
key_id = response["AccessKey"]["AccessKeyId"]
|
||||
|
||||
try:
|
||||
response = iam_client.list_access_keys(UserName=user_name)
|
||||
assert len(response["AccessKeyMetadata"]) > 0
|
||||
finally:
|
||||
iam_client.delete_access_key(UserName=user_name, AccessKeyId=key_id)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_update_access_key(self, iam_client, unique_name):
|
||||
"""Test UpdateAccessKey changes key status."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
response = iam_client.create_access_key(UserName=user_name)
|
||||
key_id = response["AccessKey"]["AccessKeyId"]
|
||||
|
||||
try:
|
||||
iam_client.update_access_key(
|
||||
UserName=user_name, AccessKeyId=key_id, Status="Inactive"
|
||||
)
|
||||
# If no exception, test passes
|
||||
finally:
|
||||
iam_client.delete_access_key(UserName=user_name, AccessKeyId=key_id)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
|
||||
class TestIAMGroup:
|
||||
"""Test IAM group operations."""
|
||||
|
||||
def test_create_group(self, iam_client, unique_name):
|
||||
"""Test CreateGroup creates a group."""
|
||||
group_name = f"pytest-group-{unique_name}"
|
||||
|
||||
try:
|
||||
response = iam_client.create_group(GroupName=group_name)
|
||||
assert response["Group"]["GroupName"] == group_name
|
||||
finally:
|
||||
iam_client.delete_group(GroupName=group_name)
|
||||
|
||||
def test_add_user_to_group(self, iam_client, unique_name):
|
||||
"""Test AddUserToGroup adds user to group."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
group_name = f"pytest-group-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.create_group(GroupName=group_name)
|
||||
|
||||
try:
|
||||
iam_client.add_user_to_group(GroupName=group_name, UserName=user_name)
|
||||
# If no exception, test passes
|
||||
finally:
|
||||
iam_client.remove_user_from_group(GroupName=group_name, UserName=user_name)
|
||||
iam_client.delete_group(GroupName=group_name)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_get_group(self, iam_client, unique_name):
|
||||
"""Test GetGroup returns group with users."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
group_name = f"pytest-group-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.create_group(GroupName=group_name)
|
||||
iam_client.add_user_to_group(GroupName=group_name, UserName=user_name)
|
||||
|
||||
try:
|
||||
response = iam_client.get_group(GroupName=group_name)
|
||||
assert any(u["UserName"] == user_name for u in response["Users"])
|
||||
finally:
|
||||
iam_client.remove_user_from_group(GroupName=group_name, UserName=user_name)
|
||||
iam_client.delete_group(GroupName=group_name)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
def test_list_groups_for_user(self, iam_client, unique_name):
|
||||
"""Test ListGroupsForUser returns user's groups."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
group_name = f"pytest-group-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
iam_client.create_group(GroupName=group_name)
|
||||
iam_client.add_user_to_group(GroupName=group_name, UserName=user_name)
|
||||
|
||||
try:
|
||||
response = iam_client.list_groups_for_user(UserName=user_name)
|
||||
assert any(g["GroupName"] == group_name for g in response["Groups"])
|
||||
finally:
|
||||
iam_client.remove_user_from_group(GroupName=group_name, UserName=user_name)
|
||||
iam_client.delete_group(GroupName=group_name)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
|
||||
|
||||
class TestIAMRole:
|
||||
"""Test IAM role operations."""
|
||||
|
||||
def test_create_role(self, iam_client, unique_name):
|
||||
"""Test CreateRole creates a role."""
|
||||
role_name = f"pytest-role-{unique_name}"
|
||||
|
||||
try:
|
||||
response = iam_client.create_role(
|
||||
RoleName=role_name,
|
||||
AssumeRolePolicyDocument=TRUST_POLICY,
|
||||
Description="pytest test role",
|
||||
)
|
||||
assert response["Role"]["RoleName"] == role_name
|
||||
assert role_name in response["Role"]["Arn"]
|
||||
finally:
|
||||
iam_client.delete_role(RoleName=role_name)
|
||||
|
||||
def test_get_role(self, iam_client, unique_name):
|
||||
"""Test GetRole returns role details."""
|
||||
role_name = f"pytest-role-{unique_name}"
|
||||
|
||||
iam_client.create_role(
|
||||
RoleName=role_name, AssumeRolePolicyDocument=TRUST_POLICY
|
||||
)
|
||||
try:
|
||||
response = iam_client.get_role(RoleName=role_name)
|
||||
assert response["Role"]["RoleName"] == role_name
|
||||
finally:
|
||||
iam_client.delete_role(RoleName=role_name)
|
||||
|
||||
def test_list_roles(self, iam_client, unique_name):
|
||||
"""Test ListRoles includes created role."""
|
||||
role_name = f"pytest-role-{unique_name}"
|
||||
|
||||
iam_client.create_role(
|
||||
RoleName=role_name, AssumeRolePolicyDocument=TRUST_POLICY
|
||||
)
|
||||
try:
|
||||
response = iam_client.list_roles()
|
||||
assert any(r["RoleName"] == role_name for r in response["Roles"])
|
||||
finally:
|
||||
iam_client.delete_role(RoleName=role_name)
|
||||
|
||||
|
||||
class TestIAMPolicy:
|
||||
"""Test IAM policy operations."""
|
||||
|
||||
def test_create_policy(self, iam_client, unique_name):
|
||||
"""Test CreatePolicy creates a policy."""
|
||||
policy_name = f"pytest-policy-{unique_name}"
|
||||
|
||||
try:
|
||||
response = iam_client.create_policy(
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=POLICY_DOC,
|
||||
Description="pytest test policy",
|
||||
)
|
||||
policy_arn = response["Policy"]["Arn"]
|
||||
assert response["Policy"]["PolicyName"] == policy_name
|
||||
assert policy_arn
|
||||
finally:
|
||||
iam_client.delete_policy(PolicyArn=response["Policy"]["Arn"])
|
||||
|
||||
def test_get_policy(self, iam_client, unique_name):
|
||||
"""Test GetPolicy returns policy details."""
|
||||
policy_name = f"pytest-policy-{unique_name}"
|
||||
|
||||
response = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=POLICY_DOC
|
||||
)
|
||||
policy_arn = response["Policy"]["Arn"]
|
||||
|
||||
try:
|
||||
response = iam_client.get_policy(PolicyArn=policy_arn)
|
||||
assert response["Policy"]["PolicyName"] == policy_name
|
||||
finally:
|
||||
iam_client.delete_policy(PolicyArn=policy_arn)
|
||||
|
||||
def test_attach_role_policy(self, iam_client, unique_name):
|
||||
"""Test AttachRolePolicy attaches policy to role."""
|
||||
role_name = f"pytest-role-{unique_name}"
|
||||
policy_name = f"pytest-policy-{unique_name}"
|
||||
|
||||
iam_client.create_role(
|
||||
RoleName=role_name, AssumeRolePolicyDocument=TRUST_POLICY
|
||||
)
|
||||
response = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=POLICY_DOC
|
||||
)
|
||||
policy_arn = response["Policy"]["Arn"]
|
||||
|
||||
try:
|
||||
iam_client.attach_role_policy(RoleName=role_name, PolicyArn=policy_arn)
|
||||
|
||||
response = iam_client.list_attached_role_policies(RoleName=role_name)
|
||||
assert any(
|
||||
p["PolicyArn"] == policy_arn for p in response["AttachedPolicies"]
|
||||
)
|
||||
finally:
|
||||
iam_client.detach_role_policy(RoleName=role_name, PolicyArn=policy_arn)
|
||||
iam_client.delete_role(RoleName=role_name)
|
||||
iam_client.delete_policy(PolicyArn=policy_arn)
|
||||
|
||||
def test_put_role_policy(self, iam_client, unique_name):
|
||||
"""Test PutRolePolicy adds inline policy to role."""
|
||||
role_name = f"pytest-role-{unique_name}"
|
||||
inline_policy_name = "inline-exec"
|
||||
|
||||
iam_client.create_role(
|
||||
RoleName=role_name, AssumeRolePolicyDocument=TRUST_POLICY
|
||||
)
|
||||
|
||||
try:
|
||||
iam_client.put_role_policy(
|
||||
RoleName=role_name,
|
||||
PolicyName=inline_policy_name,
|
||||
PolicyDocument='{"Version":"2012-10-17"}',
|
||||
)
|
||||
|
||||
response = iam_client.get_role_policy(
|
||||
RoleName=role_name, PolicyName=inline_policy_name
|
||||
)
|
||||
assert response["PolicyName"] == inline_policy_name
|
||||
|
||||
response = iam_client.list_role_policies(RoleName=role_name)
|
||||
assert inline_policy_name in response["PolicyNames"]
|
||||
finally:
|
||||
iam_client.delete_role_policy(
|
||||
RoleName=role_name, PolicyName=inline_policy_name
|
||||
)
|
||||
iam_client.delete_role(RoleName=role_name)
|
||||
|
||||
|
||||
class TestIAMUserPolicy:
|
||||
"""Test IAM user policy operations."""
|
||||
|
||||
def test_attach_user_policy(self, iam_client, unique_name):
|
||||
"""Test AttachUserPolicy attaches managed policy to user."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
policy_name = f"pytest-policy-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
response = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=POLICY_DOC
|
||||
)
|
||||
policy_arn = response["Policy"]["Arn"]
|
||||
|
||||
try:
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=policy_arn)
|
||||
# If no exception, attachment succeeded
|
||||
finally:
|
||||
iam_client.detach_user_policy(UserName=user_name, PolicyArn=policy_arn)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
iam_client.delete_policy(PolicyArn=policy_arn)
|
||||
|
||||
def test_list_attached_user_policies(self, iam_client, unique_name):
|
||||
"""Test ListAttachedUserPolicies returns attached managed policies."""
|
||||
user_name = f"pytest-user-{unique_name}"
|
||||
policy_name = f"pytest-policy-{unique_name}"
|
||||
|
||||
iam_client.create_user(UserName=user_name)
|
||||
response = iam_client.create_policy(
|
||||
PolicyName=policy_name, PolicyDocument=POLICY_DOC
|
||||
)
|
||||
policy_arn = response["Policy"]["Arn"]
|
||||
iam_client.attach_user_policy(UserName=user_name, PolicyArn=policy_arn)
|
||||
|
||||
try:
|
||||
response = iam_client.list_attached_user_policies(UserName=user_name)
|
||||
assert any(
|
||||
p["PolicyArn"] == policy_arn for p in response["AttachedPolicies"]
|
||||
)
|
||||
finally:
|
||||
iam_client.detach_user_policy(UserName=user_name, PolicyArn=policy_arn)
|
||||
iam_client.delete_user(UserName=user_name)
|
||||
iam_client.delete_policy(PolicyArn=policy_arn)
|
||||
Reference in New Issue
Block a user