From f20e761a9f703a1735f3235b0280c0c4a5d7a456 Mon Sep 17 00:00:00 2001 From: "Aldo \"xoen\" Giambelluca" Date: Thu, 19 Dec 2019 19:00:08 +0000 Subject: [PATCH] Fixed revoke access when IAM role doesn't exist When trying to revoke access to a bucket the code tries to load the corresponsing IAM role's `s3-access` inline policy but if the IAM role doesn't exist this would of course fail. It's not clear what's causing this but this shouldn't prevent the operaion to succeed as if there is no IAM role effectively the provided IAM role (which doesn't exist) already doesn't have access to the bucket and hence there is nothing to revoke. Also, as when deleting a user/app role all the associated `AppS3Bucket` and `UserS3Bucket` records are deleted this exception mean you can't delete a user/app when it has access to something but no IAM role for whatever reason. Ticket: https://trello.com/c/vwgmnhBX --- controlpanel/api/aws.py | 10 +++++++++- tests/api/test_aws.py | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/controlpanel/api/aws.py b/controlpanel/api/aws.py index ff7b5a62c..d57d1effc 100644 --- a/controlpanel/api/aws.py +++ b/controlpanel/api/aws.py @@ -365,7 +365,15 @@ def revoke_bucket_access(role_name, bucket_arn=None, path_arns=[]): log.warning(f'Asked to revoke {role_name} role access to nothing') return - role = boto3.resource('iam').Role(role_name) + try: + role = boto3.resource("iam").Role(role_name) + role.load() + except botocore.exceptions.ClientError as e: + if e.response["Error"]["Code"] == "NoSuchEntity": + log.warning(f"Role '{role_name}' doesn't exist: Nothing to revoke") + return + raise e + policy = S3AccessPolicy(role.Policy('s3-access')) for arn in path_arns: policy.revoke_access(arn) diff --git a/tests/api/test_aws.py b/tests/api/test_aws.py index 0856ed489..80ad5b375 100644 --- a/tests/api/test_aws.py +++ b/tests/api/test_aws.py @@ -359,6 +359,18 @@ def test_revoke_bucket_access(iam, users, resources): assert 'list' not in statements +def test_revoke_bucket_access_when_no_role(iam): + role_name = "test_role_non_existent" + bucket_arn = "arn:aws:s3:::test-bucket" + + # be sure role doesn't exist before calling revoke_bucket_access() + with pytest.raises(iam.meta.client.exceptions.NoSuchEntityException): + role = iam.Role(role_name) + role.load() + + aws.revoke_bucket_access(role_name, bucket_arn, []) + + def test_create_group(iam, settings): aws.create_group('test', '/group/test/')