def test_password_reset_request_with_login_failures_feature_enabled(self):
        """
        Tests that user's login failures lockout counter is reset upon successful password reset.
        """

        # Adding an entry in LoginFailures to verify the password reset endpoint
        # reset the user's login failures lockout counter.
        LoginFailures.increment_lockout_counter(self.user)

        post_request = self.create_reset_request(self.uidb36, self.token,
                                                 False)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        json_response = reset_view(post_request,
                                   uidb36=self.uidb36,
                                   token=self.token).render()
        json_response = json.loads(json_response.content.decode('utf-8'))

        # Verify that the user's login failures lockout count is reset.
        assert json_response.get('reset_status')
        assert not LoginFailures.is_user_locked_out(self.user)

        # Verify that the user's login failures lockout counter is not reset upon
        # password reset failure.
        LoginFailures.increment_lockout_counter(self.user)

        post_request = self.create_reset_request(self.uidb36, self.token,
                                                 False, 'new_password2')
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        reset_view(post_request, uidb36=self.uidb36, token=self.token).render()

        assert LoginFailures.is_user_locked_out(self.user)
    def test_password_reset_email_successfully_sent(self, is_account_recovery):
        """
        Test that with is_account_recovery query param available, password
        reset email is sent to newly updated email address.
        """
        post_request = self.create_reset_request(self.uidb36, self.token,
                                                 is_account_recovery)
        post_request.user = AnonymousUser()
        post_request.site = Mock(domain='example.com')
        reset_view = LogistrationPasswordResetView.as_view()
        reset_view(post_request, uidb36=self.uidb36, token=self.token)
        updated_user = User.objects.get(id=self.user.id)

        from_email = configuration_helpers.get_value(
            'email_from_address', settings.DEFAULT_FROM_EMAIL)
        sent_message = mail.outbox[0]
        body = sent_message.body

        self.assertIn('Password reset completed', sent_message.subject)
        self.assertIn(
            'This is to confirm that you have successfully changed your password',
            body)
        self.assertEqual(sent_message.from_email, from_email)
        self.assertEqual(len(sent_message.to), 1)
        self.assertIn(updated_user.email, sent_message.to[0])
 def test_password_mismatch_in_reset_request(self):
     """
     Test that user should not be able to reset password with password mismatch
     """
     post_request = self.create_reset_request(self.uidb36, self.token, False, 'new_password2')
     post_request.user = AnonymousUser()
     reset_view = LogistrationPasswordResetView.as_view()
     json_response = reset_view(post_request, uidb36=self.uidb36, token=self.token).render()
     json_response = json.loads(json_response.content.decode('utf-8'))
     self.assertFalse(json_response.get('reset_status'))
    def test_none_token_in_password_reset_request(self):
        """
        Test that user should not be able to reset password through no token/uidb36
        """
        uidb36 = None
        token = None

        post_request = self.create_reset_request(self.uidb36, self.token, False)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        self.assertRaises(Exception, reset_view(post_request, uidb36=uidb36, token=token))
    def test_password_reset_request(self, uidb36, token, status):
        """Tests password reset request with valid/invalid token"""

        uidb36 = uidb36 or self.uidb36
        token = token or self.token

        post_request = self.create_reset_request(uidb36, token, False)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        json_response = reset_view(post_request, uidb36=uidb36, token=token).render()
        json_response = json.loads(json_response.content.decode('utf-8'))
        self.assertEqual(json_response.get('reset_status'), status)
    def test_none_token_in_password_reset_request(self):
        """
        Test that user should not be able to reset password through no token/uidb36
        """
        uidb36 = None
        token = None

        post_request = self.create_reset_request(self.uidb36, self.token,
                                                 False)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        response = reset_view(post_request, uidb36=uidb36, token=token)
        assert response.status_code == 200
        response.render()
        response_dict = json.loads(response.content.decode('utf-8'))
        assert response_dict.get('reset_status') is False
    def test_account_recovery_using_forgot_password(self):
        """
        Test that with is_account_recovery query param available, primary
        email is updated with linked secondary email.
        """
        post_request = self.create_reset_request(self.uidb36, self.token, True)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        reset_view(post_request, uidb36=self.uidb36, token=self.token)

        updated_user = User.objects.get(id=self.user.id)
        assert updated_user.email == self.secondary_email

        self.assert_event_emitted(SETTING_CHANGE_INITIATED,
                                  user_id=self.user.id,
                                  setting='email',
                                  old=self.user.email,
                                  new=updated_user.email)
    def test_password_reset_request_with_login_failures_feature_disabled(self):
        """
        Tests that user's login failures lockout counter is not reset upon successful password reset.
        """

        # Adding an entry in LoginFailures to verify the password reset endpoint
        # does not reset the user's login failures lockout counter.
        LoginFailures.increment_lockout_counter(self.user)

        post_request = self.create_reset_request(self.uidb36, self.token,
                                                 False)
        post_request.user = AnonymousUser()
        reset_view = LogistrationPasswordResetView.as_view()
        reset_view(post_request, uidb36=self.uidb36, token=self.token).render()

        # Verify that the user's login failures lockout count is not reset.
        assert not LoginFailures.is_feature_enabled()
        assert LoginFailures.is_user_locked_out(self.user)