IAM: fix keyerror result when attaching non-existent policy, add tests, fix error message for user as well (#6482)

This commit is contained in:
Daniel Fangl 2023-07-05 17:00:19 +02:00 committed by GitHub
parent d98d8cf0d5
commit 3ddfc0db40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 2 deletions

View File

@ -1823,7 +1823,13 @@ class IAMBackend(BaseBackend):
def attach_role_policy(self, policy_arn: str, role_name: str) -> None: def attach_role_policy(self, policy_arn: str, role_name: str) -> None:
arns = dict((p.arn, p) for p in self.managed_policies.values()) arns = dict((p.arn, p) for p in self.managed_policies.values())
policy = arns[policy_arn] try:
policy = arns[policy_arn]
except KeyError:
raise IAMNotFoundException(
f"Policy {policy_arn} does not exist or is not attachable."
)
policy.attach_to(self.get_role(role_name)) policy.attach_to(self.get_role(role_name))
def update_role_description(self, role_name: str, role_description: str) -> Role: def update_role_description(self, role_name: str, role_description: str) -> Role:
@ -1891,7 +1897,9 @@ class IAMBackend(BaseBackend):
try: try:
policy = arns[policy_arn] policy = arns[policy_arn]
except KeyError: except KeyError:
raise IAMNotFoundException(f"Policy {policy_arn} was not found.") raise IAMNotFoundException(
f"Policy {policy_arn} does not exist or is not attachable."
)
policy.attach_to(self.get_user(user_name)) policy.attach_to(self.get_user(user_name))
def detach_user_policy(self, policy_arn: str, user_name: str) -> None: def detach_user_policy(self, policy_arn: str, user_name: str) -> None:

View File

@ -2063,6 +2063,16 @@ def test_attach_detach_user_policy():
Description="my user attached policy", Description="my user attached policy",
) )
# try a non-existent policy
non_existent_policy_arn = f"arn:aws:iam::{ACCOUNT_ID}:policy/not-existent"
with pytest.raises(ClientError) as exc:
client.attach_user_policy(UserName=user.name, PolicyArn=non_existent_policy_arn)
err = exc.value.response["Error"]
err["Code"].should.equal("NoSuchEntity")
err["Message"].should.equal(
f"Policy {non_existent_policy_arn} does not exist or is not attachable."
)
client.attach_user_policy(UserName=user.name, PolicyArn=policy.arn) client.attach_user_policy(UserName=user.name, PolicyArn=policy.arn)
resp = client.list_attached_user_policies(UserName=user.name) resp = client.list_attached_user_policies(UserName=user.name)
@ -2077,6 +2087,45 @@ def test_attach_detach_user_policy():
resp["AttachedPolicies"].should.have.length_of(0) resp["AttachedPolicies"].should.have.length_of(0)
@mock_iam()
def test_attach_detach_role_policy():
iam = boto3.resource("iam", region_name="us-east-1")
client = boto3.client("iam", region_name="us-east-1")
role = iam.create_role(RoleName="test-role", AssumeRolePolicyDocument="{}")
policy_name = "RoleAttachedPolicy"
policy = iam.create_policy(
PolicyName=policy_name,
PolicyDocument=MOCK_POLICY,
Path="/mypolicy/",
Description="my role attached policy",
)
# try a non-existent policy
non_existent_policy_arn = f"arn:aws:iam::{ACCOUNT_ID}:policy/not-existent"
with pytest.raises(ClientError) as exc:
client.attach_role_policy(RoleName=role.name, PolicyArn=non_existent_policy_arn)
err = exc.value.response["Error"]
err["Code"].should.equal("NoSuchEntity")
err["Message"].should.equal(
f"Policy {non_existent_policy_arn} does not exist or is not attachable."
)
client.attach_role_policy(RoleName=role.name, PolicyArn=policy.arn)
resp = client.list_attached_role_policies(RoleName=role.name)
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)
client.detach_role_policy(RoleName=role.name, PolicyArn=policy.arn)
resp = client.list_attached_role_policies(RoleName=role.name)
resp["AttachedPolicies"].should.have.length_of(0)
@mock_iam() @mock_iam()
def test_only_detach_user_policy(): def test_only_detach_user_policy():
iam = boto3.resource("iam", region_name="us-east-1") iam = boto3.resource("iam", region_name="us-east-1")