Merge pull request #35 from alphagov/did-not-receive-code

Implementation for did not receive email or sms code
This commit is contained in:
Rebecca Law
2015-12-31 10:32:34 +00:00
24 changed files with 511 additions and 229 deletions

View File

@@ -3,4 +3,4 @@ from flask import Blueprint
main = Blueprint('main', __name__)
from app.main.views import index, sign_in, register, two_factor, verify, sms, add_service
from app.main.views import index, sign_in, register, two_factor, verify, sms, add_service, code_not_received

View File

@@ -37,3 +37,17 @@ def activate_user(id):
user.state = 'active'
db.session.add(user)
db.session.commit()
def update_email_address(id, email_address):
user = get_user_by_id(id)
user.email_address = email_address
db.session.add(user)
db.session.commit()
def update_mobile_number(id, mobile_number):
user = get_user_by_id(id)
user.mobile_number = mobile_number
db.session.add(user)
db.session.commit()

View File

@@ -13,15 +13,15 @@ def add_code(user_id, code, code_type):
db.session.add(code)
db.session.commit()
return code.id
def get_code(user_id, code_type):
verify_code = VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type, code_used=False).first()
return verify_code
def get_codes(user_id, code_type):
return VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type, code_used=False).all()
def get_code_by_code(user_id, code_type):
return VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type).first()
def get_code_by_code(user_id, code, code_type):
return VerifyCodes.query.filter_by(user_id=user_id, code=code, code_type=code_type).first()
def use_code(id):
@@ -32,15 +32,20 @@ def use_code(id):
def use_code_for_user_and_type(user_id, code_type):
verify_code = VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type).first()
verify_code.code_used = True
db.session.add(verify_code)
codes = VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type, code_used=False).all()
for verify_code in codes:
verify_code.code_used = True
db.session.add(verify_code)
db.session.commit()
def get_code_by_id(id):
return VerifyCodes.query.get(id)
def add_code_with_expiry(user_id, code, code_type, expiry):
code = VerifyCodes(user_id=user_id,
code=code,
code=hashpw(code),
code_type=code_type,
expiry_datetime=expiry)

View File

@@ -49,8 +49,7 @@ class TwoFactorForm(Form):
Regexp(regex=verify_code, message='Code must be 5 digits')])
def validate_sms_code(self, a):
code = verify_codes_dao.get_code(session['user_id'], 'sms')
validate_code(self.sms_code, code)
return validate_codes(self.sms_code, 'sms')
class VerifyForm(Form):
@@ -62,26 +61,25 @@ class VerifyForm(Form):
Regexp(regex=verify_code, message='Code must be 5 digits')])
def validate_email_code(self, a):
code = verify_codes_dao.get_code(session['user_id'], 'email')
validate_code(self.email_code, code)
return validate_codes(self.email_code, 'email')
def validate_sms_code(self, a):
code = verify_codes_dao.get_code(session['user_id'], 'sms')
validate_code(self.sms_code, code)
return validate_codes(self.sms_code, 'sms')
def validate_code(field, code):
if code.expiry_datetime <= datetime.now():
field.errors.append('Code has expired')
return False
if field.data is not None:
if check_hash(field.data, code.code) is False:
field.errors.append('Code does not match')
return False
else:
return True
else:
return False
class EmailNotReceivedForm(Form):
email_address = StringField('Email address', validators=[
Length(min=5, max=255),
DataRequired(message='Email cannot be empty'),
Email(message='Please enter a valid email address'),
Regexp(regex=gov_uk_email, message='Please enter a gov.uk email address')
])
class TextNotReceivedForm(Form):
mobile_number = StringField('Mobile phone number',
validators=[DataRequired(message='Please enter your mobile number'),
Regexp(regex=mobile_number, message='Please enter a +44 mobile number')])
class AddServiceForm(Form):
@@ -93,3 +91,22 @@ class AddServiceForm(Form):
return False
else:
return True
def validate_codes(field, code_type):
codes = verify_codes_dao.get_codes(user_id=session['user_id'], code_type=code_type)
is_valid = len([code for code in codes if validate_code(field, code)]) == 1
if is_valid:
field.errors.clear()
return is_valid
def validate_code(field, code):
if field.data and check_hash(field.data, code.code):
if code.expiry_datetime <= datetime.now():
field.errors.append('Code has expired')
return False
return True
else:
field.errors.append('Code does not match')
return False

View File

@@ -12,7 +12,7 @@ def send_sms_code(user_id, mobile_number):
sms_code = create_verify_code()
try:
verify_codes_dao.add_code(user_id=user_id, code=sms_code, code_type='sms')
admin_api_client.send_sms(mobile_number, message=sms_code, token=admin_api_client.auth_token)
admin_api_client.send_sms(mobile_number=mobile_number, message=sms_code, token=admin_api_client.auth_token)
except:
raise AdminApiClientException('Exception when sending sms.')
return sms_code

View File

@@ -0,0 +1,41 @@
from flask import render_template, redirect, jsonify, session
from app.main import main
from app.main.dao import users_dao, verify_codes_dao
from app.main.forms import EmailNotReceivedForm, TextNotReceivedForm
from app.main.views import send_sms_code, send_email_code
@main.route("/email-not-received", methods=['GET'])
def email_not_received():
user = users_dao.get_user_by_id(session['user_id'])
return render_template('views/email-not-received.html',
form=EmailNotReceivedForm(email_address=user.email_address))
@main.route('/email-not-received', methods=['POST'])
def check_and_resend_email_code():
form = EmailNotReceivedForm()
if form.validate_on_submit():
user = users_dao.get_user_by_id(session['user_id'])
users_dao.update_email_address(id=user.id, email_address=form.email_address.data)
send_email_code(user_id=user.id, email=user.email_address)
return redirect('/verify')
return jsonify(form.errors), 400
@main.route("/text-not-received", methods=['GET'])
def text_not_received():
user = users_dao.get_user_by_id(session['user_id'])
return render_template('views/text-not-received.html', form=TextNotReceivedForm(mobile_number=user.mobile_number))
@main.route('/text-not-received', methods=['POST'])
def check_and_resend_text_code():
form = TextNotReceivedForm()
if form.validate_on_submit():
user = users_dao.get_user_by_id(session['user_id'])
users_dao.update_mobile_number(id=user.id, mobile_number=form.mobile_number.data)
send_sms_code(user_id=user.id, mobile_number=user.mobile_number)
return redirect('/verify')
return jsonify(form.errors), 400

View File

@@ -35,16 +35,6 @@ def dashboard():
return render_template('views/dashboard.html')
@main.route("/email-not-received")
def emailnotreceived():
return render_template('views/email-not-received.html')
@main.route("/text-not-received")
def textnotreceived():
return render_template('views/text-not-received.html')
@main.route("/send-email")
def sendemail():
return render_template('views/send-email.html')

View File

@@ -4,7 +4,6 @@ from flask import session
from app.main import main
from app.main.dao import users_dao
from app.main.encryption import check_hash
from app.main.encryption import hashpw
from app.main.forms import LoginForm
from app.main.views import send_sms_code
@@ -26,7 +25,7 @@ def process_sign_in():
if not user.is_active():
return jsonify(active_user=False), 401
if check_hash(form.password.data, user.password):
sms_code = send_sms_code(user.id, user.mobile_number)
send_sms_code(user.id, user.mobile_number)
session['user_id'] = user.id
else:
users_dao.increment_failed_login_count(user.id)

View File

@@ -60,7 +60,7 @@ class User(db.Model):
return True
def is_active(self):
if self.state == 'inactive':
if self.state != 'active':
return False
else:
return True

View File

@@ -28,7 +28,7 @@
@-o-viewport {
width: device-width;
}
/* line 46, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_shims.scss */
/* line 46, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_shims.scss */
#global-header .header-wrapper:after, #global-header .header-wrapper .header-global:after, #global-header .header-wrapper .header-global .header-logo:after, #global-header .header-proposition #proposition-link:after,
#global-header .header-proposition #proposition-links:after, #footer .footer-wrapper:after, #footer .footer-meta:after {
content: "";
@@ -36,19 +36,19 @@
clear: both;
}
/* line 18, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
/* line 18, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
#global-header-bar, #global-cookie-message p {
max-width: 960px;
margin: 0 15px;
}
@media (min-width: 641px) {
/* line 18, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
/* line 18, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
#global-header-bar, #global-cookie-message p {
margin: 0 30px;
}
}
@media (min-width: 1020px) {
/* line 18, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
/* line 18, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_grid_layout.scss */
#global-header-bar, #global-cookie-message p {
margin: 0 auto;
}
@@ -60,7 +60,7 @@
@-o-viewport {
width: device-width;
}
/* line 46, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_shims.scss */
/* line 46, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_shims.scss */
#global-header .header-wrapper:after, #global-header .header-wrapper .header-global:after, #global-header .header-wrapper .header-global .header-logo:after, #global-header .header-proposition #proposition-link:after,
#global-header .header-proposition #proposition-links:after, #footer .footer-wrapper:after, #footer .footer-meta:after {
content: "";
@@ -76,24 +76,24 @@
}
/* local styleguide includes */
/* Old depricated greys, new things should use the toolkit greys */
/* line 1, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 1, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
html, body, button, input, table, td, th {
font-family: "nta", Arial, sans-serif;
}
/* line 4, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 4, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
html, body, div, h1, h2, h3, h4, h5, h6, article, aside, footer, header, hgroup, nav, section {
margin: 0;
padding: 0;
vertical-align: baseline;
}
/* line 11, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 11, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
main {
display: block;
}
/* line 16, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 16, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
.group:before,
.group:after {
content: "\0020";
@@ -102,23 +102,23 @@ main {
overflow: hidden;
}
/* line 24, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 24, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
.group:after {
clear: both;
}
/* line 27, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 27, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
.group {
zoom: 1;
}
/* line 32, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 32, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
.content-fixed {
top: 0;
position: fixed;
}
/* line 36, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 36, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
.shim {
display: block;
}
@@ -127,7 +127,7 @@ main {
* 1. Prevents iOS text size adjust after orientation change, without disabling
* user zoom.
*/
/* line 44, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 44, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
html {
-webkit-text-size-adjust: 100%;
/* 1 */
@@ -139,12 +139,12 @@ html {
/*
Force the scrollbar to always display in IE10/11
*/
/* line 54, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 54, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
html {
-ms-overflow-style: scrollbar;
}
/* line 58, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 58, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
body {
background: #fff;
color: #0b0c0c;
@@ -154,86 +154,86 @@ body {
-moz-osx-font-smoothing: grayscale;
}
/* line 67, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 67, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
ol, ul, nav ol, nav ul {
list-style: inherit;
}
/* line 71, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 71, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
fieldset {
border: none;
padding: 0;
}
/* line 76, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 76, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
a:link {
color: #005ea5;
}
/* line 80, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 80, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
a:visited {
color: #4c2c92;
}
/* line 84, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 84, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
a:hover {
color: #2e8aca;
}
/* line 88, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 88, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
a:active {
color: #2e8aca;
}
/* line 290, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 290, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:after {
background-image: image-url("external-links/external-link.png");
background-repeat: no-repeat;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 20 / 10), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
/* line 290, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 290, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:after {
background-image: image-url("external-links/external-link-24x24.png");
background-size: 12px 400px;
}
}
/* line 231, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 231, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:after {
content: "    ";
background-position: right 6px;
}
/* line 240, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 240, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:hover:after {
background-position: right -382px;
}
@media (max-width: 640px) {
/* line 231, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 231, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:after {
content: "     ";
background-position: right 3px;
}
/* line 240, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 240, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
a[rel="external"]:hover:after {
background-position: right -385px;
}
}
/* line 231, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 231, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
.external-link:after {
content: "        ";
background-position: right 0px;
}
/* line 240, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 240, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
.external-link:hover:after {
background-position: right 0px;
}
/* line 302, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 302, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
.external-link:after {
background-image: image-url("external-links/external-link-black-12x12.png");
background-repeat: no-repeat;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 20 / 10), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
/* line 302, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
/* line 302, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_frontend_toolkit/stylesheets/_typography.scss */
.external-link:after {
background-image: image-url("external-links/external-link-black-24x24.png");
background-size: 12px 400px;
@@ -249,7 +249,7 @@ a[rel="external"]:hover:after {
* 3. Removes Android and iOS tap highlight color to prevent entire container being highlighted
* www.yuiblog.com/blog/2010/10/01/quick-tip-customizing-the-mobile-safari-tap-highlight-color/
*/
/* line 117, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 117, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
html {
font-size: 62.5%;
/* 1 */
@@ -265,7 +265,7 @@ html {
* (62.5% * 160% = 100%)
* 2. Addresses margins handled incorrectly in IE6/7
*/
/* line 130, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 130, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
body {
font-size: 160%;
/* 1 */
@@ -273,18 +273,18 @@ body {
/* 2 */
}
/* line 135, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 135, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
b,
strong {
font-weight: 600;
}
/* line 140, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 140, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
img {
border: 0;
}
/* line 150, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 150, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
abbr[title] {
cursor: help;
}
@@ -294,7 +294,7 @@ abbr[title] {
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
/* line 160, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 160, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
input[type="search"] {
-webkit-appearance: textfield;
/* 1 */
@@ -304,19 +304,19 @@ input[type="search"] {
box-sizing: content-box;
}
/* line 166, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 166, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
margin-right: 2px;
}
/* line 171, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
/* line 171, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_basic.scss */
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/* For image replacement */
/* line 2, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 2, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.ir {
display: block;
text-indent: -999em;
@@ -325,20 +325,20 @@ input[type="search"]::-webkit-search-decoration {
text-align: left;
direction: ltr;
}
/* line 10, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 10, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.ir br {
display: none;
}
/* Hide for both screenreaders and browsers */
/* line 16, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 16, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.hidden {
display: none;
visibility: hidden;
}
/* Hide only visually, but have it available for screenreaders */
/* line 22, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 22, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.visually-hidden,
.visuallyhidden {
position: absolute;
@@ -348,7 +348,7 @@ input[type="search"]::-webkit-search-decoration {
* focusable when navigated to via the keyboard
*/
}
/* line 31, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 31, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.visually-hidden.focusable:active, .visually-hidden.focusable:focus,
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
@@ -361,54 +361,54 @@ input[type="search"]::-webkit-search-decoration {
}
/* Hide visually and from screenreaders, but maintain layout */
/* line 43, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 43, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.invisible {
visibility: hidden;
}
/* Give a strong clear visual idea as to what is currently in focus */
/* line 48, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 48, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.3);
}
/* line 52, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 52, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
a:focus {
background-color: #ffbf47;
outline: 3px solid #ffbf47;
}
/* Make skiplinks visible when they are tabbed to */
/* line 59, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 59, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.skiplink {
position: absolute;
left: -9999em;
}
/* line 64, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 64, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
.skiplink:focus {
position: static;
}
/* line 68, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 68, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
#skiplink-container {
text-align: center;
background: #0b0c0c;
}
/* line 72, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 72, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
#skiplink-container div {
text-align: left;
margin: 0 auto;
max-width: 1020px;
}
/* line 78, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 78, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
#skiplink-container .skiplink {
display: -moz-inline-stack;
display: inline-block;
margin: 0.75em 0 0 30px;
}
/* line 84, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 84, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
input:focus,
textarea:focus,
select:focus,
@@ -417,12 +417,12 @@ button:focus,
outline: 3px solid #ffbf47;
}
/* line 93, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 93, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
#global-header h1 a:focus {
background-color: transparent;
outline: none;
}
/* line 98, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
/* line 98, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_accessibility.scss */
#global-header a:focus {
color: #0b0c0c;
}
@@ -430,12 +430,12 @@ button:focus,
/* @import '_shims'; */
/* @import '_conditionals'; */
/* @import '_measurements'; */
/* line 5, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 5, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header {
background-color: #0b0c0c;
width: 100%;
}
/* line 9, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 9, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper {
background-color: #0b0c0c;
max-width: 990px;
@@ -444,61 +444,61 @@ button:focus,
padding-bottom: 8px;
}
@media (min-width: 641px) {
/* line 9, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 9, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper {
padding-left: 15px;
padding-right: 15px;
}
}
/* line 26, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 26, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper .header-global .header-logo {
float: left;
}
@media (min-width: 769px) {
/* line 26, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 26, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper .header-global .header-logo {
width: 33.33%;
}
}
@media screen and (max-width: 379px) {
/* line 26, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 26, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper .header-global .header-logo {
width: auto;
float: none;
}
}
/* line 38, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 38, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper .header-global .header-logo .content {
margin: 0 15px;
}
/* line 42, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 42, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-wrapper .header-global .header-logo {
margin: 5px 0 2px;
}
@media (min-width: 769px) {
/* line 49, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 49, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header.with-proposition .header-wrapper .header-global {
float: left;
width: 33.33%;
}
/* line 54, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 54, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header.with-proposition .header-wrapper .header-global .header-logo,
#global-header.with-proposition .header-wrapper .header-global .site-search {
width: 100%;
}
}
@media (min-width: 769px) {
/* line 60, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 60, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header.with-proposition .header-wrapper .header-proposition {
width: 66.66%;
float: left;
}
}
/* line 65, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 65, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header.with-proposition .header-wrapper .header-proposition .content {
margin: 0 15px;
}
/* line 72, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 72, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header #logo {
float: left;
position: relative;
@@ -519,7 +519,7 @@ button:focus,
background-size: 35px 31px;
background-position: 0 0;
}
/* line 98, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 98, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header #logo img {
position: relative;
top: -2px;
@@ -532,26 +532,26 @@ button:focus,
border: none;
/* visibility: hidden; */
}
/* line 115, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 115, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header #logo:hover, #global-header #logo:focus {
text-decoration: none;
border-bottom-color: #fff;
}
/* line 121, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 121, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header #logo:active {
color: #2b8cc4;
}
/* line 125, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 125, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition {
padding-top: 10px;
}
@media (min-width: 769px) {
/* line 125, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 125, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition {
padding-top: 0;
}
}
/* line 130, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 130, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-name {
font-family: "nta", Arial, sans-serif;
font-size: 18px;
@@ -563,17 +563,17 @@ button:focus,
text-decoration: none;
}
@media (min-width: 641px) {
/* line 130, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 130, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-name {
font-size: 24px;
line-height: 1.25;
}
}
/* line 136, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 136, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a#proposition-name:hover {
text-decoration: underline;
}
/* line 139, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 139, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu {
font-family: "nta", Arial, sans-serif;
font-size: 14px;
@@ -587,23 +587,23 @@ button:focus,
padding-top: 6px;
}
@media (min-width: 641px) {
/* line 139, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 139, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu {
font-size: 16px;
line-height: 1.25;
}
}
@media (min-width: 769px) {
/* line 139, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 139, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu {
display: none;
}
}
/* line 149, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 149, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu:hover {
text-decoration: underline;
}
/* line 152, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 152, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu:after {
display: inline-block;
font-size: 8px;
@@ -612,45 +612,45 @@ button:focus,
vertical-align: middle;
content: " \25BC";
}
/* line 160, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 160, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition a.menu.js-hidden:after {
content: " \25B2";
}
/* line 164, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 164, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-menu {
margin-top: 5px;
}
@media (min-width: 769px) {
/* line 168, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 168, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-menu.no-proposition-name {
margin-top: 37px;
}
}
/* line 175, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 175, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link,
#global-header .header-proposition #proposition-links {
clear: both;
margin: 2px 0 0 0;
padding: 0;
}
/* line 182, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 182, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
.js-enabled #global-header .header-proposition #proposition-link, .js-enabled
#global-header .header-proposition #proposition-links {
display: none;
}
@media (min-width: 769px) {
/* line 182, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 182, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
.js-enabled #global-header .header-proposition #proposition-link, .js-enabled
#global-header .header-proposition #proposition-links {
display: block;
}
}
/* line 187, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 187, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
.js-enabled #global-header .header-proposition #proposition-link.js-visible, .js-enabled
#global-header .header-proposition #proposition-links.js-visible {
display: block;
}
/* line 192, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 192, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link li,
#global-header .header-proposition #proposition-links li {
float: left;
@@ -659,7 +659,7 @@ button:focus,
border-bottom: 1px solid #2e3133;
}
@media (min-width: 769px) {
/* line 192, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 192, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link li,
#global-header .header-proposition #proposition-links li {
display: block;
@@ -667,13 +667,13 @@ button:focus,
padding: 0 15px 0 0;
border-bottom: 0;
}
/* line 204, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 204, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link li.clear-child,
#global-header .header-proposition #proposition-links li.clear-child {
clear: left;
}
}
/* line 210, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 210, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a,
#global-header .header-proposition #proposition-links a {
color: #fff;
@@ -685,7 +685,7 @@ button:focus,
text-transform: none;
}
@media (min-width: 641px) {
/* line 210, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 210, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a,
#global-header .header-proposition #proposition-links a {
font-size: 14px;
@@ -693,7 +693,7 @@ button:focus,
}
}
@media (min-width: 769px) {
/* line 210, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 210, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a,
#global-header .header-proposition #proposition-links a {
font-family: "nta", Arial, sans-serif;
@@ -705,7 +705,7 @@ button:focus,
}
}
@media (min-width: 769px) and (min-width: 641px) {
/* line 210, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 210, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a,
#global-header .header-proposition #proposition-links a {
font-size: 16px;
@@ -713,59 +713,59 @@ button:focus,
}
}
/* line 220, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 220, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a:hover,
#global-header .header-proposition #proposition-links a:hover {
text-decoration: underline;
}
/* line 223, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 223, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a.active,
#global-header .header-proposition #proposition-links a.active {
color: #1d8feb;
}
/* line 226, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 226, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link a:focus,
#global-header .header-proposition #proposition-links a:focus {
color: #0b0c0c;
}
/* line 232, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 232, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link {
float: right;
line-height: 22px;
}
/* line 235, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 235, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
.js-enabled #global-header .header-proposition #proposition-link {
display: block;
}
@media (min-width: 769px) {
/* line 232, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 232, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header .header-proposition #proposition-link {
float: none;
}
}
/* Global header bar */
/* line 247, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 247, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-header-bar {
height: 10px;
background-color: #005ea5;
}
/* Global cookie message */
/* line 258, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 258, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
.js-enabled #global-cookie-message {
display: none;
/* shown with JS, always on for non-JS */
}
/* line 262, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 262, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-cookie-message {
width: 100%;
background-color: #d5e8f3;
padding-top: 10px;
padding-bottom: 10px;
}
/* line 267, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 267, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-cookie-message p {
font-family: "nta", Arial, sans-serif;
font-size: 14px;
@@ -776,7 +776,7 @@ button:focus,
margin-bottom: 0;
}
@media (min-width: 641px) {
/* line 267, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
/* line 267, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_header.scss */
#global-cookie-message p {
font-size: 16px;
line-height: 1.25;
@@ -784,12 +784,12 @@ button:focus,
}
/* Global footer */
/* line 3, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 3, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer {
background-color: #DEE0E2;
border-top: 1px solid #a1acb2;
}
/* line 7, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 7, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-wrapper {
margin: 0 auto;
width: auto;
@@ -799,20 +799,20 @@ button:focus,
margin: 0 auto;
}
@media (min-width: 641px) {
/* line 7, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 7, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-wrapper {
padding-top: 60px;
}
}
/* line 17, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 17, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer a {
color: #454a4c;
}
/* line 20, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 20, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer a:hover {
color: #171819;
}
/* line 25, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 25, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer h2 {
font-family: "nta", Arial, sans-serif;
font-size: 18px;
@@ -824,17 +824,17 @@ button:focus,
margin: 0;
}
@media (min-width: 641px) {
/* line 25, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 25, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer h2 {
font-size: 24px;
line-height: 1.25;
}
}
/* line 31, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 31, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer h2 a {
color: inherit;
}
/* line 36, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 36, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta {
padding-left: 15px;
padding-right: 15px;
@@ -844,25 +844,25 @@ button:focus,
color: #454a4c;
}
@media (min-width: 641px) {
/* line 36, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 36, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta {
padding-left: 30px;
padding-right: 30px;
}
}
/* line 44, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 44, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner {
display: inline-block;
vertical-align: bottom;
width: 100%;
}
@media (min-width: 641px) {
/* line 44, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 44, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner {
width: 75%;
}
}
/* line 58, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 58, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner ul {
font-family: "nta", Arial, sans-serif;
font-size: 14px;
@@ -875,41 +875,41 @@ button:focus,
padding: 0;
}
@media (min-width: 641px) {
/* line 58, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 58, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner ul {
font-size: 16px;
line-height: 1.5;
}
}
@media (min-width: 641px) {
/* line 58, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 58, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner ul {
margin: 0 0 1em 0;
}
}
/* line 69, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 69, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner ul li {
display: inline-block;
margin: 0 15px 0 0;
}
/* line 81, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 81, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence {
clear: left;
position: relative;
}
@media (min-width: 641px) {
/* line 81, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 81, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence {
padding-left: 53px;
}
}
/* line 93, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 93, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence .logo {
margin-bottom: 1em;
padding-top: 0;
}
@media (min-width: 641px) {
/* line 93, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 93, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence .logo {
position: absolute;
left: 0;
@@ -918,7 +918,7 @@ button:focus,
height: 100%;
}
}
/* line 104, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 104, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence .logo a {
display: block;
width: 41px;
@@ -928,13 +928,13 @@ button:focus,
background: image-url("/static/images/open-government-licence.png") 0 0 no-repeat;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 20 / 10), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
/* line 104, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 104, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence .logo a {
background-image: image-url("/static/images/open-government-licence_2x.png");
background-size: 41px 17px;
}
}
/* line 118, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 118, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence p {
font-family: "nta", Arial, sans-serif;
font-size: 14px;
@@ -945,13 +945,13 @@ button:focus,
padding-top: 0.1em;
}
@media (min-width: 641px) {
/* line 118, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 118, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .footer-meta-inner .open-government-licence p {
font-size: 16px;
line-height: 1.25;
}
}
/* line 126, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 126, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright {
font-family: "nta", Arial, sans-serif;
font-size: 14px;
@@ -963,14 +963,14 @@ button:focus,
display: block;
}
@media (min-width: 641px) {
/* line 126, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 126, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright {
font-size: 16px;
line-height: 1.25;
}
}
@media (min-width: 641px) {
/* line 126, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 126, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright {
display: inline-block;
text-align: inherit;
@@ -979,7 +979,7 @@ button:focus,
margin-top: 0;
}
}
/* line 147, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 147, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright a {
display: block;
background-image: url("/static/images/govuk-crest.png");
@@ -990,20 +990,20 @@ button:focus,
padding: 115px 0 0 0;
}
@media (min-width: 641px) {
/* line 147, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 147, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright a {
background-position: 100% 0%;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 20 / 10), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
/* line 147, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 147, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright a {
background-image: url("/static/images/govuk-crest-2x.png");
background-size: 125px 102px;
}
}
@media (min-width: 641px) {
/* line 147, /Users/chs/gdsworkspace/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
/* line 147, /Users/rebeccalaw/dev-projects/notify/notifications-admin/app/assets/stylesheets/govuk_template/_footer.scss */
#footer .footer-meta .copyright a {
text-align: right;
}

View File

@@ -13,15 +13,17 @@ GOV.UK Notify
<p>Check your email address is correct and then resend the confirmation code.</p>
<p>
<label class="form-label" for="email">Email address</label>
<input class="form-control-2-3" id="email" type="text" value="wrongemail@wrong.com"><br>
<span class="font-xsmall">Your email address must end in .gov.uk</span>
</p>
<form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }}
<label class="form-label">Email address</label>
<p>
<a class="button" href="verify" role="button">Resend confirmation code</a>
</p>
{{ form.email_address(class="form-control-2-3", autocomplete="off") }} <br>
<span class="font-xsmall">Your email address must end in .gov.uk</span>
<p>
<button class="button" href="verify" role="button">Resend confirmation code</button>
</p>
</form>
</div>
</div>

View File

@@ -12,15 +12,16 @@ GOV.UK Notify
<p>Check your mobile phone number is correct and then resend the confirmation code.</p>
<p>
<label class="form-label" for="mobile">Mobile phone number</label>
<input class="form-control-1-4" id="mobile" type="text" value="08983336666">
</p>
<p>
<a class="button" href="verify" role="button">Resend confirmation code</a>
</p>
<form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }}
<p>
<label class="form-label">Mobile phone number</label>
{{ form.mobile_number(class="form-control-1-4", autocomplete="off") }} <br>
</p>
<p>
<button class="button" href="verify" role="button">Resend confirmation code</button>
</p>
</form>
</div>
</div>

View File

@@ -4,13 +4,25 @@ from app.main.dao import users_dao
from app.models import User
def create_test_user():
def create_test_user(state):
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')
state=state)
users_dao.insert_user(user)
return user
def create_another_test_user(state):
user = User(name='Another Test User',
password='someOtherpassword',
email_address='another_test@user.gov.uk',
mobile_number='+442233123412',
created_at=datetime.now(),
role_id=1,
state=state)
users_dao.insert_user(user)
return user

View File

@@ -6,7 +6,7 @@ from tests.app.main import create_test_user
def test_can_insert_and_retrieve_new_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
user = create_test_user('active')
id = services_dao.insert_new_service('testing service', user)
saved_service = services_dao.get_service_by_id(id)
assert id == saved_service.id
@@ -15,7 +15,7 @@ def test_can_insert_and_retrieve_new_service(notifications_admin, notifications_
def test_unrestrict_service_updates_the_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
user = create_test_user('active')
id = services_dao.insert_new_service('unrestricted service', user)
saved_service = services_dao.get_service_by_id(id)
assert saved_service.restricted is True
@@ -25,7 +25,7 @@ def test_unrestrict_service_updates_the_service(notifications_admin, notificatio
def test_activate_service_update_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
user = create_test_user('active')
id = services_dao.insert_new_service('activated service', user)
service = services_dao.get_service_by_id(id)
assert service.active is False
@@ -44,7 +44,7 @@ def test_get_service_returns_none_if_service_does_not_exist(notifications_admin,
def test_find_by_service_name_returns_right_service(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user()
user = create_test_user('active')
id = services_dao.insert_new_service('testing service', user)
another = services_dao.insert_new_service('Testing the Service', user)
found = services_dao.find_service_by_service_name('testing service')
@@ -55,7 +55,7 @@ def test_find_by_service_name_returns_right_service(notifications_admin,
def test_should_not_allow_two_services_of_the_same_name(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
user = create_test_user('active')
services_dao.insert_new_service('duplicate service', user)
with pytest.raises(sqlalchemy.exc.IntegrityError) as error:
services_dao.insert_new_service('duplicate service', user)

View File

@@ -144,3 +144,20 @@ def test_should_throws_error_when_id_does_not_exist(notifications_admin, notific
with pytest.raises(AttributeError) as error:
users_dao.activate_user(123)
assert '''object has no attribute 'state''''' in str(error.value)
def test_should_update_email_address(notifications_admin, notifications_admin_db, notify_db_session):
user = User(name='Update Email',
password='somepassword',
email_address='test@it.gov.uk',
mobile_number='+441234123412',
created_at=datetime.now(),
role_id=1,
state='inactive')
users_dao.insert_user(user)
saved = users_dao.get_user_by_id(user.id)
assert saved.email_address == 'test@it.gov.uk'
users_dao.update_email_address(user.id, 'new_email@testit.gov.uk')
updated = users_dao.get_user_by_id(user.id)
assert updated.email_address == 'new_email@testit.gov.uk'

View File

@@ -3,14 +3,16 @@ from pytest import fail
from app.main.dao import verify_codes_dao
from app.main.encryption import check_hash
from tests.app.main import create_test_user
from tests.app.main import create_test_user, create_another_test_user
def test_insert_new_code_and_get_it_back(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
user = create_test_user('pending')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email')
saved_code = verify_codes_dao.get_code(user_id=user.id, code_type='email')
saved_codes = verify_codes_dao.get_codes(user_id=user.id, code_type='email')
assert len(saved_codes) == 1
saved_code = saved_codes[0]
assert saved_code.user_id == user.id
assert check_hash('12345', saved_code.code)
assert saved_code.code_type == 'email'
@@ -20,7 +22,7 @@ def test_insert_new_code_and_get_it_back(notifications_admin, notifications_admi
def test_insert_new_code_should_thrw_exception_when_type_does_not_exist(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user()
user = create_test_user('pending')
try:
verify_codes_dao.add_code(user_id=user.id, code='23545', code_type='not_real')
fail('Should have thrown an exception')
@@ -42,7 +44,7 @@ def test_should_throw_exception_when_user_does_not_exist(notifications_admin,
def test_should_return_none_if_code_is_used(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user()
user = create_test_user('pending')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email')
verify_codes_dao.use_code(user_id=user.id, code='12345', code_type='email')
@@ -53,10 +55,32 @@ def test_should_return_none_if_code_is_used(notifications_admin,
def test_should_return_none_if_code_is_used(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user()
user = create_test_user('pending')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
code = verify_codes_dao.get_code(user_id=user.id, code_type='sms')
verify_codes_dao.use_code(code.id)
code = verify_codes_dao.get_code(user_id=user.id, code_type='sms')
assert code is None
code = verify_codes_dao.get_codes(user_id=user.id, code_type='sms')
verify_codes_dao.use_code(code[0].id)
used_code = verify_codes_dao.get_codes(user_id=user.id, code_type='sms')
assert used_code == []
def test_should_return_all_unused_code_when_there_are_many(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user('pending')
another_user = create_another_test_user('active')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
id = verify_codes_dao.add_code(user_id=user.id, code='09876', code_type='email')
verify_codes_dao.use_code(id)
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email')
verify_codes_dao.add_code(user_id=user.id, code='23456', code_type='email')
verify_codes_dao.add_code(user_id=another_user.id, code='12345', code_type='sms')
verify_codes_dao.add_code(user_id=another_user.id, code='12345', code_type='email')
user_codes = verify_codes_dao.get_codes(user_id=user.id, code_type='email')
assert len(user_codes) == 2
s = sorted(user_codes, key=lambda r: r.expiry_datetime)
assert check_hash('12345', s[0].code)
assert check_hash('23456', s[1].code)
assert [(code.code_used, code.code_type, code.user_id) for code in user_codes] == \
[(False, 'email', user.id), (False, 'email', user.id)]

View File

@@ -8,7 +8,7 @@ def test_form_should_have_errors_when_duplicate_service_is_added(notifications_a
notify_db_session):
with notifications_admin.test_request_context(method='POST',
data={'service_name': 'some service'}) as req:
user = create_test_user()
user = create_test_user('active')
services_dao.insert_new_service('some service', user)
req.session['user_id'] = user.id
form = AddServiceForm(req.request.form)

View File

@@ -51,13 +51,12 @@ def test_returns_errors_when_code_contains_letters(notifications_admin, notifica
def test_should_return_errors_when_code_is_expired(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_request_context(method='POST',
data={'sms_code': '23456'}) as req:
user = create_test_user()
user = create_test_user('active')
req.session['user_id'] = user.id
verify_codes_dao.add_code_with_expiry(user_id=user.id,
code='23456',
code_type='sms',
expiry=datetime.now() + timedelta(hours=-2))
req.session['user_id'] = user.id
form = TwoFactorForm(req.request.form)
assert form.validate() is False
errors = form.errors
@@ -66,6 +65,6 @@ def test_should_return_errors_when_code_is_expired(notifications_admin, notifica
def set_up_test_data():
user = create_test_user()
user = create_test_user('active')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
return user

View File

@@ -65,7 +65,7 @@ def test_should_return_errors_when_code_is_expired(notifications_admin, notifica
with notifications_admin.test_request_context(method='POST',
data={'sms_code': '23456',
'email_code': '23456'}) as req:
user = create_test_user()
user = create_test_user('pending')
req.session['user_id'] = user.id
verify_codes_dao.add_code_with_expiry(user_id=user.id,
code='23456',
@@ -86,8 +86,24 @@ def test_should_return_errors_when_code_is_expired(notifications_admin, notifica
assert set(errors) == set(expected)
def test_should_return_valid_form_when_many_codes_exist(notifications_admin,
notifications_admin_db,
notify_db_session):
with notifications_admin.test_request_context(method='POST',
data={'sms_code': '23456',
'email_code': '23456'}) as req:
user = set_up_test_data()
verify_codes_dao.add_code(user_id=user.id, code='23456', code_type='email')
verify_codes_dao.add_code(user_id=user.id, code='23456', code_type='sms')
verify_codes_dao.add_code(user_id=user.id, code='60456', code_type='email')
verify_codes_dao.add_code(user_id=user.id, code='27856', code_type='sms')
req.session['user_id'] = user.id
form = VerifyForm(req.request.form)
assert form.validate() is True
def set_up_test_data():
user = create_test_user()
user = create_test_user('pending')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email')
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
return user

View File

@@ -5,7 +5,7 @@ from tests.app.main import create_test_user
def test_get_should_render_add_service_template(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('active')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})
@@ -17,7 +17,7 @@ def test_get_should_render_add_service_template(notifications_admin, notificatio
def test_should_add_service_and_redirect_to_next_page(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('active')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})
@@ -33,7 +33,7 @@ def test_should_return_form_errors_when_service_name_is_empty(notifications_admi
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('active')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})

View File

@@ -0,0 +1,106 @@
from app.main.dao import verify_codes_dao, users_dao
from tests.app.main import create_test_user
def test_should_render_email_code_not_received_template_and_populate_email_address(notifications_admin,
notifications_admin_db,
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user('pending')
session['user_id'] = user.id
response = client.get('/email-not-received')
assert response.status_code == 200
assert 'Check your email address is correct and then resend the confirmation code' \
in response.get_data(as_text=True)
assert 'value="test@user.gov.uk"' in response.get_data(as_text=True)
def test_should_check_and_resend_email_code_redirect_to_verify(notifications_admin,
notifications_admin_db,
notify_db_session,
mocker):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
_set_up_mocker(mocker)
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user.id, code='12345', code_type='email')
response = client.post('/email-not-received',
data={'email_address': 'test@user.gov.uk'})
assert response.status_code == 302
assert response.location == 'http://localhost/verify'
def test_should_render_text_code_not_received_template(notifications_admin,
notifications_admin_db,
notify_db_session,
mocker):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
_set_up_mocker(mocker)
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user.id, code='12345', code_type='email')
response = client.get('/text-not-received')
assert response.status_code == 200
assert 'Check your mobile phone number is correct and then resend the confirmation code.' \
in response.get_data(as_text=True)
assert 'value="+441234123412"'
def test_should_check_and_redirect_to_verify(notifications_admin,
notifications_admin_db,
notify_db_session,
mocker):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
_set_up_mocker(mocker)
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user.id, code='12345', code_type='sms')
response = client.post('/text-not-received',
data={'mobile_number': '+441234123412'})
assert response.status_code == 302
assert response.location == 'http://localhost/verify'
def test_should_update_email_address_resend_code(notifications_admin,
notifications_admin_db,
notify_db_session,
mocker):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
_set_up_mocker(mocker)
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email')
response = client.post('/email-not-received',
data={'email_address': 'new@address.gov.uk'})
assert response.status_code == 302
assert response.location == 'http://localhost/verify'
updated_user = users_dao.get_user_by_id(user.id)
assert updated_user.email_address == 'new@address.gov.uk'
def test_should_update_mobile_number_resend_code(notifications_admin,
notifications_admin_db,
notify_db_session,
mocker):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
_set_up_mocker(mocker)
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
response = client.post('/text-not-received',
data={'mobile_number': '+443456789012'})
assert response.status_code == 302
assert response.location == 'http://localhost/verify'
updated_user = users_dao.get_user_by_id(user.id)
assert updated_user.mobile_number == '+443456789012'
def _set_up_mocker(mocker):
mocker.patch("app.admin_api_client.send_sms")
mocker.patch("app.admin_api_client.send_email")

View File

@@ -20,7 +20,8 @@ def test_process_sign_in_return_2fa_template(notifications_admin, notifications_
mobile_number='+441234123123',
name='valid',
created_at=datetime.now(),
role_id=1)
role_id=1,
state='active')
users_dao.insert_user(user)
response = notifications_admin.test_client().post('/sign-in',
data={'email_address': 'valid@example.gov.uk',
@@ -37,7 +38,8 @@ def test_should_return_locked_out_true_when_user_is_locked(notifications_admin,
mobile_number='+441234123123',
name='valid',
created_at=datetime.now(),
role_id=1)
role_id=1,
state='active')
users_dao.insert_user(user)
for _ in range(10):
notifications_admin.test_client().post('/sign-in',
@@ -86,6 +88,22 @@ def test_should_return_401_when_user_does_not_exist(notifications_admin, notific
assert response.status_code == 401
def test_should_return_400_when_user_is_not_active(notifications_admin, notifications_admin_db, notify_db_session):
user = User(email_address='PendingUser@example.gov.uk',
password='val1dPassw0rd!',
mobile_number='+441234123123',
name='pending user',
created_at=datetime.now(),
role_id=1,
state='pending')
users_dao.insert_user(user)
response = notifications_admin.test_client().post('/sign-in',
data={'email_address': 'PendingUser@example.gov.uk',
'password': 'val1dPassw0rd!'})
assert response.status_code == 401
assert '"active_user": false' in response.get_data(as_text=True)
def _set_up_mocker(mocker):
mocker.patch("app.admin_api_client.send_sms")
mocker.patch("app.admin_api_client.send_email")

View File

@@ -13,7 +13,7 @@ def test_should_render_two_factor_page(notifications_admin, notifications_admin_
def test_should_login_user_and_redirect_to_dashboard(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('active')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
response = client.post('/two-factor',
@@ -28,7 +28,7 @@ def test_should_return_400_with_sms_code_error_when_sms_code_is_wrong(notificati
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('active')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
response = client.post('/two-factor',

View File

@@ -14,7 +14,7 @@ def test_should_redirect_to_add_service_when_code_are_correct(notifications_admi
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
verify_codes_dao.add_code(user_id=user.id, code='23456', code_type='email')
@@ -28,7 +28,7 @@ def test_should_redirect_to_add_service_when_code_are_correct(notifications_admi
def test_should_activate_user_after_verify(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
verify_codes_dao.add_code(user_id=user.id, code='23456', code_type='email')
@@ -43,7 +43,7 @@ def test_should_activate_user_after_verify(notifications_admin, notifications_ad
def test_should_return_400_when_codes_are_wrong(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
user = create_test_user('pending')
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='23345', code_type='sms')
verify_codes_dao.add_code(user_id=user.id, code='98456', code_type='email')
@@ -56,3 +56,24 @@ def test_should_return_400_when_codes_are_wrong(notifications_admin, notificatio
errors = json.loads(response.get_data(as_text=True))
assert len(errors) == 2
assert set(errors) == set(expected)
def test_should_mark_all_codes_as_used_when_many_codes_exist(notifications_admin,
notifications_admin_db,
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user('pending')
session['user_id'] = user.id
code1 = verify_codes_dao.add_code(user_id=user.id, code='23345', code_type='sms')
code2 = verify_codes_dao.add_code(user_id=user.id, code='98456', code_type='email')
code3 = verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
code4 = verify_codes_dao.add_code(user_id=user.id, code='23412', code_type='email')
response = client.post('/verify',
data={'sms_code': '23345',
'email_code': '23412'})
assert response.status_code == 302
assert verify_codes_dao.get_code_by_id(code1).code_used is True
assert verify_codes_dao.get_code_by_id(code2).code_used is True
assert verify_codes_dao.get_code_by_id(code3).code_used is True
assert verify_codes_dao.get_code_by_id(code4).code_used is True