def test_email_verification(self): """ Test encoding an email, and see if it can be resolved with the verify endpoint """ # Even though we have a a valid token, no user was registered with this # email address. This should never happen in normal use. msg, token = utils.send_email( email_addr="this_email_wasnt@registered", base_url='localhost', email_template=VerificationEmail, payload="this_email_wasnt@registered" ) self.assertIn("localhost", msg.html) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 404) self.assertEqual(r.json['error'],"no user associated with that " "verification token") # Test for an inproperly encoded email, expect 404 r = self.client.get(url+"incorrect") self.assertStatus(r, 404) self.assertEqual(r.json['error'], 'unknown verification token') # Test a valid token with a registered user msg, token = utils.send_email( email_addr=self.real_user.email, email_template=VerificationEmail, payload=self.real_user.email ) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 200) self.assertEqual(r.json["email"], self.real_user.email) self.assertIsInstance(self.real_user.confirmed_at, datetime.date) self.assertAlmostEqual( self.real_user.confirmed_at, datetime.datetime.now(), delta=datetime.timedelta(seconds=1), ) # Test for an already confirmed email r = self.client.get(url) self.assertStatus(r, 400) self.assertEqual(r.json["error"], "this user and email has already " "been validated")
def test_email_verification(self): """ Test encoding an email, and see if it can be resolved with the verify endpoint """ # Even though we have a a valid token, no user was registered with this # email address. This should never happen in normal use. msg, token = utils.send_email(email_addr="this_email_wasnt@registered", base_url='localhost', email_template=VerificationEmail, payload="this_email_wasnt@registered") self.assertIn("localhost", msg.html) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 404) self.assertEqual(r.json['error'], "no user associated with that " "verification token") # Test for an inproperly encoded email, expect 404 r = self.client.get(url + "incorrect") self.assertStatus(r, 404) self.assertEqual(r.json['error'], 'unknown verification token') # Test a valid token with a registered user msg, token = utils.send_email(email_addr=self.real_user.email, email_template=VerificationEmail, payload=self.real_user.email) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 200) self.assertEqual(r.json["email"], self.real_user.email) self.assertIsInstance(self.real_user.confirmed_at, datetime.date) self.assertAlmostEqual( self.real_user.confirmed_at, datetime.datetime.now(), delta=datetime.timedelta(seconds=1), ) # Test for an already confirmed email r = self.client.get(url) self.assertStatus(r, 400) self.assertEqual(r.json["error"], "this user and email has already " "been validated")
def test_reset_password(self): """ test the reset password workflow """ with self.client as c: csrf = self.get_csrf() self.setup_google_recaptcha_response() user_manipulator.update(self.real_user,confirmed_at=datetime.datetime.now()) url = url_for( 'forgotpasswordview', token="this_email_wasnt@registered" ) payload = { 'g-recaptcha-response': 'correct_response', 'reset_url':'http://not_relevant.com', } # Attempt to reset the password for an unregistered email address r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken':csrf} ) self.assertStatus(r, 404) self.assertEqual(r.json['error'], 'no such user exists') # Resetting password for the default user should not be permitted url = url_for( 'forgotpasswordview', token=self.bootstrap_user.email ) r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf} ) self.assertStatus(r, 403) # Test a proper change-email request url = url_for('forgotpasswordview', token=self.real_user.email) r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf} ) self.assertStatus(r, 200) # Now let's test GET and PUT requests with the encoded token msg, token = utils.send_email( email_addr=self.real_user.email, email_template=PasswordResetEmail, payload=self.real_user.email ) url = url_for('forgotpasswordview', token=token) # Test de-coding and verifying of the token r = c.get(url) self.assertStatus(r, 200) self.assertEqual(r.json['email'], self.real_user.email) # Change the password, then attempt to log-in with the new password payload = {'password1': '123Abc', 'password2': '123Abc'} r = c.put( url, data=json.dumps(payload), headers={'X-CSRFToken':csrf} ) self.assertStatus(r, 200) url = url_for('userauthview') payload = {'username': self.real_user.email,'password':'******'} r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf} ) self.assertStatus(r, 200) self.assertEqual(current_user.email, self.real_user.email)
def test_change_email(self): """ Test the change email workflow. The workflow is tightly coupled with the verify-email workflow, which should be de-coupled by using signals in the future """ url = url_for('changeemailview') with self.client as c: csrf = self.get_csrf() self.setup_google_recaptcha_response() # Unauthenticated should return 401 r = c.post(url, headers={'X-CSRFToken': csrf}) self.assertStatus(r, 401) self.login(self.real_user, c, csrf) # incorrect password, even though we're logged in should return 401 payload = { 'email': self.real_user.email, 'password': '******', 'verify_url': 'http://not_relevant.com' } r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}, ) self.assertStatus(r, 401) # correct password, but that email is already registered payload = { 'email': self.bootstrap_user.email, 'password': self.passwords[self.real_user], 'verify_url': 'http://not_relevant.com' } r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}, ) self.assertStatus(r, 403) # valid end-to-end workflow previous_email = self.real_user.email payload = { 'email': 'changed@email', 'password': self.passwords[self.real_user], 'verify_url': 'http://not_relevant.com' } r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf} ) self.assertStatus(r, 200) u = user_manipulator.first(email='changed@email') self.assertIsNotNone(u) self.assertIsNone(u.confirmed_at) self.assertIsNotNone( user_manipulator.first(email=previous_email) ) self.assertIsNotNone( user_manipulator.first(email=previous_email).confirmed_at ) self.assertNotEqual(self.real_user.email, "changed@email") # Get the token that this view will send, send it to the # verfication email endpoint, and check that the user's email # was correctly updated msg, token = utils.send_email( email_addr="changed@email", email_template=VerificationEmail, payload = ["changed@email", self.real_user.id], ) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 200) self.assertIsNone( user_manipulator.first(email=previous_email) ) self.assertEqual(self.real_user.email, "changed@email")
def test_reset_password(self): """ test the reset password workflow """ with self.client as c: csrf = self.get_csrf() self.setup_google_recaptcha_response() user_manipulator.update(self.real_user, confirmed_at=datetime.datetime.now()) url = url_for('forgotpasswordview', token="this_email_wasnt@registered") payload = { 'g-recaptcha-response': 'correct_response', 'reset_url': 'http://not_relevant.com', } # Attempt to reset the password for an unregistered email address r = c.post(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 404) self.assertEqual(r.json['error'], 'no such user exists') # Resetting password for the default user should not be permitted url = url_for('forgotpasswordview', token=self.bootstrap_user.email) r = c.post(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 403) # Test a proper change-email request url = url_for('forgotpasswordview', token=self.real_user.email) r = c.post(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 200) # Now let's test GET and PUT requests with the encoded token msg, token = utils.send_email(email_addr=self.real_user.email, email_template=PasswordResetEmail, payload=self.real_user.email) url = url_for('forgotpasswordview', token=token) # Test de-coding and verifying of the token r = c.get(url) self.assertStatus(r, 200) self.assertEqual(r.json['email'], self.real_user.email) # Change the password, then attempt to log-in with the new password payload = {'password1': '123Abc', 'password2': '123Abc'} r = c.put(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 200) url = url_for('userauthview') payload = {'username': self.real_user.email, 'password': '******'} r = c.post(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 200) self.assertEqual(current_user.email, self.real_user.email)
def test_change_email(self): """ Test the change email workflow. The workflow is tightly coupled with the verify-email workflow, which should be de-coupled by using signals in the future """ url = url_for('changeemailview') with self.client as c: csrf = self.get_csrf() self.setup_google_recaptcha_response() # Unauthenticated should return 401 r = c.post(url, headers={'X-CSRFToken': csrf}) self.assertStatus(r, 401) self.login(self.real_user, c, csrf) # incorrect password, even though we're logged in should return 401 payload = { 'email': self.real_user.email, 'password': '******', 'verify_url': 'http://not_relevant.com' } r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}, ) self.assertStatus(r, 401) # correct password, but that email is already registered payload = { 'email': self.bootstrap_user.email, 'password': self.passwords[self.real_user], 'verify_url': 'http://not_relevant.com' } r = c.post( url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}, ) self.assertStatus(r, 403) # valid end-to-end workflow previous_email = self.real_user.email payload = { 'email': 'changed@email', 'password': self.passwords[self.real_user], 'verify_url': 'http://not_relevant.com' } r = c.post(url, data=json.dumps(payload), headers={'X-CSRFToken': csrf}) self.assertStatus(r, 200) u = user_manipulator.first(email='changed@email') self.assertIsNotNone(u) self.assertIsNone(u.confirmed_at) self.assertIsNotNone(user_manipulator.first(email=previous_email)) self.assertIsNotNone( user_manipulator.first(email=previous_email).confirmed_at) self.assertNotEqual(self.real_user.email, "changed@email") # Get the token that this view will send, send it to the # verfication email endpoint, and check that the user's email # was correctly updated msg, token = utils.send_email( email_addr="changed@email", email_template=VerificationEmail, payload=["changed@email", self.real_user.id], ) url = url_for('verifyemailview', token=token) r = self.client.get(url) self.assertStatus(r, 200) self.assertIsNone(user_manipulator.first(email=previous_email)) self.assertEqual(self.real_user.email, "changed@email")