kopia lustrzana https://github.com/simonw/s3-credentials
list-user-policies command, closes #5
rodzic
1f0cc51142
commit
a8e10fb148
42
README.md
42
README.md
|
@ -29,6 +29,7 @@ In this example I create credentials for reading and writing files in my `static
|
|||
|
||||
```
|
||||
% s3-credentials create static.niche-museums.com
|
||||
|
||||
Created user: s3.read-write.static.niche-museums.com with permissions boundary: arn:aws:iam::aws:policy/AmazonS3FullAccess
|
||||
Attached policy s3.read-write.static.niche-museums.com to user s3.read-write.static.niche-museums.com
|
||||
Created access key for user: s3.read-write.static.niche-museums.com
|
||||
|
@ -64,7 +65,7 @@ Here's the full sequence of events that take place when you run this command:
|
|||
|
||||
To see which user you are authenticated as:
|
||||
|
||||
$ s3-credentials whoami
|
||||
s3-credentials whoami
|
||||
|
||||
This will output JSON representing the currently authenticated user.
|
||||
|
||||
|
@ -72,7 +73,7 @@ This will output JSON representing the currently authenticated user.
|
|||
|
||||
To see a list of all users that exist for your AWS account:
|
||||
|
||||
$ s3-credentials list-users
|
||||
s3-credentials list-users
|
||||
|
||||
This will return pretty-printed JSON objects by default.
|
||||
|
||||
|
@ -80,6 +81,43 @@ Add `--nl` to collapse these to single lines as valid newline-delimited JSON.
|
|||
|
||||
Add `--array` to output a valid JSON array of objects instead.
|
||||
|
||||
### list-user-policies
|
||||
|
||||
To see a list of inline policies belonging to users:
|
||||
|
||||
```
|
||||
% s3-credentials list-user-policies s3.read-write.static.niche-museums.com
|
||||
|
||||
User: s3.read-write.static.niche-museums.com
|
||||
PolicyName: s3.read-write.static.niche-museums.com
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "ListObjectsInBucket",
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"s3:ListBucket"
|
||||
],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::static.niche-museums.com"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sid": "AllObjectActions",
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*Object",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::static.niche-museums.com/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
You can pass any number of usernames here. If you don't specify a username the tool will loop through every user belonging to your account:
|
||||
|
||||
s3-credentials list-user-policies
|
||||
|
||||
## Development
|
||||
|
||||
To contribute to this tool, first checkout the code. Then create a new virtual environment:
|
||||
|
|
|
@ -188,3 +188,29 @@ def list_users(array, nl):
|
|||
click.echo(json.dumps(user, indent=4, default=str))
|
||||
if gathered:
|
||||
click.echo(json.dumps(gathered, indent=4, default=str))
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("usernames", nargs=-1)
|
||||
def list_user_policies(usernames):
|
||||
"List inline policies for specified user"
|
||||
iam = boto3.client("iam")
|
||||
if not usernames:
|
||||
usernames = []
|
||||
paginator = iam.get_paginator("list_users")
|
||||
for response in paginator.paginate():
|
||||
for user in response["Users"]:
|
||||
usernames.append(user["UserName"])
|
||||
|
||||
paginator = iam.get_paginator("list_user_policies")
|
||||
for username in usernames:
|
||||
click.echo("User: {}".format(username))
|
||||
for response in paginator.paginate(UserName=username):
|
||||
for policy_name in response["PolicyNames"]:
|
||||
click.echo("PolicyName: {}".format(policy_name))
|
||||
policy_response = iam.get_user_policy(
|
||||
UserName=username, PolicyName=policy_name
|
||||
)
|
||||
click.echo(
|
||||
json.dumps(policy_response["PolicyDocument"], indent=4, default=str)
|
||||
)
|
||||
|
|
|
@ -65,3 +65,57 @@ def test_create(mocker):
|
|||
'call().put_user_policy(PolicyDocument=\'{"Version": "2012-10-17", "Statement": [{"Sid": "ListObjectsInBucket", "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": ["arn:aws:s3:::pytest-bucket-simonw-1"]}, {"Sid": "AllObjectActions", "Effect": "Allow", "Action": "s3:*Object", "Resource": ["arn:aws:s3:::pytest-bucket-simonw-1/*"]}]}\', PolicyName=\'s3.read-write.pytest-bucket-simonw-1\', UserName=\'s3.read-write.pytest-bucket-simonw-1\')',
|
||||
"call().create_access_key(UserName='s3.read-write.pytest-bucket-simonw-1')",
|
||||
]
|
||||
|
||||
|
||||
def test_list_user_policies(mocker):
|
||||
boto3 = mocker.patch("boto3.client")
|
||||
boto3.return_value = Mock()
|
||||
boto3.return_value.get_user_policy.return_value = {
|
||||
"PolicyDocument": {"policy": "here"}
|
||||
}
|
||||
|
||||
def get_paginator(type):
|
||||
m = Mock()
|
||||
if type == "list_users":
|
||||
m.paginate.return_value = [
|
||||
{"Users": [{"UserName": "one"}, {"UserName": "two"}]}
|
||||
]
|
||||
elif type == "list_user_policies":
|
||||
m.paginate.return_value = [{"PolicyNames": ["policy-one", "policy-two"]}]
|
||||
return m
|
||||
|
||||
boto3().get_paginator.side_effect = get_paginator
|
||||
runner = CliRunner()
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(cli, ["list-user-policies"], catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert result.output == (
|
||||
"User: one\n"
|
||||
"PolicyName: policy-one\n"
|
||||
"{\n"
|
||||
' "policy": "here"\n'
|
||||
"}\n"
|
||||
"PolicyName: policy-two\n"
|
||||
"{\n"
|
||||
' "policy": "here"\n'
|
||||
"}\n"
|
||||
"User: two\n"
|
||||
"PolicyName: policy-one\n"
|
||||
"{\n"
|
||||
' "policy": "here"\n'
|
||||
"}\n"
|
||||
"PolicyName: policy-two\n"
|
||||
"{\n"
|
||||
' "policy": "here"\n'
|
||||
"}\n"
|
||||
)
|
||||
assert [str(c) for c in boto3.mock_calls] == [
|
||||
"call()",
|
||||
"call('iam')",
|
||||
"call().get_paginator('list_users')",
|
||||
"call().get_paginator('list_user_policies')",
|
||||
"call().get_user_policy(UserName='one', PolicyName='policy-one')",
|
||||
"call().get_user_policy(UserName='one', PolicyName='policy-two')",
|
||||
"call().get_user_policy(UserName='two', PolicyName='policy-one')",
|
||||
"call().get_user_policy(UserName='two', PolicyName='policy-two')",
|
||||
]
|
||||
|
|
Ładowanie…
Reference in New Issue