def test_reset_password_post_failure_no_user(self): """ Test posting to the password reset form with an anonymous user, a token for a non-existing user, and a valid form. Expected result: The password is not updated and the user is shown a 404 error page. """ password = '******' user = self.create_user(email='*****@*****.**', name='Jane Doe', password=password) token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() db.session.delete(user) db.session.commit() new_password = '******' data = self.post(f'/user/reset-password/{token}', expected_status=404, data=dict(password=new_password, password_confirmation=new_password + 'GHI')) self.assertNotIn('Your password has successfully been changed.', data) self.assertFalse(user.check_password(new_password)) self.assertTrue(user.check_password(password))
def test_reset_password_post_failure_invalid_input(self): """ Test posting to the password reset form with an anonymous user, a valid token, and an invalid form. Expected result: The password is not updated and the user is shown the reset password form. """ email = '*****@*****.**' password = '******' name = 'John Doe' user_id = 1 user = User(email, name) user.set_password(password) db.session.add(user) db.session.commit() self.assertEqual(user_id, user.id) token_obj = ResetPasswordToken() token_obj.user_id = user_id token = token_obj.create() new_password = '******' response = self.client.post(f'/user/reset-password/{token}', follow_redirects=True, data=dict( password=new_password, password_confirmation=new_password + 'ghi' )) data = response.get_data(as_text=True) self.assertIn('Reset Your Password', data) self.assertNotIn('The token is invalid.', data) self.assertNotIn('Your password has successfully been changed.', data) self.assertFalse(user.check_password(new_password)) self.assertTrue(user.check_password(password))
def test_reset_password_post_failure_invalid_input(self): """ Test posting to the password reset form with an anonymous user, a valid token, and an invalid form. Expected result: The password is not updated and the user is shown the reset password form. """ password = '******' user = self.create_user(email='*****@*****.**', name='Jane Doe', password=password) token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() new_password = '******' data = self.post(f'/user/reset-password/{token}', data=dict(password=new_password, password_confirmation=new_password + 'GHI')) self.assertIn('Reset Your Password', data) self.assertNotIn('The token is invalid.', data) self.assertNotIn('Your password has successfully been changed.', data) self.assertFalse(user.check_password(new_password)) self.assertTrue(user.check_password(password))
def test_reset_password_get_logged_in(self): """ Test accessing the password reset form with a user who is logged in, and a valid token. Expected result: The user is redirected to the home page. """ email = '*****@*****.**' password = '******' name = 'John Doe' user_id = 1 user = User(email, name) user.set_password(password) db.session.add(user) db.session.commit() self.assertEqual(user_id, user.id) self.client.post('/user/login', follow_redirects=True, data=dict( email=email, password=password )) token_obj = ResetPasswordToken() token_obj.user_id = user_id token = token_obj.create() response = self.client.get(f'/user/reset-password/{token}', follow_redirects=True) data = response.get_data(as_text=True) self.assertIn('Dashboard', data) self.assertNotIn('The token is invalid.', data) self.assertNotIn('Reset Your Password', data) self.assertNotIn('Your password has successfully been changed.', data)
def test_reset_password_get_success(self): """ Test accessing the password reset form with an anonymous user and a valid token. Expected result: The user password reset form is displayed. """ email = '*****@*****.**' name = 'John Doe' user = User(email, name) db.session.add(user) db.session.commit() token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() response = self.client.get(f'/user/reset-password/{token}', follow_redirects=True) data = response.get_data(as_text=True) self.assertIn('Reset Your Password', data) self.assertIn('New Password', data) self.assertNotIn('The token is invalid.', data) self.assertIn('Confirm Your New Password', data) self.assertNotIn('Your password has successfully been changed.', data)
def request_password_reset(self) -> Optional[ResetPasswordToken]: """ Send a mail for resetting the user's password to their email address. :return: The token send in the mail. """ if self.email is None: return None token_obj = ResetPasswordToken() token_obj.user_id = self.id token = token_obj.create() validity = timedelta_to_minutes(token_obj.get_validity()) link = url_for('userprofile.reset_password', token=token, _external=True) email = Email(_('Reset Your Password'), 'userprofile/emails/reset_password_request') email.prepare(name=self.name, link=link, validity=validity) email.send(self.email) return token_obj
def test_reset_password_get_logged_in(self): """ Test accessing the password reset form with a user who is logged in, and a valid token. Expected result: The user is redirected to the home page. """ user = self.create_and_login_user() token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() data = self.get(f'/user/reset-password/{token}') self.assertIn('Dashboard', data) self.assertNotIn('The token is invalid.', data) self.assertNotIn('Reset Your Password', data) self.assertNotIn('Your password has successfully been changed.', data)
def test_init(self): """ Test initializing a password reset token. Expected result: The token is initialized with emtpy values. """ token = ResetPasswordToken() self.assertIsNotNone(token) self.assertIsNone(token.user_id)
def verify_password_reset_token(token: str) -> Optional['User']: """ Verify a given token for resetting a password. :param token: The password-reset JWT. :return: The user for whom the token is valid. ``None`` if the token is invalid or if outside the application context. """ token_obj = ResetPasswordToken.verify(token) return User.load_from_id(token_obj.user_id)
def test_reset_password_get_failure_no_user(self): """ Test accessing the password reset form with an anonymous user and a token for a non-existing user. Expected result: A 404 error page is shown. """ user = self.create_user(email='*****@*****.**', name='Jane', password='******') token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() db.session.delete(user) db.session.commit() data = self.get(f'/user/reset-password/{token}', expected_status=404) self.assertNotIn('Your password has successfully been changed.', data)
def test_reset_password_get_success(self): """ Test accessing the password reset form with an anonymous user and a valid token. Expected result: The user password reset form is displayed. """ user = self.create_user(email='*****@*****.**', name='Jane', password='******') token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() data = self.get(f'/user/reset-password/{token}') self.assertIn('Reset Your Password', data) self.assertIn('New Password', data) self.assertNotIn('The token is invalid.', data) self.assertIn('Confirm Your New Password', data) self.assertNotIn('Your password has successfully been changed.', data)
def send_password_reset_email(self) -> Optional[ResetPasswordToken]: """ Send a mail for resetting the user's password to their email address. :return: The token send in the mail """ if self.get_email() is None: return None token_obj = ResetPasswordToken() token_obj.user_id = self.id token = token_obj.create() validity = token_obj.get_validity(in_minutes=True) link = url_for('userprofile.reset_password', token=token, _external=True) email = Email(_('Reset Your Password'), 'userprofile/emails/reset_password_request') email.prepare(name=self.name, link=link, validity=validity) email.send(self.get_email()) return token_obj
def test_reset_password_post_logged_in(self): """ Test posting to the password reset form with a user who is logged in, and a valid token. Expected result: The user is redirected to the home page without changing the password. """ password = '******' user = self.create_and_login_user(password=password) token_obj = ResetPasswordToken() token_obj.user_id = user.id token = token_obj.create() new_password = '******' data = self.post(f'/user/reset-password/{token}', data=dict(password=new_password, password_confirmation=new_password)) self.assertIn('Dashboard', data) self.assertNotIn('The token is invalid.', data) self.assertNotIn('Reset Your Password', data) self.assertNotIn('Your password has successfully been changed.', data) self.assertTrue(user.check_password(password))
def verify_password_reset_token(token: str) -> Optional['User']: """ Verify a given token for resetting a password. :param token: The password-reset JWT. :return: The user for whom the token is valid. `None` if the token is invalid or if outside the application context. """ try: token_obj = ResetPasswordToken.verify(token) except EasyJWTError: return None return User.load_from_id(token_obj.user_id) # type: ignore