def test_authenticate(self): """Can a user be authenticated? """ user1 = create_account('user1', '*****@*****.**', 'Password') self.assertIsNotNone(user1) # Check authenticate self.assertEqual(authenticate('user1', 'Password').get('_id'), user1) # Check auth with e-mail self.assertEqual(authenticate('*****@*****.**', 'Password').get('_id'), user1) # Case in-sensitive test self.assertEqual(authenticate('USER1', 'Password').get('_id'), user1) self.assertEqual(authenticate('*****@*****.**', 'Password').get('_id'), user1) # Ensure case in-sensitive password does NOT WORK self.assertIsNone(authenticate('user1', 'password')) self.assertIsNone(authenticate('user1', 'PASSWORD')) # Check incorrect password self.assertIsNone(authenticate('user1', 'Pass')) # Check non-existent user self.assertIsNone(authenticate('userX', 'Password')) # Check no glob username self.assertIsNone(authenticate('use*', 'Password')) # Check no glob password (just to be safe) self.assertIsNone(authenticate('user1', 'Passw*'))
def test_authenticate(self): """Can a user be authenticated? """ user1 = create_account('user1', '*****@*****.**', 'Password') self.assertIsNotNone(user1) # Check authenticate self.assertEqual(authenticate('user1', 'Password').get('_id'), user1) # Check auth with e-mail self.assertEqual( authenticate('*****@*****.**', 'Password').get('_id'), user1) # Case in-sensitive test self.assertEqual(authenticate('USER1', 'Password').get('_id'), user1) self.assertEqual( authenticate('*****@*****.**', 'Password').get('_id'), user1) # Ensure case in-sensitive password does NOT WORK self.assertIsNone(authenticate('user1', 'password')) self.assertIsNone(authenticate('user1', 'PASSWORD')) # Check incorrect password self.assertIsNone(authenticate('user1', 'Pass')) # Check non-existent user self.assertIsNone(authenticate('userX', 'Password')) # Check no glob username self.assertIsNone(authenticate('use*', 'Password')) # Check no glob password (just to be safe) self.assertIsNone(authenticate('user1', 'Passw*'))
def delete_account(): """ View the user uses to delete their account. Once the user has submitted the form and their password has been validated there is no turning back. They will receive an e-mail to confirm the account deletion. """ form = ConfirmPasswordForm(request.form) if request.method == 'POST': if authenticate(current_user['username'], form.password.data): uid = current_user['uid'] email = current_user['email'] # Log the current user out logout() # Delete the account be_delete_account(uid) # Inform the user that the account has/is being deleted flash('Your account has been deleted<br />Thanks for using us', 'information') # Send the user their last ever email on Pjuu send_mail( 'Pjuu Account Notification - Account Deletion', [email], text_body=render_template('emails/account_deletion.txt'), html_body=render_template('emails/account_deletion.html') ) # Send user back to login return redirect(url_for('signin')) else: flash('Oops! wrong password', 'error') return render_template('delete_account.html', form=form)
def signin(): """ """ form = SignInForm(request.form) if request.method == 'POST': # Handles the passing of the next argument to the login view redirect_url = handle_next(request, url_for('users.feed')) if form.validate(): # Calls authenticate from backend.py user = authenticate(form.username.data, form.password.data) if user: # Ensure the user is active if not user.get('active', False): flash('Please activate your account<br />' 'Check your e-mail', 'information') # Ensure the user is not banned elif user.get('banned', False): flash('You\'re a very naughty boy!', 'error') # All OK log the user in else: # We will also make the session permanent if the user # has requested too session.permanent = form.keep_signed_in.data be_signin(user.get('_id')) return redirect(redirect_url) else: flash('Invalid user name or password', 'error') else: flash('Invalid user name or password', 'error') return render_template('signin.html', form=form)
def delete_account(): """ """ form = ConfirmPasswordForm(request.form) if request.method == 'POST': if authenticate(current_user['username'], form.password.data): uid = current_user['_id'] email = current_user['email'] # Log the current user out be_signout() # Delete the account be_delete_account(uid) # Inform the user that the account has/is being deleted flash('Your account is being deleted<br />Thanks for using us', 'information') # Send the user their last ever email on Pjuu send_mail( 'Pjuu Account Notification - Account Deletion', [email], text_body=render_template('emails/account_deletion.txt'), html_body=render_template('emails/account_deletion.html')) # Send user back to login return redirect(url_for('auth.signin')) else: flash('Oops! wrong password', 'error') return render_template('delete_account.html', form=form)
def signin(): """ """ form = SignInForm(request.form) if request.method == 'POST': # Handles the passing of the next argument to the login view redirect_url = handle_next(request, url_for('users.feed')) if form.validate(): # Calls authenticate from backend.py user = authenticate(form.username.data, form.password.data) if user: # Ensure the user is active if not user.get('active', False): flash( 'Please activate your account<br />' 'Check your e-mail', 'information') # Ensure the user is not banned elif user.get('banned', False): flash('You\'re a very naughty boy!', 'error') # All OK log the user in else: # We will also make the session permanent if the user # has requested too session.permanent = form.keep_signed_in.data be_signin(user.get('_id')) return redirect(redirect_url) else: flash('Invalid user name or password', 'error') else: flash('Invalid user name or password', 'error') return render_template('signin.html', form=form)
def signin(): """ Logs a user in. Will authenticate username/password, check account activation and if the user is banned or not before setting user_id in session. """ form = SignInForm(request.form) if request.method == 'POST': # Handles the passing of the next argument to the login view redirect_url = handle_next(request, url_for('feed')) if form.validate(): # Calls authenticate from backend.py uid = authenticate(form.username.data, form.password.data) if uid: # Ensure the user is active if not is_active(uid): flash('Please activate your account<br />' 'Check your e-mail', 'information') # Ensure the user is not banned elif is_banned(uid): flash('You\'re a very naughty boy!', 'error') # All OK log the user in else: # We will also make the session permanent if the user # has requested too session.permanent = form.keep_signed_in.data login(uid) return redirect(redirect_url) else: flash('Invalid user name or password', 'error') else: flash('Invalid user name or password', 'error') return render_template('signin.html', form=form)
def test_change_password(self): """Can a user change password? There is no sanity or restrictions on passwords in the backend. """ user1 = create_account('user1', '*****@*****.**', 'Password') # Take current password (is hash don't string compare) current_password = get_user(user1).get('password') # Change password self.assertIsNotNone(change_password(user1, 'Password1')) new_password = get_user(user1).get('password') # Just check the hashed are different self.assertNotEqual(current_password, new_password) # Make sure the old password does not authenticate self.assertIsNone(authenticate('user1', 'Password')) # Check new password lets us log in self.assertEqual(authenticate('user1', 'Password1').get('_id'), user1)
def dump_account(): """ """ form = ConfirmPasswordForm(request.form) if request.method == 'POST': if authenticate(current_user['username'], form.password.data): # Dump the users account data = be_dump_account(current_user['uid']) # JSONify the data and display it to the user :) simple return jsonify(data) else: flash('Oops! wrong password', 'error') return render_template('dump_account.html', form=form)
def dump_account(): """Enables the user to dump a JSON representation of their account. """ form = ConfirmPasswordForm(request.form) if request.method == 'POST': if authenticate(current_user['username'], form.password.data): # Dump the users account data = be_dump_account(current_user['_id']) # JSONify the data and display it to the user :) simple return jsonify(data) else: flash('Oops! wrong password', 'error') return render_template('dump_account.html', form=form)
def test_delete_account_basic(self): """Does the basic data go when a user delete their account? ..note: Just checks the auth part. """ user1 = create_account('user1', '*****@*****.**', 'Password') self.assertIsNotNone(user1) delete_account(user1) self.assertIsNone(get_user(user1)) self.assertIsNone(get_uid_username('user1')) self.assertIsNone(get_uid_email('*****@*****.**')) self.assertFalse(authenticate('user1', 'Password')) self.assertIsNone(get_uid_username('user1')) self.assertIsNone(get_uid_email('*****@*****.**'))
def validate_password(form, field): if not authenticate(current_user['username'], field.data): raise ValidationError('Invalid password')
def validate_password(self, field): if not authenticate(current_user['username'], field.data): raise ValidationError('Invalid password')
def test_forgot_reset(self): """ Test forgotten password and the password reset form. """ # Test that we can GET the forgot page resp = self.client.get(url_for("auth.forgot")) self.assertEqual(resp.status_code, 200) # Try and post data to the form even though we don't have a user. # This will work as the form will always return the same response # this is to stop users trying to recover random details resp = self.client.post(url_for("auth.forgot"), data={"username": "******"}, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn("If we've found your account we've", resp.data) # Let's make sure there is no X-Pjuu-Token header added as one should # not be generated for a non existant user self.assertIsNone(resp.headers.get("X-Pjuu-Token")) # Same test with e-mail resp = self.client.post(url_for("auth.forgot"), data={"username": "******"}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn("If we've found your account we've", resp.data) self.assertIsNone(resp.headers.get("X-Pjuu-Token")) # Lets do this again but with a user (this is the only way to test # password resetting) create_account("user1", "*****@*****.**", "Password") # Lets do the above test again but with this new user resp = self.client.post(url_for("auth.forgot"), data={"username": "******"}, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn("If we've found your account we've", resp.data) # This time we should have a token token = resp.headers.get("X-Pjuu-Token") self.assertIsNotNone(token) # Same test with e-mail resp = self.client.post(url_for("auth.forgot"), data={"username": "******"}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn("If we've found your account we've", resp.data) token = resp.headers.get("X-Pjuu-Token") self.assertIsNotNone(token) # Now we will try and change the password on our account # Lets just make sure we can get to the reset view with our token resp = self.client.get(url_for("auth.reset", token=token)) self.assertEqual(resp.status_code, 200) # Lets make sure the form tells us when we have filled it in wrong # Attempt to set a mis matching password resp = self.client.post( url_for("auth.reset", token=token), data={"password": "******", "password2": "PasswordTwo"}, follow_redirects=True, ) self.assertEqual(resp.status_code, 200) self.assertIn("Oh no! There are errors in your form", resp.data) # Attempt to not even fill the form in resp = self.client.post(url_for("auth.reset", token=token), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn("Oh no! There are errors in your form", resp.data) # Test reset with an invalid token resp = self.client.post(url_for("auth.reset", token="token"), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn("Invalid token", resp.data) # Lets post to the view and change the password. # This also confirms the preservation of the auth tokens resp = self.client.post( url_for("auth.reset", token=token), data={"password": "******", "password2": "NewPassword"}, follow_redirects=True, ) # This should redirect us back to the signin view as well as have # changed out password self.assertEqual(resp.status_code, 200) self.assertIn("Your password has now been reset", resp.data) # We will just check we can log in with the new Password not password self.assertTrue(authenticate("user1", "NewPassword")) # I know, I know this is tested in the backend buts let's make sure # we can't auth with the old password self.assertFalse(authenticate("test", "Password")) # Test an error is thrown if not username or email in entered resp = self.client.post(url_for("auth.forgot"), data={"username": ""}, follow_redirects=True) self.assertIn("Please enter a username or e-mail address", resp.data)
def test_forgot_reset(self): """ Test forgotten password and the password reset form. """ # Test that we can GET the forgot page resp = self.client.get(url_for('auth.forgot')) self.assertEqual(resp.status_code, 200) # Try and post data to the form even though we don't have a user. # This will work as the form will always return the same response # this is to stop users trying to recover random details resp = self.client.post(url_for('auth.forgot'), data={ 'username': '******' }, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) # Let's make sure there is no X-Pjuu-Token header added as one should # not be generated for a non existant user self.assertIsNone(resp.headers.get('X-Pjuu-Token')) # Lets do this again but with a user (this is the only way to test # password resetting) create_account('user1', '*****@*****.**', 'Password') # Lets do the above test again but with this new user resp = self.client.post(url_for('auth.forgot'), data={ 'username': '******' }, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) # This time we should have a token token = resp.headers.get('X-Pjuu-Token') self.assertIsNotNone(token) # Now we will try and change the password on our account # Lets just make sure we can get to the reset view with our token resp = self.client.get(url_for('auth.reset', token=token)) self.assertEqual(resp.status_code, 200) # Lets make sure the form tells us when we have filled it in wrong # Attempt to set a mis matching password resp = self.client.post(url_for('auth.reset', token=token), data={ 'password': '******', 'password2': 'PasswordTwo' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oh no! There are errors in your form', resp.data) # Attempt to not even fill the form in resp = self.client.post(url_for('auth.reset', token=token), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oh no! There are errors in your form', resp.data) # Test reset with an invalid token resp = self.client.post(url_for('auth.reset', token='token'), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid token', resp.data) # Lets post to the view and change the password. # This also confirms the preservation of the auth tokens resp = self.client.post(url_for('auth.reset', token=token), data={ 'password': '******', 'password2': 'NewPassword' }, follow_redirects=True) # This should redirect us back to the signin view as well as have # changed out password self.assertEqual(resp.status_code, 200) self.assertIn('Your password has now been reset', resp.data) # We will just check we can log in with the new Password not password self.assertTrue(authenticate('user1', 'NewPassword')) # I know, I know this is tested in the backend buts let's make sure # we can't auth with the old password self.assertFalse(authenticate('test', 'Password'))
def test_forgot_reset(self): """ Test forgotten password and the password reset form. """ # Test that we can GET the forgot page resp = self.client.get(url_for('auth.forgot')) self.assertEqual(resp.status_code, 200) # Try and post data to the form even though we don't have a user. # This will work as the form will always return the same response # this is to stop users trying to recover random details resp = self.client.post(url_for('auth.forgot'), data={'username': '******'}, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) # Let's make sure there is no X-Pjuu-Token header added as one should # not be generated for a non existant user self.assertIsNone(resp.headers.get('X-Pjuu-Token')) # Same test with e-mail resp = self.client.post(url_for('auth.forgot'), data={'username': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) self.assertIsNone(resp.headers.get('X-Pjuu-Token')) # Lets do this again but with a user (this is the only way to test # password resetting) create_account('user1', '*****@*****.**', 'Password') # Lets do the above test again but with this new user resp = self.client.post(url_for('auth.forgot'), data={'username': '******'}, follow_redirects=True) # We should be redirect to login and a message flashed self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) # This time we should have a token token = resp.headers.get('X-Pjuu-Token') self.assertIsNotNone(token) # Same test with e-mail resp = self.client.post(url_for('auth.forgot'), data={'username': '******'}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('If we\'ve found your account we\'ve', resp.data) token = resp.headers.get('X-Pjuu-Token') self.assertIsNotNone(token) # Now we will try and change the password on our account # Lets just make sure we can get to the reset view with our token resp = self.client.get(url_for('auth.reset', token=token)) self.assertEqual(resp.status_code, 200) # Lets make sure the form tells us when we have filled it in wrong # Attempt to set a mis matching password resp = self.client.post(url_for('auth.reset', token=token), data={ 'password': '******', 'password2': 'PasswordTwo' }, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oh no! There are errors in your form', resp.data) # Attempt to not even fill the form in resp = self.client.post(url_for('auth.reset', token=token), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Oh no! There are errors in your form', resp.data) # Test reset with an invalid token resp = self.client.post(url_for('auth.reset', token='token'), data={}, follow_redirects=True) self.assertEqual(resp.status_code, 200) self.assertIn('Invalid token', resp.data) # Lets post to the view and change the password. # This also confirms the preservation of the auth tokens resp = self.client.post(url_for('auth.reset', token=token), data={ 'password': '******', 'password2': 'NewPassword' }, follow_redirects=True) # This should redirect us back to the signin view as well as have # changed out password self.assertEqual(resp.status_code, 200) self.assertIn('Your password has now been reset', resp.data) # We will just check we can log in with the new Password not password self.assertTrue(authenticate('user1', 'NewPassword')) # I know, I know this is tested in the backend buts let's make sure # we can't auth with the old password self.assertFalse(authenticate('test', 'Password'))