Add IAM list_groups and list_groups_for_user. Closes #343.
This commit is contained in:
parent
d1c823e0d8
commit
be5f041416
@ -6,6 +6,7 @@ from .utils import random_access_key, random_alphanumeric, random_resource_id
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
|
||||||
class Role(object):
|
class Role(object):
|
||||||
|
|
||||||
def __init__(self, role_id, name, assume_role_policy_document, path):
|
def __init__(self, role_id, name, assume_role_policy_document, path):
|
||||||
@ -212,16 +213,16 @@ class User(object):
|
|||||||
access_key_2_last_rotated = date_created.strftime(date_format)
|
access_key_2_last_rotated = date_created.strftime(date_format)
|
||||||
|
|
||||||
return '{0},{1},{2},{3},{4},{5},not_supported,false,{6},{7},{8},{9},false,N/A,false,N/A'.format(self.name,
|
return '{0},{1},{2},{3},{4},{5},not_supported,false,{6},{7},{8},{9},false,N/A,false,N/A'.format(self.name,
|
||||||
self.arn,
|
self.arn,
|
||||||
date_created.strftime(date_format),
|
date_created.strftime(date_format),
|
||||||
password_enabled,
|
password_enabled,
|
||||||
password_last_used,
|
password_last_used,
|
||||||
date_created.strftime(date_format),
|
date_created.strftime(date_format),
|
||||||
access_key_1_active,
|
access_key_1_active,
|
||||||
access_key_1_last_rotated,
|
access_key_1_last_rotated,
|
||||||
access_key_2_active,
|
access_key_2_active,
|
||||||
access_key_2_last_rotated
|
access_key_2_last_rotated
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class IAMBackend(BaseBackend):
|
class IAMBackend(BaseBackend):
|
||||||
@ -337,6 +338,18 @@ class IAMBackend(BaseBackend):
|
|||||||
|
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
def list_groups(self):
|
||||||
|
return self.groups.values()
|
||||||
|
|
||||||
|
def get_groups_for_user(self, user_name):
|
||||||
|
user = self.get_user(user_name)
|
||||||
|
groups = []
|
||||||
|
for group in self.list_groups():
|
||||||
|
if user in group.users:
|
||||||
|
groups.append(group)
|
||||||
|
|
||||||
|
return groups
|
||||||
|
|
||||||
def create_user(self, user_name, path='/'):
|
def create_user(self, user_name, path='/'):
|
||||||
if user_name in self.users:
|
if user_name in self.users:
|
||||||
raise BotoServerError(409, 'Conflict')
|
raise BotoServerError(409, 'Conflict')
|
||||||
|
@ -131,6 +131,18 @@ class IamResponse(BaseResponse):
|
|||||||
template = self.response_template(GET_GROUP_TEMPLATE)
|
template = self.response_template(GET_GROUP_TEMPLATE)
|
||||||
return template.render(group=group)
|
return template.render(group=group)
|
||||||
|
|
||||||
|
def list_groups(self):
|
||||||
|
groups = iam_backend.list_groups()
|
||||||
|
template = self.response_template(LIST_GROUPS_TEMPLATE)
|
||||||
|
return template.render(groups=groups)
|
||||||
|
|
||||||
|
def list_groups_for_user(self):
|
||||||
|
user_name = self._get_param('UserName')
|
||||||
|
|
||||||
|
groups = iam_backend.get_groups_for_user(user_name)
|
||||||
|
template = self.response_template(LIST_GROUPS_FOR_USER_TEMPLATE)
|
||||||
|
return template.render(groups=groups)
|
||||||
|
|
||||||
def create_user(self):
|
def create_user(self):
|
||||||
user_name = self._get_param('UserName')
|
user_name = self._get_param('UserName')
|
||||||
path = self._get_param('Path')
|
path = self._get_param('Path')
|
||||||
@ -502,6 +514,45 @@ GET_GROUP_TEMPLATE = """<GetGroupResponse>
|
|||||||
</ResponseMetadata>
|
</ResponseMetadata>
|
||||||
</GetGroupResponse>"""
|
</GetGroupResponse>"""
|
||||||
|
|
||||||
|
LIST_GROUPS_TEMPLATE = """<ListGroupsResponse>
|
||||||
|
<ListGroupsResult>
|
||||||
|
<Groups>
|
||||||
|
{% for group in groups %}
|
||||||
|
<member>
|
||||||
|
<Path>{{ group.path }}</Path>
|
||||||
|
<GroupName>{{ group.name }}</GroupName>
|
||||||
|
<GroupId>{{ group.id }}</GroupId>
|
||||||
|
<Arn>arn:aws:iam::123456789012:group/{{ group.path }}</Arn>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Groups>
|
||||||
|
<IsTruncated>false</IsTruncated>
|
||||||
|
</ListGroupsResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</ListGroupsResponse>"""
|
||||||
|
|
||||||
|
LIST_GROUPS_FOR_USER_TEMPLATE = """<ListGroupsForUserResponse>
|
||||||
|
<ListGroupsForUserResult>
|
||||||
|
<Groups>
|
||||||
|
{% for group in groups %}
|
||||||
|
<member>
|
||||||
|
<Path>{{ group.path }}</Path>
|
||||||
|
<GroupName>{{ group.name }}</GroupName>
|
||||||
|
<GroupId>{{ group.id }}</GroupId>
|
||||||
|
<Arn>arn:aws:iam::123456789012:group/{{ group.path }}</Arn>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Groups>
|
||||||
|
<IsTruncated>false</IsTruncated>
|
||||||
|
</ListGroupsForUserResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</ListGroupsForUserResponse>"""
|
||||||
|
|
||||||
|
|
||||||
USER_TEMPLATE = """<{{ action }}UserResponse>
|
USER_TEMPLATE = """<{{ action }}UserResponse>
|
||||||
<{{ action }}UserResult>
|
<{{ action }}UserResult>
|
||||||
<User>
|
<User>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import boto
|
import boto
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
import re
|
|
||||||
|
|
||||||
from nose.tools import assert_raises, assert_equals, assert_not_equals
|
from nose.tools import assert_raises, assert_equals, assert_not_equals
|
||||||
from boto.exception import BotoServerError
|
from boto.exception import BotoServerError
|
||||||
@ -62,6 +61,7 @@ def test_create_role_and_instance_profile():
|
|||||||
conn.list_roles().roles[0].role_name.should.equal('my-role')
|
conn.list_roles().roles[0].role_name.should.equal('my-role')
|
||||||
conn.list_instance_profiles().instance_profiles[0].instance_profile_name.should.equal("my-profile")
|
conn.list_instance_profiles().instance_profiles[0].instance_profile_name.should.equal("my-profile")
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_list_instance_profiles_for_role():
|
def test_list_instance_profiles_for_role():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
@ -71,15 +71,15 @@ def test_list_instance_profiles_for_role():
|
|||||||
|
|
||||||
profile_name_list = ['my-profile', 'my-profile2']
|
profile_name_list = ['my-profile', 'my-profile2']
|
||||||
profile_path_list = ['my-path', 'my-path2']
|
profile_path_list = ['my-path', 'my-path2']
|
||||||
for profile_count in range(0,2):
|
for profile_count in range(0, 2):
|
||||||
conn.create_instance_profile(profile_name_list[profile_count], path=profile_path_list[profile_count])
|
conn.create_instance_profile(profile_name_list[profile_count], path=profile_path_list[profile_count])
|
||||||
|
|
||||||
for profile_count in range(0,2):
|
for profile_count in range(0, 2):
|
||||||
conn.add_role_to_instance_profile(profile_name_list[profile_count], "my-role")
|
conn.add_role_to_instance_profile(profile_name_list[profile_count], "my-role")
|
||||||
|
|
||||||
profile_dump = conn.list_instance_profiles_for_role(role_name="my-role")
|
profile_dump = conn.list_instance_profiles_for_role(role_name="my-role")
|
||||||
profile_list = profile_dump['list_instance_profiles_for_role_response']['list_instance_profiles_for_role_result']['instance_profiles']
|
profile_list = profile_dump['list_instance_profiles_for_role_response']['list_instance_profiles_for_role_result']['instance_profiles']
|
||||||
for profile_count in range(0,len(profile_list)):
|
for profile_count in range(0, len(profile_list)):
|
||||||
profile_name_list.remove(profile_list[profile_count]["instance_profile_name"])
|
profile_name_list.remove(profile_list[profile_count]["instance_profile_name"])
|
||||||
profile_path_list.remove(profile_list[profile_count]["path"])
|
profile_path_list.remove(profile_list[profile_count]["path"])
|
||||||
profile_list[profile_count]["roles"]["member"]["role_name"].should.equal("my-role")
|
profile_list[profile_count]["roles"]["member"]["role_name"].should.equal("my-role")
|
||||||
@ -91,6 +91,7 @@ def test_list_instance_profiles_for_role():
|
|||||||
profile_list = profile_dump2['list_instance_profiles_for_role_response']['list_instance_profiles_for_role_result']['instance_profiles']
|
profile_list = profile_dump2['list_instance_profiles_for_role_response']['list_instance_profiles_for_role_result']['instance_profiles']
|
||||||
len(profile_list).should.equal(0)
|
len(profile_list).should.equal(0)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_list_role_policies():
|
def test_list_role_policies():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
@ -118,23 +119,6 @@ def test_update_assume_role_policy():
|
|||||||
role.assume_role_policy_document.should.equal("my-policy")
|
role.assume_role_policy_document.should.equal("my-policy")
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
|
||||||
def test_create_group():
|
|
||||||
conn = boto.connect_iam()
|
|
||||||
conn.create_group('my-group')
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.create_group('my-group')
|
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
|
||||||
def test_get_group():
|
|
||||||
conn = boto.connect_iam()
|
|
||||||
conn.create_group('my-group')
|
|
||||||
conn.get_group('my-group')
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.get_group('not-group')
|
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_create_user():
|
def test_create_user():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
@ -163,31 +147,6 @@ def test_create_login_profile():
|
|||||||
conn.create_login_profile('my-user', 'my-pass')
|
conn.create_login_profile('my-user', 'my-pass')
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
|
||||||
def test_add_user_to_group():
|
|
||||||
conn = boto.connect_iam()
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.add_user_to_group('my-group', 'my-user')
|
|
||||||
conn.create_group('my-group')
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.add_user_to_group('my-group', 'my-user')
|
|
||||||
conn.create_user('my-user')
|
|
||||||
conn.add_user_to_group('my-group', 'my-user')
|
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
|
||||||
def test_remove_user_from_group():
|
|
||||||
conn = boto.connect_iam()
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.remove_user_from_group('my-group', 'my-user')
|
|
||||||
conn.create_group('my-group')
|
|
||||||
conn.create_user('my-user')
|
|
||||||
with assert_raises(BotoServerError):
|
|
||||||
conn.remove_user_from_group('my-group', 'my-user')
|
|
||||||
conn.add_user_to_group('my-group', 'my-user')
|
|
||||||
conn.remove_user_from_group('my-group', 'my-user')
|
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_create_access_key():
|
def test_create_access_key():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
@ -230,6 +189,7 @@ def test_delete_user():
|
|||||||
conn.create_user('my-user')
|
conn.create_user('my-user')
|
||||||
conn.delete_user('my-user')
|
conn.delete_user('my-user')
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_generate_credential_report():
|
def test_generate_credential_report():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
@ -238,6 +198,7 @@ def test_generate_credential_report():
|
|||||||
result = conn.generate_credential_report()
|
result = conn.generate_credential_report()
|
||||||
result['generate_credential_report_response']['generate_credential_report_result']['state'].should.equal('COMPLETE')
|
result['generate_credential_report_response']['generate_credential_report_result']['state'].should.equal('COMPLETE')
|
||||||
|
|
||||||
|
|
||||||
@mock_iam()
|
@mock_iam()
|
||||||
def test_get_credential_report():
|
def test_get_credential_report():
|
||||||
conn = boto.connect_iam()
|
conn = boto.connect_iam()
|
||||||
|
72
tests/test_iam/test_iam_groups.py
Normal file
72
tests/test_iam/test_iam_groups.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import boto
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from nose.tools import assert_raises
|
||||||
|
from boto.exception import BotoServerError
|
||||||
|
from moto import mock_iam
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_create_group():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
conn.create_group('my-group')
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.create_group('my-group')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_get_group():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
conn.create_group('my-group')
|
||||||
|
conn.get_group('my-group')
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.get_group('not-group')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_get_all_groups():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
conn.create_group('my-group1')
|
||||||
|
conn.create_group('my-group2')
|
||||||
|
groups = conn.get_all_groups()['list_groups_response']['list_groups_result']['groups']
|
||||||
|
groups.should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_add_user_to_group():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.add_user_to_group('my-group', 'my-user')
|
||||||
|
conn.create_group('my-group')
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.add_user_to_group('my-group', 'my-user')
|
||||||
|
conn.create_user('my-user')
|
||||||
|
conn.add_user_to_group('my-group', 'my-user')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_remove_user_from_group():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.remove_user_from_group('my-group', 'my-user')
|
||||||
|
conn.create_group('my-group')
|
||||||
|
conn.create_user('my-user')
|
||||||
|
with assert_raises(BotoServerError):
|
||||||
|
conn.remove_user_from_group('my-group', 'my-user')
|
||||||
|
conn.add_user_to_group('my-group', 'my-user')
|
||||||
|
conn.remove_user_from_group('my-group', 'my-user')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam()
|
||||||
|
def test_get_groups_for_user():
|
||||||
|
conn = boto.connect_iam()
|
||||||
|
conn.create_group('my-group1')
|
||||||
|
conn.create_group('my-group2')
|
||||||
|
conn.create_group('other-group')
|
||||||
|
conn.create_user('my-user')
|
||||||
|
conn.add_user_to_group('my-group1', 'my-user')
|
||||||
|
conn.add_user_to_group('my-group2', 'my-user')
|
||||||
|
|
||||||
|
groups = conn.get_groups_for_user('my-user')['list_groups_for_user_response']['list_groups_for_user_result']['groups']
|
||||||
|
groups.should.have.length_of(2)
|
Loading…
x
Reference in New Issue
Block a user