Implement List user tags

This commit is contained in:
Asher Foa 2019-12-19 18:30:43 -08:00
parent 0f67a74d25
commit 1415a93596
4 changed files with 88 additions and 9 deletions

View File

@ -3447,7 +3447,7 @@
- [X] list_signing_certificates - [X] list_signing_certificates
- [ ] list_ssh_public_keys - [ ] list_ssh_public_keys
- [X] list_user_policies - [X] list_user_policies
- [ ] list_user_tags - [X] list_user_tags
- [X] list_users - [X] list_users
- [X] list_virtual_mfa_devices - [X] list_virtual_mfa_devices
- [X] put_group_policy - [X] put_group_policy

View File

@ -543,7 +543,7 @@ class Group(BaseModel):
class User(BaseModel): class User(BaseModel):
def __init__(self, name, path=None): def __init__(self, name, path=None, tags=None):
self.name = name self.name = name
self.id = random_resource_id() self.id = random_resource_id()
self.path = path if path else "/" self.path = path if path else "/"
@ -556,6 +556,7 @@ class User(BaseModel):
self.password = None self.password = None
self.password_reset_required = False self.password_reset_required = False
self.signing_certificates = {} self.signing_certificates = {}
self.tags = tags
@property @property
def arn(self): def arn(self):
@ -1421,13 +1422,13 @@ class IAMBackend(BaseBackend):
"The group with name {0} cannot be found.".format(group_name) "The group with name {0} cannot be found.".format(group_name)
) )
def create_user(self, user_name, path="/"): def create_user(self, user_name, path="/", tags=None):
if user_name in self.users: if user_name in self.users:
raise IAMConflictException( raise IAMConflictException(
"EntityAlreadyExists", "User {0} already exists".format(user_name) "EntityAlreadyExists", "User {0} already exists".format(user_name)
) )
user = User(user_name, path) user = User(user_name, path, tags)
self.users[user_name] = user self.users[user_name] = user
return user return user
@ -1583,6 +1584,10 @@ class IAMBackend(BaseBackend):
user = self.get_user(user_name) user = self.get_user(user_name)
return user.policies.keys() return user.policies.keys()
def list_user_tags(self, user_name):
user = self.get_user(user_name)
return user.tags
def put_user_policy(self, user_name, policy_name, policy_json): def put_user_policy(self, user_name, policy_name, policy_json):
user = self.get_user(user_name) user = self.get_user(user_name)

View File

@ -440,8 +440,8 @@ class IamResponse(BaseResponse):
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")
tags = self._get_multi_param("Tags.member")
user = iam_backend.create_user(user_name, path) user = iam_backend.create_user(user_name, path, tags)
template = self.response_template(USER_TEMPLATE) template = self.response_template(USER_TEMPLATE)
return template.render(action="Create", user=user) return template.render(action="Create", user=user)
@ -538,6 +538,12 @@ class IamResponse(BaseResponse):
template = self.response_template(LIST_USER_POLICIES_TEMPLATE) template = self.response_template(LIST_USER_POLICIES_TEMPLATE)
return template.render(policies=policies) return template.render(policies=policies)
def list_user_tags(self):
user_name = self._get_param("UserName")
tags = iam_backend.list_user_tags(user_name)
template = self.response_template(LIST_USER_TAGS_TEMPLATE)
return template.render(user_tags=tags or [])
def put_user_policy(self): def put_user_policy(self):
user_name = self._get_param("UserName") user_name = self._get_param("UserName")
policy_name = self._get_param("PolicyName") policy_name = self._get_param("PolicyName")
@ -1699,6 +1705,23 @@ LIST_USER_POLICIES_TEMPLATE = """<ListUserPoliciesResponse>
</ResponseMetadata> </ResponseMetadata>
</ListUserPoliciesResponse>""" </ListUserPoliciesResponse>"""
LIST_USER_TAGS_TEMPLATE = """<ListUserTagsResponse>
<ListUserTagsResult>
<Tags>
{% for tag in user_tags %}
<item>
<Key>{{ tag.Key }}</Key>
<Value>{{ tag.Value }}</Value>
</item>
{% endfor %}
</Tags>
<IsTruncated>false</IsTruncated>
</ListUserTagsResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListUserTagsResponse>"""
CREATE_ACCESS_KEY_TEMPLATE = """<CreateAccessKeyResponse> CREATE_ACCESS_KEY_TEMPLATE = """<CreateAccessKeyResponse>
<CreateAccessKeyResult> <CreateAccessKeyResult>
<AccessKey> <AccessKey>

View File

@ -1737,9 +1737,7 @@ def test_delete_saml_provider():
def test_create_role_defaults(): def test_create_role_defaults():
"""Tests default values""" """Tests default values"""
conn = boto3.client("iam", region_name="us-east-1") conn = boto3.client("iam", region_name="us-east-1")
conn.create_role( conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="{}")
RoleName="my-role", AssumeRolePolicyDocument="{}",
)
# Get role: # Get role:
role = conn.get_role(RoleName="my-role")["Role"] role = conn.get_role(RoleName="my-role")["Role"]
@ -2672,3 +2670,56 @@ def test_get_account_summary():
"GroupsQuota": 300, "GroupsQuota": 300,
} }
) )
@mock_iam()
def test_list_user_tags():
"""Tests both setting a tags on a user in create_user and list_user_tags"""
conn = boto3.client("iam", region_name="us-east-1")
conn.create_user(UserName="kenny-bania")
conn.create_user(
UserName="jackie-chiles", Tags=[{"Key": "Sue-Allen", "Value": "Oh-Henry"}]
)
conn.create_user(
UserName="cosmo",
Tags=[
{"Key": "Stan", "Value": "The Caddy"},
{"Key": "like-a", "Value": "glove"},
],
)
assert conn.list_user_tags(UserName="kenny-bania") == {
"Tags": [],
"IsTruncated": False,
"ResponseMetadata": {
"RequestId": "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE",
"HTTPStatusCode": 200,
"HTTPHeaders": {"server": "amazon.com"},
"RetryAttempts": 0,
},
}
assert conn.list_user_tags(UserName="jackie-chiles") == {
"Tags": [{"Key": "Sue-Allen", "Value": "Oh-Henry"}],
"IsTruncated": False,
"ResponseMetadata": {
"RequestId": "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE",
"HTTPStatusCode": 200,
"HTTPHeaders": {"server": "amazon.com"},
"RetryAttempts": 0,
},
}
assert conn.list_user_tags(UserName="cosmo") == {
"Tags": [
{"Key": "Stan", "Value": "The Caddy"},
{"Key": "like-a", "Value": "glove"},
],
"IsTruncated": False,
"ResponseMetadata": {
"RequestId": "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE",
"HTTPStatusCode": 200,
"HTTPHeaders": {"server": "amazon.com"},
"RetryAttempts": 0,
},
}