diff --git a/moto/iam/models.py b/moto/iam/models.py index a9bd4eb71..376469ce8 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -8,12 +8,12 @@ from datetime import datetime class Role(object): - def __init__(self, role_id, name, assume_role_policy_document, path, policies): + def __init__(self, role_id, name, assume_role_policy_document, path): self.id = role_id self.name = name self.assume_role_policy_document = assume_role_policy_document self.path = path - self.policies = policies + self.policies = {} @classmethod def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): @@ -26,6 +26,9 @@ class Role(object): policies=properties.get('Policies', []), ) + def put_policy(self, policy_name, policy_json): + self.policies[policy_name] = policy_json + @property def physical_resource_id(self): return self.id @@ -185,9 +188,9 @@ class IAMBackend(BaseBackend): self.users = {} super(IAMBackend, self).__init__() - def create_role(self, role_name, assume_role_policy_document, path, policies): + def create_role(self, role_name, assume_role_policy_document, path): role_id = random_resource_id() - role = Role(role_id, role_name, assume_role_policy_document, path, policies) + role = Role(role_id, role_name, assume_role_policy_document, path) self.roles[role_id] = role return role @@ -202,6 +205,29 @@ class IAMBackend(BaseBackend): def get_roles(self): return self.roles.values() + def put_role_policy(self, role_name, policy_name, policy_json): + role = self.get_role(role_name) + if role: + role.put_policy(policy_name, policy_json) + else: + raise BotoServerError(404, 'Not Found') + + def get_role_policy(self, role_name, policy_name): + role = self.get_role(role_name) + if role: + for p, d in role.policies.iteritems(): + if p == policy_name: + return p, d + else: + raise BotoServerError(404, 'Not Found') + + def list_role_policies(self, role_name): + role = self.get_role(role_name) + if role: + return role.policies.keys() + else: + raise BotoServerError(404, 'Not Found') + def create_instance_profile(self, name, path, role_ids): instance_profile_id = random_resource_id() diff --git a/moto/iam/responses.py b/moto/iam/responses.py index 422977bfe..1f4036ddf 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -15,7 +15,7 @@ class IamResponse(BaseResponse): path = self._get_param('Path') assume_role_policy_document = self._get_param('AssumeRolePolicyDocument') - role = iam_backend.create_role(role_name, assume_role_policy_document, path, policies=[]) + role = iam_backend.create_role(role_name, assume_role_policy_document, path) template = Template(CREATE_ROLE_TEMPLATE) return template.render(role=role) @@ -26,6 +26,36 @@ class IamResponse(BaseResponse): template = Template(GET_ROLE_TEMPLATE) return template.render(role=role) + def list_role_policies(self): + role_name = self._get_param('RoleName') + role_policies_names = iam_backend.list_role_policies(role_name) + template = Template(LIST_ROLE_POLICIES) + return template.render(role_policies=role_policies_names) + + def put_role_policy(self): + role_name = self._get_param('RoleName') + policy_name = self._get_param('PolicyName') + policy_document = self._get_param('PolicyDocument') + iam_backend.put_role_policy(role_name, policy_name, policy_document) + template = Template(GENERIC_EMPTY_TEMPLATE) + return template.render(name="PutRolePolicyResponse") + + def get_role_policy(self): + role_name = self._get_param('RoleName') + policy_name = self._get_param('PolicyName') + policy_name, policy_document = iam_backend.get_role_policy(role_name, policy_name) + template = Template(GET_ROLE_POLICY_TEMPLATE) + return template.render(role_name=role_name, + policy_name=policy_name, + policy_document=policy_document) + + def update_assume_role_policy(self): + role_name = self._get_param('RoleName') + role = iam_backend.get_role(role_name) + role.assume_role_policy_document = self._get_param('PolicyDocument') + template = Template(GENERIC_EMPTY_TEMPLATE) + return template.render(name="UpdateAssumeRolePolicyResponse") + def create_instance_profile(self): profile_name = self._get_param('InstanceProfileName') path = self._get_param('Path') @@ -259,6 +289,17 @@ CREATE_ROLE_TEMPLATE = """ + + {{ policy_name }} + {{ role_name }} + {{ policy_document }} + + + 7e7cd8bc-99ef-11e1-a4c3-27EXAMPLE804 + +""" + GET_ROLE_TEMPLATE = """ @@ -302,6 +343,20 @@ LIST_ROLES_TEMPLATE = """ + + + {% for policy_name in role_policies %} + {{ policy_name }} + {% endfor %} + + false + + + 8c7e1816-99f0-11e1-a4c3-27EXAMPLE804 + +""" + LIST_INSTANCE_PROFILES_TEMPLATE = """ false diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index e9121a5aa..11863d83d 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -62,6 +62,33 @@ def test_create_role_and_instance_profile(): conn.list_instance_profiles().instance_profiles[0].instance_profile_name.should.equal("my-profile") +@mock_iam() +def test_list_role_policies(): + conn = boto.connect_iam() + conn.create_role("my-role") + conn.put_role_policy("my-role", "test policy", "my policy") + role = conn.list_role_policies("my-role") + role.policy_names[0].should.equal("test policy") + + +@mock_iam() +def test_put_role_policy(): + conn = boto.connect_iam() + conn.create_role("my-role", assume_role_policy_document="some policy", path="my-path") + conn.put_role_policy("my-role", "test policy", "my policy") + policy = conn.get_role_policy("my-role", "test policy")['get_role_policy_response']['get_role_policy_result']['policy_name'] + policy.should.equal("test policy") + + +@mock_iam() +def test_update_assume_role_policy(): + conn = boto.connect_iam() + role = conn.create_role("my-role") + conn.update_assume_role_policy(role.role_name, "my-policy") + role = conn.get_role("my-role") + role.assume_role_policy_document.should.equal("my-policy") + + @mock_iam() def test_create_group(): conn = boto.connect_iam()