diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index a5650f572..1c76b04cf 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2334,7 +2334,7 @@ - [ ] update_service_specific_credential - [X] update_signing_certificate - [ ] update_ssh_public_key -- [ ] update_user +- [X] update_user - [X] upload_server_certificate - [X] upload_signing_certificate - [ ] upload_ssh_public_key diff --git a/moto/iam/models.py b/moto/iam/models.py index 92ac19da7..ae993ebfd 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -892,6 +892,18 @@ class IAMBackend(BaseBackend): return users + def update_user(self, user_name, new_path=None, new_user_name=None): + try: + user = self.users[user_name] + except KeyError: + raise IAMNotFoundException("User {0} not found".format(user_name)) + + if new_path: + user.path = new_path + if new_user_name: + user.name = new_user_name + self.users[new_user_name] = self.users.pop(user_name) + def list_roles(self, path_prefix, marker, max_items): roles = None try: diff --git a/moto/iam/responses.py b/moto/iam/responses.py index 5b19c9cdc..e5b4c9070 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -440,6 +440,18 @@ class IamResponse(BaseResponse): template = self.response_template(LIST_USERS_TEMPLATE) return template.render(action='List', users=users) + def update_user(self): + user_name = self._get_param('UserName') + new_path = self._get_param('NewPath') + new_user_name = self._get_param('NewUserName') + iam_backend.update_user(user_name, new_path, new_user_name) + if new_user_name: + user = iam_backend.get_user(new_user_name) + else: + user = iam_backend.get_user(user_name) + template = self.response_template(USER_TEMPLATE) + return template.render(action='Update', user=user) + def create_login_profile(self): user_name = self._get_param('UserName') password = self._get_param('Password') diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index ceec5e06a..5875b747a 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -401,6 +401,19 @@ def test_get_user(): conn.get_user('my-user') +@mock_iam() +def test_update_user(): + conn = boto3.client('iam', region_name='us-east-1') + with assert_raises(conn.exceptions.NoSuchEntityException): + conn.update_user(UserName='my-user') + conn.create_user(UserName='my-user') + conn.update_user(UserName='my-user', NewPath='/new-path/', NewUserName='new-user') + response = conn.get_user(UserName='new-user') + response['User'].get('Path').should.equal('/new-path/') + with assert_raises(conn.exceptions.NoSuchEntityException): + conn.get_user(UserName='my-user') + + @mock_iam_deprecated() def test_get_current_user(): """If no user is specific, IAM returns the current user"""