diff --git a/moto/iam/models.py b/moto/iam/models.py index da11d58b2..1e4b58578 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -256,6 +256,7 @@ class User(BaseModel): self.policies = {} self.access_keys = [] self.password = None + self.password_reset_required = False @property def arn(self): @@ -772,6 +773,24 @@ class IAMBackend(BaseBackend): raise IAMConflictException( "User {0} already has password".format(user_name)) user.password = password + return user + + def get_login_profile(self, user_name): + user = self.get_user(user_name) + if not user.password: + raise IAMNotFoundException( + "Login profile for {0} not found".format(user_name)) + return user + + def update_login_profile(self, user_name, password, password_reset_required): + # This does not currently deal with PasswordPolicyViolation. + user = self.get_user(user_name) + if not user.password: + raise IAMNotFoundException( + "Login profile for {0} not found".format(user_name)) + user.password = password + user.password_reset_required = password_reset_required + return user def delete_login_profile(self, user_name): user = self.get_user(user_name) diff --git a/moto/iam/responses.py b/moto/iam/responses.py index 138c08d23..a5e5081c3 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -290,10 +290,27 @@ class IamResponse(BaseResponse): def create_login_profile(self): user_name = self._get_param('UserName') password = self._get_param('Password') - iam_backend.create_login_profile(user_name, password) + password = self._get_param('Password') + user = iam_backend.create_login_profile(user_name, password) template = self.response_template(CREATE_LOGIN_PROFILE_TEMPLATE) - return template.render(user_name=user_name) + return template.render(user=user) + + def get_login_profile(self): + user_name = self._get_param('UserName') + user = iam_backend.get_login_profile(user_name) + + template = self.response_template(GET_LOGIN_PROFILE_TEMPLATE) + return template.render(user=user) + + def update_login_profile(self): + user_name = self._get_param('UserName') + password = self._get_param('Password') + password_reset_required = self._get_param('PasswordResetRequired') + user = iam_backend.update_login_profile(user_name, password, password_reset_required) + + template = self.response_template(UPDATE_LOGIN_PROFILE_TEMPLATE) + return template.render(user=user) def add_user_to_group(self): group_name = self._get_param('GroupName') @@ -918,12 +935,11 @@ LIST_USERS_TEMPLATE = """<{{ action }}UsersResponse> """ -CREATE_LOGIN_PROFILE_TEMPLATE = """ - +CREATE_LOGIN_PROFILE_TEMPLATE = """ - {{ user_name }} - 2011-09-19T23:00:56Z + {{ user.name }} + {{ user.created_iso_8601 }} @@ -932,6 +948,29 @@ CREATE_LOGIN_PROFILE_TEMPLATE = """ """ +GET_LOGIN_PROFILE_TEMPLATE = """ + + + {{ user.name }} + {{ user.created_iso_8601 }} + {% if user.password_reset_required %} + true + {% endif %} + + + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + + +""" + +UPDATE_LOGIN_PROFILE_TEMPLATE = """ + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + + +""" + GET_USER_POLICY_TEMPLATE = """ {{ user_name }} diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index 46b727360..b5968f722 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -114,6 +114,29 @@ def test_remove_role_from_instance_profile(): dict(profile.roles).should.be.empty +@mock_iam() +def test_get_login_profile(): + conn = boto3.client('iam', region_name='us-east-1') + conn.create_user(UserName='my-user') + conn.create_login_profile(UserName='my-user', Password='my-pass') + + response = conn.get_login_profile(UserName='my-user') + response['LoginProfile']['UserName'].should.equal('my-user') + + +@mock_iam() +def test_update_login_profile(): + conn = boto3.client('iam', region_name='us-east-1') + conn.create_user(UserName='my-user') + conn.create_login_profile(UserName='my-user', Password='my-pass') + response = conn.get_login_profile(UserName='my-user') + response['LoginProfile'].get('PasswordResetRequired').should.equal(None) + + conn.update_login_profile(UserName='my-user', Password='new-pass', PasswordResetRequired=True) + response = conn.get_login_profile(UserName='my-user') + response['LoginProfile'].get('PasswordResetRequired').should.equal(True) + + @mock_iam() def test_delete_role(): conn = boto3.client('iam', region_name='us-east-1')