Merge branch 'master' of github.com:alphagov/notifications-admin

This commit is contained in:
Martyn Inglis
2015-12-07 11:30:37 +00:00
29 changed files with 220 additions and 56 deletions

View File

@@ -9,6 +9,7 @@ from flask_wtf import CsrfProtect
from webassets.filter import get_filter from webassets.filter import get_filter
from werkzeug.exceptions import abort from werkzeug.exceptions import abort
from app.notify_client.api_client import AdminAPIClient
from app.its_dangerous_session import ItsdangerousSessionInterface from app.its_dangerous_session import ItsdangerousSessionInterface
import app.proxy_fix import app.proxy_fix
from config import configs from config import configs
@@ -18,6 +19,8 @@ db = SQLAlchemy()
login_manager = LoginManager() login_manager = LoginManager()
csrf = CsrfProtect() csrf = CsrfProtect()
admin_api_client = AdminAPIClient()
def create_app(config_name): def create_app(config_name):
application = Flask(__name__) application = Flask(__name__)
@@ -39,6 +42,7 @@ def create_app(config_name):
proxy_fix.init_app(application) proxy_fix.init_app(application)
application.session_interface = ItsdangerousSessionInterface() application.session_interface = ItsdangerousSessionInterface()
admin_api_client.init_app(application)
return application return application
@@ -98,7 +102,8 @@ def init_asset_environment(app):
assets.Bundle( assets.Bundle(
'govuk_template/govuk-template.scss', 'govuk_template/govuk-template.scss',
filters='scss', filters='scss',
output='stylesheets/govuk-template.css' output='stylesheets/govuk-template.css',
depends='*.scss'
) )
) )

View File

@@ -19,4 +19,29 @@
font-size: 19px; font-size: 19px;
line-height: 1.31579; line-height: 1.31579;
} }
}
.phase-tag {
@include phase-tag(beta);
}
@media (min-width: 641px) {
.phase-tag {
font-size: 16px;
line-height: 1.25;
margin-top: 7px;
}
}
@media (max-width: 641px) {
.phase-tag {
margin-top: 11px;
}
}
#global-header #logo {
white-space: nowrap;
} }

5
app/main/exceptions.py Normal file
View File

@@ -0,0 +1,5 @@
class AdminApiClientException(Exception):
def __init__(self, message):
self.value = message

View File

@@ -2,6 +2,8 @@ from flask_wtf import Form
from wtforms import StringField, PasswordField from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Email, Length, Regexp from wtforms.validators import DataRequired, Email, Length, Regexp
from app.main.validators import Blacklist
class LoginForm(Form): class LoginForm(Form):
email_address = StringField('Email address', validators=[ email_address = StringField('Email address', validators=[
@@ -19,7 +21,7 @@ mobile_number = "^\\+44[\\d]{10}$"
class RegisterUserForm(Form): class RegisterUserForm(Form):
name = StringField('Name', name = StringField('Full name',
validators=[DataRequired(message='Name can not be empty')]) validators=[DataRequired(message='Name can not be empty')])
email_address = StringField('Email address', validators=[ email_address = StringField('Email address', validators=[
Length(min=5, max=255), Length(min=5, max=255),
@@ -30,6 +32,7 @@ class RegisterUserForm(Form):
mobile_number = StringField('Mobile phone number', mobile_number = StringField('Mobile phone number',
validators=[DataRequired(message='Please enter your mobile number'), validators=[DataRequired(message='Please enter your mobile number'),
Regexp(regex=mobile_number, message='Please enter a +44 mobile number')]) Regexp(regex=mobile_number, message='Please enter a +44 mobile number')])
password = PasswordField('Password', password = PasswordField('Create a password',
validators=[DataRequired(message='Please enter your password'), validators=[DataRequired(message='Please enter your password'),
Length(10, 255, message='Password must be at least 10 characters')]) Length(10, 255, message='Password must be at least 10 characters'),
Blacklist(message='That password is blacklisted, too common')])

12
app/main/validators.py Normal file
View File

@@ -0,0 +1,12 @@
from wtforms import ValidationError
class Blacklist(object):
def __init__(self, message=None):
if not message:
message = 'Password is blacklisted.'
self.message = message
def __call__(self, form, field):
if field.data in ['password1234', 'passw0rd1234']:
raise ValidationError(self.message)

View File

@@ -15,19 +15,16 @@ def govuk():
@main.route("/register-from-invite") @main.route("/register-from-invite")
@login_required
def registerfrominvite(): def registerfrominvite():
return render_template('register-from-invite.html') return render_template('register-from-invite.html')
@main.route("/verify") @main.route("/verify")
@login_required
def verify(): def verify():
return render_template('verify.html') return render_template('verify.html')
@main.route("/verify-mobile") @main.route("/verify-mobile")
@login_required
def verifymobile(): def verifymobile():
return render_template('verify-mobile.html') return render_template('verify-mobile.html')
@@ -50,7 +47,6 @@ def addservice():
@main.route("/two-factor") @main.route("/two-factor")
@login_required
def twofactor(): def twofactor():
return render_template('two-factor.html') return render_template('two-factor.html')

View File

@@ -1,9 +1,14 @@
from datetime import datetime from datetime import datetime, timedelta
from random import randint
from flask import render_template, redirect, jsonify from flask import render_template, redirect, jsonify, session
from sqlalchemy.exc import SQLAlchemyError
from app import admin_api_client
from app.main import main from app.main import main
from app.main.dao import users_dao from app.main.dao import users_dao
from app.main.encryption import hashpw
from app.main.exceptions import AdminApiClientException
from app.main.forms import RegisterUserForm from app.main.forms import RegisterUserForm
from app.models import User from app.models import User
@@ -25,9 +30,43 @@ def process_register():
created_at=datetime.now(), created_at=datetime.now(),
role_id=1) role_id=1)
try: try:
sms_code = send_sms_code(form.mobile_number.data)
email_code = send_email_code(form.email_address.data)
session['sms_code'] = hashpw(sms_code)
session['email_code'] = hashpw(email_code)
session['expiry_date'] = str(datetime.now() + timedelta(hours=1))
users_dao.insert_user(user) users_dao.insert_user(user)
return redirect('/two-factor') except AdminApiClientException as e:
except Exception as e: return jsonify(admin_api_client_error=e.value)
except SQLAlchemyError:
return jsonify(database_error='encountered database error'), 400 return jsonify(database_error='encountered database error'), 400
else: else:
return jsonify(form.errors), 400 return jsonify(form.errors), 400
return redirect('/verify')
def send_sms_code(mobile_number):
sms_code = _create_code()
try:
admin_api_client.send_sms(mobile_number, message=sms_code, token=admin_api_client.auth_token)
except:
raise AdminApiClientException('Exception when sending sms.')
return sms_code
def send_email_code(email):
email_code = _create_code()
try:
admin_api_client.send_email(email_address=email,
from_str='notify@digital.cabinet-office.gov.uk',
message=email_code,
subject='Verification code',
token=admin_api_client.auth_token)
except:
raise AdminApiClientException('Exception when sending email.')
return email_code
def _create_code():
return ''.join(["%s" % randint(0, 9) for _ in range(0, 5)])

View File

View File

@@ -0,0 +1,8 @@
from __future__ import unicode_literals
from notify_client import NotifyAPIClient
class AdminAPIClient(NotifyAPIClient):
def init_app(self, app):
self.base_url = app.config['NOTIFY_DATA_API_URL']
self.auth_token = app.config['NOTIFY_DATA_API_AUTH_TOKEN']

View File

@@ -9,6 +9,12 @@ GOV.UK Notify | Set up service
<div class="grid-row"> <div class="grid-row">
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Set up notifications for your service</h1> <h1 class="heading-xlarge">Set up notifications for your service</h1>
<p>Users will see your service name:</p>
<ul>
<li>at the start of every text message, eg 'Vehicle tax: we received your payment, thank you'</li>
<li>as your email sender name</li>
</ul>
<p> <p>
@@ -17,11 +23,6 @@ GOV.UK Notify | Set up service
<span class="font-xsmall">For example, 'Vehicle tax' or 'Carer's allowance'</span> <span class="font-xsmall">For example, 'Vehicle tax' or 'Carer's allowance'</span>
</p> </p>
<h2 class="heading-small">We'll create your service in test mode</h2>
<p>In test mode you can only send notifications to people in your team.</p>
<p>When you're ready to go live we'll remove this restriction.</p>
<p> <p>
<a class="button" href="dashboard" role="button">Continue</a> <a class="button" href="dashboard" role="button">Continue</a>
</p> </p>

View File

@@ -7,5 +7,13 @@ GOV.UK notifications admin
{% block cookie_message %} {% block cookie_message %}
{% endblock %} {% endblock %}
{% block inside_header %}
<div class="phase-banner-beta">
<strong class="phase-tag">BETA</strong>
</div>
{% endblock %}
{% set global_header_text = "GOV.UK Notify" %} {% set global_header_text = "GOV.UK Notify" %}

View File

@@ -10,7 +10,7 @@ GOV.UK Notify
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Check your email address</h1> <h1 class="heading-xlarge">Check your email address</h1>
<p>Check your email address is correct and resend a confirmation code.</p> <p>Check your email address is correct and then resend the confirmation code.</p>
<p> <p>
<label class="form-label" for="email">Email address</label> <label class="form-label" for="email">Email address</label>
@@ -25,4 +25,4 @@ GOV.UK Notify
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -9,10 +9,13 @@ GOV.UK Notify
<div class="grid-row"> <div class="grid-row">
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Create a new password</h1> <h1 class="heading-xlarge">Create a new password</h1>
<p> You can now create a new password for your account.</p>
<p> <p>
<label class="form-label" for="password">Password</label> <label class="form-label" for="password">Create a password</label>
<input class="form-control-1-4" id="password" type="password"> <input class="form-control-1-4" id="password" type="password">
<span class="font-xsmall">Your password must have at least 10 characters</span></label>
</p> </p>
<p> <p>
@@ -21,4 +24,4 @@ GOV.UK Notify
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -13,7 +13,7 @@ GOV.UK Notify | Create a user account
<p>If you've used GOV.UK Notify before, <a href="">sign in to your account</a>.</p> <p>If you've used GOV.UK Notify before, <a href="">sign in to your account</a>.</p>
<p> <p>
<label class="form-label" for="name-f1">Name</label> <label class="form-label" for="name-f1">Full name</label>
<input class="form-control-2-3" id="name-f1" type="text"> <input class="form-control-2-3" id="name-f1" type="text">
</p> </p>
<p> <p>
@@ -21,8 +21,9 @@ GOV.UK Notify | Create a user account
<input class="form-control-1-4" id="mobile" type="text"> <input class="form-control-1-4" id="mobile" type="text">
</p> </p>
<p> <p>
<label class="form-label" for="password">Password</label> <label class="form-label" for="password">Create a password</label>
<input class="form-control-1-4" id="password" type="password"> <input class="form-control-1-4" id="password" type="password">
<span class="font-xsmall">Your password must have at least 10 characters</span></label>
</p> </p>
<p> <p>

View File

@@ -12,9 +12,7 @@ GOV.UK Notify | Create an account
<p>If you've used GOV.UK Notify before, <a href="">sign in to your account</a>.</p> <p>If you've used GOV.UK Notify before, <a href="">sign in to your account</a>.</p>
<p>You need to have access to your email account and a mobile phone to register.</p> <form autocomplete="off" action="" method="post">
<form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<p> <p>
<label class="form-label"> {{ form.name.label }} </label> <label class="form-label"> {{ form.name.label }} </label>
@@ -32,6 +30,7 @@ GOV.UK Notify | Create an account
<p> <p>
<label class="form-label"> {{ form.password.label}} </label> <label class="form-label"> {{ form.password.label}} </label>
{{ form.password(class="form-control-1-4", autocomplete="off") }} <br> {{ form.password(class="form-control-1-4", autocomplete="off") }} <br>
<span class="font-xsmall">Your password must have at least 10 characters</span></label>
</p> </p>
<p> <p>
<button class="button" role="button">Continue</button> <button class="button" role="button">Continue</button>

View File

@@ -12,13 +12,13 @@ GOV.UK Notify | Get started
<p>Use GOV.UK Notify to send notifications by text message, email and letter.</p> <p>Use GOV.UK Notify to send notifications by text message, email and letter.</p>
<p>We're making it easy to keep your users informed.</p> <p>We're making it easy to keep your users informed.</p>
<p>If you work for a central UK Government department or agency you can set up a test account now.</p> <p>If you work for a UK government department or agency you can set up a test account now.</p>
<a class="button" href="register" role="button">Set up an account</a> <a class="button" href="register" role="button">Set up an account</a>
<!-- <h2 class="heading-large">Used GOV.UK Notify before?</h2> --> <!-- <h2 class="heading-large">Used GOV.UK Notify before?</h2> -->
<p><a href="sign-in">Sign in</a></p> <p>If you've used GOV.UK Notify before, <a href="sign-in">sign in to your account</a>.</p>
</div> </div>
</div> </div>

View File

@@ -10,7 +10,7 @@ Sign in
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Sign in</h1> <h1 class="heading-xlarge">Sign in</h1>
<p>If you do not have an account, you can <a href="register">register</a>.</p> <p>If you do not have an account, you can <a href="register">register for one now</a>.</p>
<form autocomplete="off" action="" method="post"> <form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
@@ -33,4 +33,4 @@ Sign in
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -12,7 +12,7 @@ GOV.UK Notify
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Check your mobile number</h1> <h1 class="heading-xlarge">Check your mobile number</h1>
<p>Check your mobile phone number is correct and resend a confirmation code.</p> <p>Check your mobile phone number is correct and then resend the confirmation code.</p>
<p> <p>
<label class="form-label" for="mobile">Mobile phone number</label> <label class="form-label" for="mobile">Mobile phone number</label>
@@ -26,4 +26,4 @@ GOV.UK Notify
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -10,7 +10,7 @@ GOV.UK Notify
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Check your mobile number</h1> <h1 class="heading-xlarge">Check your mobile number</h1>
<p>Check your mobile phone number is correct and resend a confirmation code.</p> <p>Check your mobile phone number is correct and then resend the confirmation code.</p>
<p> <p>
<label class="form-label" for="mobile">Mobile phone number</label> <label class="form-label" for="mobile">Mobile phone number</label>
@@ -24,4 +24,4 @@ GOV.UK Notify
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -10,11 +10,10 @@ GOV.UK Notify | Text verification
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Text verification</h1> <h1 class="heading-xlarge">Text verification</h1>
<p>We've sent you a text message containing a verification code.</p> <p>We've sent you a text message with a verification code.</p>
<p> <p>
<label class="form-label" for="email">Text message verification code<br> <label class="form-label" for="email">Enter verification code<br>
<span class="font-xsmall">Enter the code we sent you by email</span></label>
<input class="form-control-1-4" id="email" type="text"><br> <input class="form-control-1-4" id="email" type="text"><br>
<span class="font-xsmall"><a href="verification-not-received">I haven't received a text</a></span> <span class="font-xsmall"><a href="verification-not-received">I haven't received a text</a></span>
</p> </p>

View File

@@ -10,15 +10,15 @@ GOV.UK Notify
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Resend verification code</h1> <h1 class="heading-xlarge">Resend verification code</h1>
<p>Text messages sometimes take a few minutes to be received. <br> If you have not received a text message, you can resend.</p> <p>Text messages sometimes take a few minutes to arrive. If you do not receive the text message, you can resend it.</p>
<p>If you no longer have access to your mobile phone and registered number, get in contact with your service manager to reset your number.</p>P> <p>If you no longer have access to the phone with the number you registered for this service, speak to your service manager to reset the number.</p>
<p> <p>
<a class="button" href="two-factor" role="button">Resend confirmation code</a> <a class="button" href="two-factor" role="button">Resend verification code</a>
</p> </p>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -10,12 +10,10 @@ GOV.UK Notify | Confirm mobile number
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Confirm your mobile number</h1> <h1 class="heading-xlarge">Confirm your mobile number</h1>
<p>You need to prove the contact details you gave us are yours.</p> <p>We've sent you a confirmation code by text message.</p>
<p>We've sent you an email and a text message containing confirmation codes.</p>
<p> <p>
<label class="form-label" for="email">Text message confirmation code<br> <label class="form-label" for="email">Enter confirmation code<br>
<span class="font-xsmall">Enter the code we sent you by text</span></label>
<input class="form-control-1-4" id="email" type="text"><br> <input class="form-control-1-4" id="email" type="text"><br>
<span class="font-xsmall"><a href="text-not-received-2">I haven't received a text</a></span> <span class="font-xsmall"><a href="text-not-received-2">I haven't received a text</a></span>
</p> </p>

View File

@@ -8,20 +8,17 @@ GOV.UK Notify | Confirm email address and mobile number
<div class="grid-row"> <div class="grid-row">
<div class="column-two-thirds"> <div class="column-two-thirds">
<h1 class="heading-xlarge">Confirm your email address and mobile number</h1> <h1 class="heading-xlarge">Activate your account</h1>
<p>You need to prove the contact details you gave us are yours.</p> <p>We've sent you confirmation codes by email and text message. You need to enter both codes here.</p>
<p>We've sent you an email and a text message containing confirmation codes.</p>
<p> <p>
<label class="form-label" for="emailverify">Email confirmation code<br> <label class="form-label" for="emailverify">Email confirmation code<br>
<span class="font-xsmall">Enter the code we sent you by email</span></label>
<input class="form-control-1-4" id="emailverify" type="text"><br> <input class="form-control-1-4" id="emailverify" type="text"><br>
<span class="font-xsmall"><a href="email-not-received">I haven't received an email</a></span> <span class="font-xsmall"><a href="email-not-received">I haven't received an email</a></span>
</p> </p>
<p> <p>
<label class="form-label" for="email">Text message confirmation code<br> <label class="form-label" for="email">Text message confirmation code<br>
<span class="font-xsmall">Enter the code we sent you by text</span></label>
<input class="form-control-1-4" id="email" type="text"><br> <input class="form-control-1-4" id="email" type="text"><br>
<span class="font-xsmall"><a href="text-not-received">I haven't received a text</a></span> <span class="font-xsmall"><a href="text-not-received">I haven't received a text</a></span>
</p> </p>

View File

@@ -1,3 +1,5 @@
import os
class Config(object): class Config(object):
DEBUG = False DEBUG = False
@@ -11,6 +13,14 @@ class Config(object):
MAX_FAILED_LOGIN_COUNT = 10 MAX_FAILED_LOGIN_COUNT = 10
PASS_SECRET_KEY = 'secret-key-unique-changeme' PASS_SECRET_KEY = 'secret-key-unique-changeme'
SESSION_COOKIE_NAME = 'notify_admin_session'
SESSION_COOKIE_PATH = '/admin'
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
NOTIFY_DATA_API_URL = os.getenv('NOTIFY_API_URL', "http://localhost:6001")
NOTIFY_DATA_API_AUTH_TOKEN = os.getenv('NOTIFY_API_TOKEN', "dev-token")
WTF_CSRF_ENABLED = True WTF_CSRF_ENABLED = True
SECRET_KEY = 'secret-key' SECRET_KEY = 'secret-key'
HTTP_PROTOCOL = 'http' HTTP_PROTOCOL = 'http'

View File

@@ -8,4 +8,6 @@ SQLAlchemy==1.0.5
SQLAlchemy-Utils==0.30.5 SQLAlchemy-Utils==0.30.5
Flask-WTF==0.11 Flask-WTF==0.11
Flask-Login==0.2.11 Flask-Login==0.2.11
Flask-Bcrypt==0.6.2 Flask-Bcrypt==0.6.2
git+https://github.com/alphagov/notify-api-client.git@0.1.4#egg=notify-api-client==0.1.4

View File

@@ -1,3 +1,4 @@
-r requirements.txt -r requirements.txt
pep8==1.5.7 pep8==1.5.7
pytest==2.8.1 pytest==2.8.1
pytest-mock==0.8.1

View File

@@ -0,0 +1,17 @@
from pytest import fail
from app.main.forms import RegisterUserForm
def test_should_raise_validation_error_for_password(notifications_admin):
form = RegisterUserForm()
form.name.data = 'test'
form.email_address.data = 'teset@example.gov.uk'
form.mobile_number.data = '+441231231231'
form.password.data = 'password1234'
try:
form.validate()
fail()
except:
assert 'That password is blacklisted, too common' in form.errors['password']

View File

@@ -7,17 +7,22 @@ def test_render_register_returns_template_with_form(notifications_admin, notific
assert 'Create an account' in response.get_data(as_text=True) assert 'Create an account' in response.get_data(as_text=True)
def test_process_register_creates_new_user(notifications_admin, notifications_admin_db): def test_process_register_creates_new_user(notifications_admin, notifications_admin_db, mocker):
_set_up_mocker(mocker)
response = notifications_admin.test_client().post('/register', response = notifications_admin.test_client().post('/register',
data={'name': 'Some One Valid', data={'name': 'Some One Valid',
'email_address': 'someone@example.gov.uk', 'email_address': 'someone@example.gov.uk',
'mobile_number': '+441231231231', 'mobile_number': '+441231231231',
'password': 'validPassword!'}) 'password': 'validPassword!'})
assert response.status_code == 302 assert response.status_code == 302
assert response.location == 'http://localhost/two-factor' assert response.location == 'http://localhost/verify'
def test_process_register_returns_400_when_mobile_number_is_invalid(notifications_admin, notifications_admin_db): def test_process_register_returns_400_when_mobile_number_is_invalid(notifications_admin,
notifications_admin_db,
mocker):
_set_up_mocker(mocker)
response = notifications_admin.test_client().post('/register', response = notifications_admin.test_client().post('/register',
data={'name': 'Bad Mobile', data={'name': 'Bad Mobile',
'email_address': 'bad_mobile@example.gov.uk', 'email_address': 'bad_mobile@example.gov.uk',
@@ -28,7 +33,8 @@ def test_process_register_returns_400_when_mobile_number_is_invalid(notification
assert 'Please enter a +44 mobile number' in response.get_data(as_text=True) assert 'Please enter a +44 mobile number' in response.get_data(as_text=True)
def test_should_return_400_when_email_is_not_gov_uk(notifications_admin, notifications_admin_db): def test_should_return_400_when_email_is_not_gov_uk(notifications_admin, notifications_admin_db, mocker):
_set_up_mocker(mocker)
response = notifications_admin.test_client().post('/register', response = notifications_admin.test_client().post('/register',
data={'name': 'Bad Mobile', data={'name': 'Bad Mobile',
'email_address': 'bad_mobile@example.not.right', 'email_address': 'bad_mobile@example.not.right',
@@ -37,3 +43,31 @@ def test_should_return_400_when_email_is_not_gov_uk(notifications_admin, notific
assert response.status_code == 400 assert response.status_code == 400
assert 'Please enter a gov.uk email address' in response.get_data(as_text=True) assert 'Please enter a gov.uk email address' in response.get_data(as_text=True)
def test_should_add_verify_codes_on_session(notifications_admin, notifications_admin_db, mocker):
_set_up_mocker(mocker)
with notifications_admin.test_client() as client:
response = client.post('/register',
data={'name': 'Test Codes',
'email_address': 'test_codes@example.gov.uk',
'mobile_number': '+441234567890',
'password': 'validPassword!'})
assert response.status_code == 302
assert 'notify_admin_session' in response.headers.get('Set-Cookie')
def _set_up_mocker(mocker):
mocker.patch("app.admin_api_client.send_sms")
mocker.patch("app.admin_api_client.send_email")
def test_should_return_400_if_password_is_blacklisted(notifications_admin, notifications_admin_db):
response = notifications_admin.test_client().post('/register',
data={'name': 'Bad Mobile',
'email_address': 'bad_mobile@example.not.right',
'mobile_number': '+44123412345',
'password': 'password1234'})
response.status_code == 400
assert 'That password is blacklisted, too common' in response.get_data(as_text=True)

View File

@@ -1,4 +1,5 @@
import pytest import pytest
from _pytest.monkeypatch import monkeypatch
from sqlalchemy.schema import MetaData, DropConstraint from sqlalchemy.schema import MetaData, DropConstraint
from app import create_app, db from app import create_app, db