diff --git a/app/__init__.py b/app/__init__.py index 333a108b3..7a5730483 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -34,7 +34,7 @@ def create_app(config_name): init_csrf(application) login_manager.init_app(application) - login_manager.login_view = 'main.sign_in.render_sign_in' + # login_manager.login_view = 'main.sign_in.render_sign_in' from app.main import main as main_blueprint application.register_blueprint(main_blueprint) diff --git a/app/main/dao/users_dao.py b/app/main/dao/users_dao.py index d4d3a0b42..83521985e 100644 --- a/app/main/dao/users_dao.py +++ b/app/main/dao/users_dao.py @@ -30,3 +30,10 @@ def increment_failed_login_count(id): user = User.query.filter_by(id=id).first() user.failed_login_count += 1 db.session.commit() + + +def activate_user(id): + user = get_user_by_id(id) + user.state = 'active' + db.session.add(user) + db.session.commit() diff --git a/app/main/forms.py b/app/main/forms.py index 874126341..92ec1b8c5 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -39,5 +39,7 @@ class RegisterUserForm(Form): class VerifyForm(Form): - sms_code = IntegerField(DataRequired(message='SMS code can not be empty')) - email_code = IntegerField(DataRequired(message='Email code can not be empty')) + sms_code = IntegerField("Text message confirmation code", + validators=[DataRequired(message='SMS code can not be empty')]) + email_code = IntegerField("Email confirmation code", + validators=[DataRequired(message='Email code can not be empty')]) diff --git a/app/main/views/register.py b/app/main/views/register.py index 48c9d68fa..953d514b5 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -36,6 +36,7 @@ def process_register(): session['email_code'] = hashpw(email_code) session['expiry_date'] = str(datetime.now() + timedelta(hours=1)) users_dao.insert_user(user) + session['user_id'] = user.id except AdminApiClientException as e: return jsonify(admin_api_client_error=e.value) except SQLAlchemyError: diff --git a/app/main/views/verify.py b/app/main/views/verify.py index 8317fa55c..4e627d0a7 100644 --- a/app/main/views/verify.py +++ b/app/main/views/verify.py @@ -1,6 +1,8 @@ -from app.main import main from flask import render_template, redirect, jsonify, session +from flask_login import login_user +from app.main import main +from app.main.dao import users_dao from app.main.encryption import checkpw from app.main.forms import VerifyForm @@ -13,15 +15,18 @@ def render_verify(): @main.route('/verify', methods=['POST']) def process_verify(): form = VerifyForm() - if form.validate_on_submit(): valid_sms = checkpw(form.sms_code.data, session['sms_code']) valid_email = checkpw(form.email_code.data, session['email_code']) if valid_sms is False: - return jsonify(sms_code='invalid'), 400 + return jsonify(sms_code='does not match'), 400 if valid_email is False: - return jsonify(email_code='invalid'), 400 + return jsonify(email_code='does not match'), 400 else: return jsonify(form.errors), 400 + user = users_dao.get_user_by_id(session['user_id']) + users_dao.activate_user(user.id) + login_user(user) + return redirect('/add-service') diff --git a/app/templates/verify.html b/app/templates/verify.html index a6ab5b8f5..0248e2348 100644 --- a/app/templates/verify.html +++ b/app/templates/verify.html @@ -12,20 +12,23 @@ GOV.UK Notify | Confirm email address and mobile number

We've sent you confirmation codes by email and text message. You need to enter both codes here.

-

-

-

-

+
+ {{ form.hidden_tag() }} +

+ + {{ form.email_code(class="form-control-1-4", autocomplete="off") }}
+ I haven't received an email +

+

+ + {{ form.sms_code(class="form-control-1-4", autocomplete="off") }}
+ I haven't received a text +

-

- Continue -

+

+ +

+
diff --git a/tests/app/main/dao/test_users_dao.py b/tests/app/main/dao/test_users_dao.py index 9fde6bd9b..f6d8d5f87 100644 --- a/tests/app/main/dao/test_users_dao.py +++ b/tests/app/main/dao/test_users_dao.py @@ -119,3 +119,23 @@ def test_user_is_active_is_false_if_state_is_inactive(notifications_admin, notif saved_user = users_dao.get_user_by_id(user.id) assert saved_user.is_active() is False + + +def test_should_update_user_to_active(notifications_admin, notifications_admin_db): + user = User(name='Make user active', + password='somepassword', + email_address='activate@user.gov.uk', + mobile_number='+441234123412', + created_at=datetime.now(), + role_id=1, + state='pending') + users_dao.insert_user(user) + users_dao.activate_user(user.id) + updated_user = users_dao.get_user_by_id(user.id) + assert updated_user.state == 'active' + + +def test_should_throws_error_when_id_does_not_exist(notifications_admin, notifications_admin_db): + with pytest.raises(AttributeError) as error: + users_dao.activate_user(123) + assert '''object has no attribute 'state''''' in str(error.value) diff --git a/tests/app/main/views/test_verify.py b/tests/app/main/views/test_verify.py index cd943c6ea..a595cbd5d 100644 --- a/tests/app/main/views/test_verify.py +++ b/tests/app/main/views/test_verify.py @@ -1,9 +1,12 @@ +from datetime import datetime + +from app.main.dao import users_dao from app.main.encryption import hashpw +from app.models import User def test_should_return_verify_template(notifications_admin, notifications_admin_db): response = notifications_admin.test_client().get('/verify') - assert response.status_code == 200 assert 'Activate your account' in response.get_data(as_text=True) @@ -11,6 +14,8 @@ def test_should_return_verify_template(notifications_admin, notifications_admin_ def test_should_redirect_to_add_service_when_code_are_correct(notifications_admin, notifications_admin_db): with notifications_admin.test_client() as client: with client.session_transaction() as session: + user = _create_test_user() + session['user_id'] = user.id session['sms_code'] = hashpw('12345') session['email_code'] = hashpw('23456') response = client.post('/verify', @@ -20,13 +25,70 @@ def test_should_redirect_to_add_service_when_code_are_correct(notifications_admi assert response.location == 'http://localhost/add-service' +def test_should_activate_user_after_verify(notifications_admin, notifications_admin_db): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + user = _create_test_user() + session['user_id'] = user.id + session['sms_code'] = hashpw('12345') + session['email_code'] = hashpw('23456') + client.post('/verify', + data={'sms_code': '12345', + 'email_code': '23456'}) + + after_verify = users_dao.get_user_by_id(user.id) + assert after_verify.state == 'active' + + def test_should_return_400_when_sms_code_is_wrong(notifications_admin, notifications_admin_db): with notifications_admin.test_client() as client: with client.session_transaction() as session: + user = _create_test_user() + session['user_id'] = user.id session['sms_code'] = hashpw('12345') session['email_code'] = hashpw('23456') response = client.post('/verify', data={'sms_code': '98765', 'email_code': '23456'}) assert response.status_code == 400 - assert 'sms_code' in response.get_data(as_text=True) + assert '"sms_code": "does not match"' in response.get_data(as_text=True) + + +def test_should_return_400_when_email_code_is_wrong(notifications_admin, notifications_admin_db): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + user = _create_test_user() + session['user_id'] = user.id + session['sms_code'] = hashpw('12345') + session['email_code'] = hashpw('98456') + response = client.post('/verify', + data={'sms_code': '12345', + 'email_code': '23456'}) + assert response.status_code == 400 + assert '"email_code": "does not match"' in response.get_data(as_text=True) + + +def test_should_return_400_when_sms_code_is_missing(notifications_admin, notifications_admin_db): + response = notifications_admin.test_client().post('/verify', + data={'email_code': '23456'}) + assert response.status_code == 400 + assert 'SMS code can not be empty' in response.get_data(as_text=True) + + +def test_should_return_400_when_email_code_is_missing(notifications_admin, notifications_admin_db): + response = notifications_admin.test_client().post('/verify', + data={'sms_code': '23456'}) + assert response.status_code == 400 + assert 'Email code can not be empty' in response.get_data(as_text=True) + + +def _create_test_user(): + user = User(name='Test User', + password='somepassword', + email_address='test@user.gov.uk', + mobile_number='+441234123412', + created_at=datetime.now(), + role_id=1, + state='pending') + users_dao.insert_user(user) + return user