From 96d38b8189bcce5f8be0f01d2c3148ee3ba7337b Mon Sep 17 00:00:00 2001 From: Nicholas Staples Date: Fri, 22 Jan 2016 16:34:36 +0000 Subject: [PATCH] Added check for password on service change page, work in progress. --- app/main/dao/users_dao.py | 4 + app/main/forms.py | 9 ++ app/main/views/service_settings.py | 23 ++-- app/main/views/user_profile.py | 142 +++++++++++----------- tests/app/main/views/test_user_profile.py | 34 +++--- 5 files changed, 119 insertions(+), 93 deletions(-) diff --git a/app/main/dao/users_dao.py b/app/main/dao/users_dao.py index b08b09c5c..357382632 100644 --- a/app/main/dao/users_dao.py +++ b/app/main/dao/users_dao.py @@ -38,6 +38,10 @@ def verify_password(user, password): return user_api_client.verify_password(user, password) +def update_user(user): + return user_api_client.update_user(user) + + def increment_failed_login_count(id): user = get_user_by_id(id) user.failed_login_count += 1 diff --git a/app/main/forms.py b/app/main/forms.py index 1edf1ceb9..3acc41cdf 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -186,8 +186,17 @@ class ServiceNameForm(Form): class ConfirmPasswordForm(Form): + + def __init__(self, validate_password_func, *args, **kwargs): + self.validate_password_func = validate_password_func + super(ConfirmPasswordForm, self).__init__(*args, **kwargs) + password = PasswordField(u'Enter password') + def validate_password(self, field): + if not self.validate_password_func(field.data): + raise ValidationError('Invalid password') + class TemplateForm(Form): name = StringField( diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 412e2844d..81e218227 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -1,10 +1,11 @@ from flask import ( render_template, redirect, request, url_for, abort, session) -from flask_login import login_required +from flask_login import (login_required, current_user) from app.main import main from app.main.dao.services_dao import ( get_service_by_id, delete_service, update_service) +from app.main.dao.users_dao import verify_password from app.main.forms import ConfirmPasswordForm, ServiceNameForm from client.errors import HTTPError @@ -61,7 +62,10 @@ def service_name_change_confirm(service_id): else: raise e - form = ConfirmPasswordForm() + # Validate password for form + def _check_password(pwd): + return verify_password(current_user, pwd) + form = ConfirmPasswordForm(_check_password) if form.validate_on_submit(): service['name'] = session['service_name_change'] @@ -128,9 +132,10 @@ def service_status_change_confirm(service_id): else: raise e - # TODO validate password, will leave until - # user management has been moved to the api. - form = ConfirmPasswordForm() + # Validate password for form + def _check_password(pwd): + return verify_password(current_user, pwd) + form = ConfirmPasswordForm(_check_password) if form.validate_on_submit(): service['active'] = True @@ -175,9 +180,11 @@ def service_delete_confirm(service_id): abort(404) else: raise e - # TODO validate password, will leave until - # user management has been moved to the api. - form = ConfirmPasswordForm() + + # Validate password for form + def _check_password(pwd): + return verify_password(current_user, pwd) + form = ConfirmPasswordForm(_check_password) if form.validate_on_submit(): try: diff --git a/app/main/views/user_profile.py b/app/main/views/user_profile.py index 7053cf04c..721affc9d 100644 --- a/app/main/views/user_profile.py +++ b/app/main/views/user_profile.py @@ -1,6 +1,7 @@ from flask import request, render_template, redirect, url_for from flask.ext.login import current_user from app.main import main +from app.main.dao.users_dao import (verify_password, update_user) from app.main.forms import ( ChangePasswordForm, ChangeNameForm, ChangeEmailForm, ConfirmEmailForm, ChangeMobileNumberForm, ConfirmMobileNumberForm, ConfirmPasswordForm @@ -15,125 +16,130 @@ def user_profile(): @main.route("/user-profile/name", methods=['GET', 'POST']) def user_profile_name(): - form = ChangeNameForm() + form = ChangeNameForm(new_name=current_user.name) - if request.method == 'GET': - if current_user.is_authenticated(): - form.new_name.data = current_user.name - return render_template( - 'views/user-profile/change.html', - thing='name', - form_field=form.new_name - ) - elif request.method == 'POST': + if form.validate_on_submit(): + current_user.name = form.new_name + update_user(current_user) return redirect(url_for('.user_profile')) + return render_template( + 'views/user-profile/change.html', + thing='name', + form_field=form.new_name + ) + @main.route("/user-profile/email", methods=['GET', 'POST']) def user_profile_email(): - form = ChangeEmailForm() + form = ChangeEmailForm(email_address=current_user.email_address) - if request.method == 'GET': - if current_user.is_authenticated(): - form.email_address.data = current_user.email_address - return render_template( - 'views/user-profile/change.html', - thing='email address', - form_field=form.email_address - ) - elif request.method == 'POST': + if form.validate_on_submit(): + # TODO update session with password confirm return redirect(url_for('.user_profile_email_authenticate')) + return render_template( + 'views/user-profile/change.html', + thing='email address', + form_field=form.email_address + ) + @main.route("/user-profile/email/authenticate", methods=['GET', 'POST']) def user_profile_email_authenticate(): - form = ConfirmPasswordForm() + # Validate password for form + def _check_password(pwd): + return verify_password(current_user, pwd) + form = ConfirmPasswordForm(_check_password) - if request.method == 'GET': - return render_template( - 'views/user-profile/authenticate.html', - thing='email address', - form=form, - back_link=url_for('.user_profile_email') - ) - elif request.method == 'POST': + if form.validate_on_submit(): return redirect(url_for('.user_profile_email_confirm')) + return render_template( + 'views/user-profile/authenticate.html', + thing='email address', + form=form, + back_link=url_for('.user_profile_email') + ) + @main.route("/user-profile/email/confirm", methods=['GET', 'POST']) def user_profile_email_confirm(): form = ConfirmEmailForm() - if request.method == 'GET': - return render_template( - 'views/user-profile/confirm.html', - form_field=form.email_code, - thing='email address' - ) - elif request.method == 'POST': + if form.validate_on_submit(): return redirect(url_for('.user_profile')) + return render_template( + 'views/user-profile/confirm.html', + form_field=form.email_code, + thing='email address' + ) + @main.route("/user-profile/mobile-number", methods=['GET', 'POST']) def user_profile_mobile_number(): - form = ChangeMobileNumberForm() + form = ChangeMobileNumberForm(mobile_number=current_user.mobile_number) - if request.method == 'GET': - if current_user.is_authenticated(): - form.mobile_number.data = current_user.mobile_number - return render_template( - 'views/user-profile/change.html', - thing='mobile number', - form_field=form.mobile_number - ) - elif request.method == 'POST': + if form.validate_on_submit(): + # update session with this step return redirect(url_for('.user_profile_mobile_number_authenticate')) + return render_template( + 'views/user-profile/change.html', + thing='mobile number', + form_field=form.mobile_number + ) + @main.route("/user-profile/mobile-number/authenticate", methods=['GET', 'POST']) def user_profile_mobile_number_authenticate(): - form = ConfirmPasswordForm() + # Validate password for form + def _check_password(pwd): + return verify_password(current_user, pwd) + form = ConfirmPasswordForm(_check_password) - if request.method == 'GET': - return render_template( - 'views/user-profile/authenticate.html', - thing='mobile number', - form=form, - back_link=url_for('.user_profile_mobile_number_confirm') - ) - elif request.method == 'POST': + if form.validate_on_submit(): + # Update mobile number return redirect(url_for('.user_profile_mobile_number_confirm')) + return render_template( + 'views/user-profile/authenticate.html', + thing='mobile number', + form=form, + back_link=url_for('.user_profile_mobile_number_confirm') + ) + @main.route("/user-profile/mobile-number/confirm", methods=['GET', 'POST']) def user_profile_mobile_number_confirm(): form = ConfirmMobileNumberForm() - if request.method == 'GET': - return render_template( - 'views/user-profile/confirm.html', - form_field=form.sms_code, - thing='mobile number' - ) - elif request.method == 'POST': + if form.validate_on_submit(): return redirect(url_for('.user_profile')) + return render_template( + 'views/user-profile/confirm.html', + form_field=form.sms_code, + thing='mobile number' + ) + @main.route("/user-profile/password", methods=['GET', 'POST']) def user_profile_password(): form = ChangePasswordForm() - if request.method == 'GET': - return render_template( - 'views/user-profile/change-password.html', - form=form - ) - elif request.method == 'POST': + if form.validate_on_submit(): return redirect(url_for('.user_profile')) + + return render_template( + 'views/user-profile/change-password.html', + form=form + ) diff --git a/tests/app/main/views/test_user_profile.py b/tests/app/main/views/test_user_profile.py index b2a8f278b..7c7acc20f 100644 --- a/tests/app/main/views/test_user_profile.py +++ b/tests/app/main/views/test_user_profile.py @@ -1,39 +1,39 @@ -def test_should_show_overview_page(app_): +def test_should_show_overview_page(app_, db_, db_session): response = app_.test_client().get('/user-profile') assert 'Your profile' in response.get_data(as_text=True) assert response.status_code == 200 -def test_should_show_name_page(app_): +def test_should_show_name_page(app_, db_, db_session): response = app_.test_client().get('/user-profile/name') assert 'Change your name' in response.get_data(as_text=True) assert response.status_code == 200 -def test_should_redirect_after_name_change(app_): +def test_should_redirect_after_name_change(app_, db_, db_session): response = app_.test_client().post('/user-profile/name') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile' -def test_should_show_email_page(app_): +def test_should_show_email_page(app_, db_, db_session): response = app_.test_client().get('/user-profile/email') assert 'Change your email address' in response.get_data(as_text=True) assert response.status_code == 200 -def test_should_redirect_after_email_change(app_): +def test_should_redirect_after_email_change(app_, db_, db_session): response = app_.test_client().post('/user-profile/email') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile/email/authenticate' -def test_should_show_authenticate_after_email_change(app_): +def test_should_show_authenticate_after_email_change(app_, db_, db_session): response = app_.test_client().get('/user-profile/email/authenticate') assert 'Change your email address' in response.get_data(as_text=True) @@ -41,14 +41,14 @@ def test_should_show_authenticate_after_email_change(app_): assert response.status_code == 200 -def test_should_redirect_after_email_change_confirm(app_): +def test_should_redirect_after_email_change_confirm(app_, db_, db_session): response = app_.test_client().post('/user-profile/email/authenticate') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile/email/confirm' -def test_should_show_confirm_after_email_change(app_): +def test_should_show_confirm_after_email_change(app_, db_, db_session): response = app_.test_client().get('/user-profile/email/confirm') assert 'Change your email address' in response.get_data(as_text=True) @@ -56,28 +56,28 @@ def test_should_show_confirm_after_email_change(app_): assert response.status_code == 200 -def test_should_redirect_after_email_change_confirm(app_): +def test_should_redirect_after_email_change_confirm(app_, db_, db_session): response = app_.test_client().post('/user-profile/email/confirm') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile' -def test_should_show_mobile_number_page(app_): +def test_should_show_mobile_number_page(app_, db_, db_session): response = app_.test_client().get('/user-profile/mobile-number') assert 'Change your mobile number' in response.get_data(as_text=True) assert response.status_code == 200 -def test_should_redirect_after_mobile_number_change(app_): +def test_should_redirect_after_mobile_number_change(app_, db_, db_session): response = app_.test_client().post('/user-profile/email') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile/email/authenticate' -def test_should_show_authenticate_after_mobile_number_change(app_): +def test_should_show_authenticate_after_mobile_number_change(app_, db_, db_session): response = app_.test_client().get('/user-profile/mobile-number/authenticate') assert 'Change your mobile number' in response.get_data(as_text=True) @@ -85,14 +85,14 @@ def test_should_show_authenticate_after_mobile_number_change(app_): assert response.status_code == 200 -def test_should_redirect_after_mobile_number_authenticate(app_): +def test_should_redirect_after_mobile_number_authenticate(app_, db_, db_session): response = app_.test_client().post('/user-profile/mobile-number/authenticate') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile/mobile-number/confirm' -def test_should_show_confirm_after_mobile_number_change(app_): +def test_should_show_confirm_after_mobile_number_change(app_, db_, db_session): response = app_.test_client().get('/user-profile/mobile-number/confirm') assert 'Change your mobile number' in response.get_data(as_text=True) @@ -100,21 +100,21 @@ def test_should_show_confirm_after_mobile_number_change(app_): assert response.status_code == 200 -def test_should_redirect_after_mobile_number_confirm(app_): +def test_should_redirect_after_mobile_number_confirm(app_, db_, db_session): response = app_.test_client().post('/user-profile/mobile-number/confirm') assert response.status_code == 302 assert response.location == 'http://localhost/user-profile' -def test_should_show_password_page(app_): +def test_should_show_password_page(app_, db_, db_session): response = app_.test_client().get('/user-profile/password') assert 'Change your password' in response.get_data(as_text=True) assert response.status_code == 200 -def test_should_redirect_after_password_change(app_): +def test_should_redirect_after_password_change(app_, db_, db_session): response = app_.test_client().post('/user-profile/password') assert response.status_code == 302