diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 1a8d54926..f19cc9f9c 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -1,3 +1,3 @@ $(() => GOVUK.modules.start()); -$(() => new GOVUK.SelectionButtons('.block-label input')); +$(() => new GOVUK.SelectionButtons('.block-label input, .sms-message-option input')); diff --git a/app/assets/stylesheets/components/sms-message.scss b/app/assets/stylesheets/components/sms-message.scss index a429edbaa..a72e7c939 100644 --- a/app/assets/stylesheets/components/sms-message.scss +++ b/app/assets/stylesheets/components/sms-message.scss @@ -1,53 +1,63 @@ -.sms-message { - - position: relative; +%sms-message-wrapper, +.sms-message-wrapper { + width: 100%; + box-sizing: border-box; + padding: $gutter/2; + background: $panel-colour; + border: 1px solid $panel-colour; + border-radius: 5px; + white-space: normal; margin: 0 0 $gutter 0; +} + +.sms-message-wrapper-with-radio { + @extend %sms-message-wrapper; + padding-left: 45px; + cursor: pointer; +} + +.sms-message-recipient { + @include copy-19; + color: $secondary-text-colour; + margin: -$gutter-half 0 $gutter 0; +} + +.sms-message-name { + @include bold-19; + margin: 30px 0 10px 0; +} + +.sms-message-picker { + display: block; + margin: 7px 0 0 0; + position: absolute; + left: 15px; + top: 50%; + z-index: 50; +} + +label.sms-message-option { + + display: block; + position: relative; + + &.selected { + + .sms-message-wrapper-with-radio { + background: $white; + border: 1px solid $text-colour; + } - &:before { - content: ''; - position: absolute; - z-index: 10; - bottom: -12px; - right: 5px; - width: 20px; - height: 25px; - border-radius: 100%; - background: $panel-colour; } - &:after { - content: ''; - position: absolute; - z-index: 20; - bottom: -15px; - right: -5px; - border-radius: 100%; - width: 20px; - height: 20px; - background: $white; - } + &.focused { - &-wrapper { - width: 100%; - display: inline-block; - box-sizing: border-box; - position: relative; - z-index: 30; - padding: $gutter/2; - background: $panel-colour; - border-radius: 5px; - white-space: normal; - } + outline: none; - &-recipient { - @include copy-19; - color: $secondary-text-colour; - margin: -$gutter-half 0 $gutter 0; - } + .sms-message-wrapper-with-radio { + box-shadow: 0 0 0 3px $yellow; + } - &-name { - @include bold-19; - margin: 50px 0 10px 0; } } diff --git a/app/assets/stylesheets/components/template-picker.scss b/app/assets/stylesheets/components/template-picker.scss deleted file mode 100644 index 1b2851194..000000000 --- a/app/assets/stylesheets/components/template-picker.scss +++ /dev/null @@ -1,33 +0,0 @@ -.template-picker { - - &-name { - @include bold-19; - padding-left: 5px; - } - - &-option { - - white-space: nowrap; - clear: both; - - &-radio { - padding-right: 10px; - box-sizing: border-box; - vertical-align: top; - width: 33%; - display: inline-block; - } - - .block-label { - display: inline-block; - } - - .sms-message { - display: inline-block; - vertical-align: top; - max-width: 66%; - } - - } - -} diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 59b450ec7..38d1547e1 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -32,7 +32,6 @@ // Specific to this application @import 'grids'; -@import 'components/template-picker'; @import 'components/placeholder'; @import 'components/sms-message'; @import 'components/page-footer'; diff --git a/app/main/dao/users_dao.py b/app/main/dao/users_dao.py index f45d2a95d..c44065c74 100644 --- a/app/main/dao/users_dao.py +++ b/app/main/dao/users_dao.py @@ -6,6 +6,8 @@ from app import db, login_manager from app.models import User from app.main.encryption import hashpw +from app import user_api_client + @login_manager.user_loader def load_user(user_id): @@ -21,7 +23,7 @@ def insert_user(user): # TODO Would be better to have a generic get and update for user # something that replicates the sql functionality. def get_user_by_id(id): - return User.query.filter_by(id=id).first() + return user_api_client.get_user(id) def get_all_users(): @@ -38,11 +40,9 @@ def increment_failed_login_count(id): db.session.commit() -def activate_user(id): - user = get_user_by_id(id) +def activate_user(user): user.state = 'active' - db.session.add(user) - db.session.commit() + return user_api_client.update_user(user) def update_email_address(id, email_address): diff --git a/app/main/views/_templates.py b/app/main/views/_templates.py index da7f97c32..6d20217ce 100644 --- a/app/main/views/_templates.py +++ b/app/main/views/_templates.py @@ -1,39 +1,12 @@ templates = [ { 'type': 'sms', - 'name': 'Confirmation', - 'body': 'Lasting power of attorney: We’ve received your application. Applications take between 8 and 10 weeks to process.' # noqa + 'name': 'Confirmation with details Jan 2016', + 'body': '((name)), we’ve received your ((thing)). We’ll contact you again within 1 week.' }, { 'type': 'sms', - 'name': 'Reminder', - 'body': 'Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)). Tax your vehicle at www.gov.uk/vehicle-tax' # noqa - }, - { - 'type': 'sms', - 'name': 'Warning', - 'body': 'Vehicle tax: Your vehicle tax for ((registration number)) has expired. Tax your vehicle at www.gov.uk/vehicle-tax' # noqa - }, - { - 'type': 'email', - 'name': 'Application alert 06/2016', - 'subject': 'Your lasting power of attorney application', - 'body': """Dear ((name)), - -When you’ve made your lasting power of attorney (LPA), you need to register it \ -with the Office of the Public Guardian (OPG). - -You can apply to register your LPA yourself if you’re able to make your own decisions. - -Your attorney can also register it for you. You’ll be told if they do and you can \ -object to the registration. - -It takes between 8 and 10 weeks to register an LPA if there are no mistakes in the application. - """ - }, - { - 'type': 'sms', - 'name': 'Air quality alert', - 'body': 'Air pollution levels will be ((level)) in ((region)) tomorrow.' - }, + 'name': 'Confirmation Jan 2016', + 'body': 'We’ve received your payment. We’ll contact you again within 1 week.' + } ] diff --git a/app/main/views/register.py b/app/main/views/register.py index dadb33faa..6d67a976a 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -4,14 +4,12 @@ from flask import ( render_template, redirect, session, - current_app, abort ) from client.errors import HTTPError from app.main import main -from app.models import User from app.main.dao import users_dao from app.main.forms import RegisterUserForm @@ -27,7 +25,6 @@ def register(): form = RegisterUserForm(users_dao.get_user_by_email) if form.validate_on_submit(): - try: user = user_api_client.register_user(form.name.data, form.email_address.data, diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 7c0e28a26..cd953e15f 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -16,6 +16,8 @@ def sign_in(): if form.validate_on_submit(): user = users_dao.get_user_by_email(form.email_address.data) if user: + # TODO move to user API in next pr to actually do password check as this + # is totally broken now if not user.is_locked() and user.is_active() and check_hash(form.password.data, user.password): send_sms_code(user.id, user.mobile_number) session['user_email'] = user.email_address diff --git a/app/main/views/verify.py b/app/main/views/verify.py index 7d803cb03..0a55ddc74 100644 --- a/app/main/views/verify.py +++ b/app/main/views/verify.py @@ -1,11 +1,13 @@ from flask import ( render_template, redirect, - jsonify, session, - url_for + url_for, + abort ) +from client.errors import HTTPError + from flask_login import login_user from app.main import main @@ -24,9 +26,15 @@ def verify(): verify_codes_dao.use_code_for_user_and_type(user_id=user_id, code_type='email') verify_codes_dao.use_code_for_user_and_type(user_id=user_id, code_type='sms') - # TODO complete verify and login flow - # users_dao.activate_user(user.id) - # login_user(user) + try: + user = users_dao.get_user_by_id(user_id) + activated_user = users_dao.activate_user(user) + login_user(activated_user) + return redirect(url_for('main.add_service', first='first')) + except HTTPError as e: + if e.status_code == 404: + abort(404) + else: + raise e - return redirect(url_for('.add_service', first='first')) return render_template('views/verify.html', form=form) diff --git a/app/notify_client/user_api_client.py b/app/notify_client/user_api_client.py index a6858eba7..1ea8708a7 100644 --- a/app/notify_client/user_api_client.py +++ b/app/notify_client/user_api_client.py @@ -24,6 +24,17 @@ class UserApiClient(BaseAPIClient): user_data = self.post("/user", data) return User(user_data['data'], max_failed_login_count=self.user_max_failed_login_count) + def get_user(self, id): + url = "{}/user/{}".format(self.base_url, id) + user_data = self.get(url) + return User(user_data['data'], max_failed_login_count=self.user_max_failed_login_count) + + def update_user(self, user): + data = user.serialize() + url = "{}/user/{}".format(self.base_url, user.id) + user_data = self.put(url, data=data) + return User(user_data['data'], max_failed_login_count=self.user_max_failed_login_count) + class User(object): @@ -51,24 +62,28 @@ class User(object): def password_changed_at(self): return self.fields.get('password_changed_at') - @property + def get_id(self): + return self.id + def is_authenticated(self): - return self.fields.get('is_authenticated') + return True - @property def is_active(self): - if self.fields.get('state') != 'active': - return False - else: - return True + return self.state == 'active' @property + def state(self): + return self.fields['state'] + + @state.setter + def state(self, state): + self.fields['state'] = state + def is_anonymous(self): return False - @property def is_locked(self): - if self.fields.get('failed_login_count') < self.max_failed_login_count: - return False - else: - return True + return self.fields.get('failed_login_count') > self.max_failed_login_count + + def serialize(self): + return self.fields diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index d3ac7c6da..85ec76dd6 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -55,8 +55,10 @@ Service name - Switch to A N Other service - Add a new service to GOV.UK Notify +
+ Switch to A N Other service + Add a new service to GOV.UK Notify +
diff --git a/app/templates/components/sms-message.html b/app/templates/components/sms-message.html index a04a47c62..38d41f486 100644 --- a/app/templates/components/sms-message.html +++ b/app/templates/components/sms-message.html @@ -1,4 +1,9 @@ -{% macro sms_message(body, recipient=None, name=None, edit_link=None) %} +{% macro sms_message( + body, recipient=None, name=None, edit_link=None, input_name=None, input_index=None +) %} + {% if input_name %} +