2016-01-12 18:10:16 +00:00
|
|
|
|
import re
|
2015-11-27 09:47:29 +00:00
|
|
|
|
from flask_wtf import Form
|
2016-01-12 10:43:23 +00:00
|
|
|
|
|
|
|
|
|
|
from wtforms import (
|
|
|
|
|
|
StringField,
|
|
|
|
|
|
PasswordField,
|
|
|
|
|
|
ValidationError,
|
|
|
|
|
|
TextAreaField,
|
2016-01-19 15:54:12 +00:00
|
|
|
|
FileField,
|
2016-02-23 15:45:19 +00:00
|
|
|
|
RadioField,
|
2016-03-02 15:25:04 +00:00
|
|
|
|
BooleanField,
|
|
|
|
|
|
HiddenField
|
2016-01-12 10:43:23 +00:00
|
|
|
|
)
|
2016-02-15 13:13:57 +00:00
|
|
|
|
from wtforms.fields.html5 import EmailField, TelField
|
2015-12-01 13:23:54 +00:00
|
|
|
|
from wtforms.validators import DataRequired, Email, Length, Regexp
|
2016-01-11 15:00:51 +00:00
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
from app.main.validators import Blacklist, CsvFileValidator
|
2016-02-01 16:57:40 +00:00
|
|
|
|
|
2016-02-17 15:49:07 +00:00
|
|
|
|
from app.utils import (
|
2016-02-01 16:57:40 +00:00
|
|
|
|
validate_phone_number,
|
|
|
|
|
|
format_phone_number,
|
|
|
|
|
|
InvalidPhoneError
|
|
|
|
|
|
)
|
2015-12-01 15:51:09 +00:00
|
|
|
|
|
2015-11-27 09:47:29 +00:00
|
|
|
|
|
2016-02-19 15:02:13 +00:00
|
|
|
|
def email_address(label='Email address'):
|
2016-01-08 12:00:52 +00:00
|
|
|
|
gov_uk_email \
|
|
|
|
|
|
= "(^[^@^\\s]+@[^@^\\.^\\s]+(\\.[^@^\\.^\\s]*)*.gov.uk)"
|
2016-02-19 15:02:13 +00:00
|
|
|
|
return EmailField(label, validators=[
|
2016-01-08 12:00:52 +00:00
|
|
|
|
Length(min=5, max=255),
|
|
|
|
|
|
DataRequired(message='Email cannot be empty'),
|
|
|
|
|
|
Email(message='Enter a valid email address'),
|
|
|
|
|
|
Regexp(regex=gov_uk_email, message='Enter a gov.uk email address')])
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-02-15 13:13:57 +00:00
|
|
|
|
class UKMobileNumber(TelField):
|
2016-01-12 18:10:16 +00:00
|
|
|
|
|
|
|
|
|
|
def pre_validate(self, form):
|
2016-02-01 16:57:40 +00:00
|
|
|
|
try:
|
|
|
|
|
|
self.data = validate_phone_number(self.data)
|
|
|
|
|
|
except InvalidPhoneError as e:
|
|
|
|
|
|
raise ValidationError(e.message)
|
2016-01-12 18:10:16 +00:00
|
|
|
|
|
|
|
|
|
|
def post_validate(self, form, validation_stopped):
|
|
|
|
|
|
|
|
|
|
|
|
if len(self.data) != 9:
|
|
|
|
|
|
return
|
2016-01-20 11:46:39 +00:00
|
|
|
|
# TODO implement in the render field method.
|
|
|
|
|
|
# API's require no spaces in the number
|
2016-01-20 14:45:50 +00:00
|
|
|
|
# self.data = '+44 7{} {} {}'.format(*re.findall('...', self.data))
|
2016-02-01 16:57:40 +00:00
|
|
|
|
self.data = format_phone_number(self.data)
|
2016-01-12 18:10:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-08 12:00:52 +00:00
|
|
|
|
def mobile_number():
|
2016-01-13 09:26:38 +00:00
|
|
|
|
return UKMobileNumber('Mobile phone number',
|
|
|
|
|
|
validators=[DataRequired(message='Cannot be empty')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-12 11:25:46 +00:00
|
|
|
|
def password(label='Create a password'):
|
|
|
|
|
|
return PasswordField(label,
|
2016-01-08 12:00:52 +00:00
|
|
|
|
validators=[DataRequired(message='Password can not be empty'),
|
|
|
|
|
|
Length(10, 255, message='Password must be at least 10 characters'),
|
|
|
|
|
|
Blacklist(message='That password is blacklisted, too common')])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sms_code():
|
|
|
|
|
|
verify_code = '^\d{5}$'
|
2016-02-02 15:41:54 +00:00
|
|
|
|
return StringField('Text message code',
|
2016-01-08 12:00:52 +00:00
|
|
|
|
validators=[DataRequired(message='Text message confirmation code can not be empty'),
|
|
|
|
|
|
Regexp(regex=verify_code,
|
2016-01-27 12:22:32 +00:00
|
|
|
|
message='Text message confirmation code must be 5 digits')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def email_code():
|
|
|
|
|
|
verify_code = '^\d{5}$'
|
2016-02-02 15:41:54 +00:00
|
|
|
|
return StringField("Email code",
|
2016-01-08 12:00:52 +00:00
|
|
|
|
validators=[DataRequired(message='Email confirmation code can not be empty'),
|
2016-01-27 12:22:32 +00:00
|
|
|
|
Regexp(regex=verify_code, message='Email confirmation code must be 5 digits')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2015-11-27 09:47:29 +00:00
|
|
|
|
class LoginForm(Form):
|
|
|
|
|
|
email_address = StringField('Email address', validators=[
|
2015-11-27 16:25:56 +00:00
|
|
|
|
Length(min=5, max=255),
|
2015-11-27 09:47:29 +00:00
|
|
|
|
DataRequired(message='Email cannot be empty'),
|
2016-01-08 12:00:52 +00:00
|
|
|
|
Email(message='Enter a valid email address')
|
2015-11-27 09:47:29 +00:00
|
|
|
|
])
|
2015-12-02 15:23:03 +00:00
|
|
|
|
password = PasswordField('Password', validators=[
|
2016-01-08 12:00:52 +00:00
|
|
|
|
DataRequired(message='Enter your password')
|
2015-11-27 09:47:29 +00:00
|
|
|
|
])
|
2015-12-01 13:23:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RegisterUserForm(Form):
|
2016-01-05 12:41:20 +00:00
|
|
|
|
|
2015-12-02 15:23:03 +00:00
|
|
|
|
name = StringField('Full name',
|
2015-12-01 13:23:54 +00:00
|
|
|
|
validators=[DataRequired(message='Name can not be empty')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
email_address = email_address()
|
|
|
|
|
|
mobile_number = mobile_number()
|
|
|
|
|
|
password = password()
|
2015-12-04 16:21:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-02 15:25:04 +00:00
|
|
|
|
class RegisterUserFromInviteForm(Form):
|
|
|
|
|
|
name = StringField('Full name',
|
|
|
|
|
|
validators=[DataRequired(message='Name can not be empty')])
|
|
|
|
|
|
mobile_number = mobile_number()
|
|
|
|
|
|
password = password()
|
|
|
|
|
|
service = HiddenField('service')
|
|
|
|
|
|
email_address = HiddenField('email_address')
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-02-19 15:02:13 +00:00
|
|
|
|
class InviteUserForm(Form):
|
|
|
|
|
|
email_address = email_address('Their email address')
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-07 16:56:11 +00:00
|
|
|
|
class TwoFactorForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def __init__(self, validate_code_func, *args, **kwargs):
|
2016-01-07 12:43:10 +00:00
|
|
|
|
'''
|
|
|
|
|
|
Keyword arguments:
|
2016-01-27 12:22:32 +00:00
|
|
|
|
validate_code_func -- Validates the code with the API.
|
2016-01-07 12:43:10 +00:00
|
|
|
|
'''
|
2016-01-27 12:22:32 +00:00
|
|
|
|
self.validate_code_func = validate_code_func
|
2016-01-07 12:43:10 +00:00
|
|
|
|
super(TwoFactorForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-08 12:00:52 +00:00
|
|
|
|
sms_code = sms_code()
|
2016-02-23 15:45:19 +00:00
|
|
|
|
remember_me = BooleanField("Remember me")
|
2015-12-08 12:36:54 +00:00
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def validate_sms_code(self, field):
|
|
|
|
|
|
is_valid, reason = self.validate_code_func(field.data)
|
|
|
|
|
|
if not is_valid:
|
|
|
|
|
|
raise ValidationError(reason)
|
|
|
|
|
|
|
2015-12-07 16:56:11 +00:00
|
|
|
|
|
2015-12-04 16:21:01 +00:00
|
|
|
|
class VerifyForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def __init__(self, validate_code_func, *args, **kwargs):
|
2016-01-07 12:43:10 +00:00
|
|
|
|
'''
|
|
|
|
|
|
Keyword arguments:
|
2016-01-27 12:22:32 +00:00
|
|
|
|
validate_code_func -- Validates the code with the API.
|
2016-01-07 12:43:10 +00:00
|
|
|
|
'''
|
2016-01-27 12:22:32 +00:00
|
|
|
|
self.validate_code_func = validate_code_func
|
2016-01-07 12:43:10 +00:00
|
|
|
|
super(VerifyForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-08 12:00:52 +00:00
|
|
|
|
sms_code = sms_code()
|
|
|
|
|
|
email_code = email_code()
|
2015-12-14 17:12:28 +00:00
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def _validate_code(self, cde, code_type):
|
|
|
|
|
|
is_valid, reason = self.validate_code_func(cde, code_type)
|
|
|
|
|
|
if not is_valid:
|
|
|
|
|
|
raise ValidationError(reason)
|
|
|
|
|
|
|
|
|
|
|
|
def validate_email_code(self, field):
|
|
|
|
|
|
self._validate_code(field.data, 'email')
|
|
|
|
|
|
|
|
|
|
|
|
def validate_sms_code(self, field):
|
|
|
|
|
|
self._validate_code(field.data, 'sms')
|
|
|
|
|
|
|
2015-12-14 17:12:28 +00:00
|
|
|
|
|
2015-12-15 15:35:30 +00:00
|
|
|
|
class EmailNotReceivedForm(Form):
|
2016-01-08 12:00:52 +00:00
|
|
|
|
email_address = email_address()
|
2015-12-15 15:35:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TextNotReceivedForm(Form):
|
2016-01-08 12:00:52 +00:00
|
|
|
|
mobile_number = mobile_number()
|
2015-12-15 15:35:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2015-12-14 17:12:28 +00:00
|
|
|
|
class AddServiceForm(Form):
|
2016-01-15 16:10:24 +00:00
|
|
|
|
def __init__(self, names_func, *args, **kwargs):
|
|
|
|
|
|
"""
|
|
|
|
|
|
Keyword arguments:
|
|
|
|
|
|
names_func -- Returns a list of unique service_names already registered
|
|
|
|
|
|
on the system.
|
|
|
|
|
|
"""
|
|
|
|
|
|
self._names_func = names_func
|
2016-01-04 15:31:50 +00:00
|
|
|
|
super(AddServiceForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-19 09:49:01 +00:00
|
|
|
|
name = StringField(
|
2016-01-18 10:47:53 +00:00
|
|
|
|
'Service name',
|
|
|
|
|
|
validators=[
|
2016-02-26 10:46:49 +00:00
|
|
|
|
DataRequired(message='Service name can’t be empty')
|
2016-01-18 10:47:53 +00:00
|
|
|
|
]
|
|
|
|
|
|
)
|
2015-12-15 10:17:43 +00:00
|
|
|
|
|
2016-01-18 17:35:28 +00:00
|
|
|
|
def validate_name(self, a):
|
|
|
|
|
|
if a.data in self._names_func():
|
2016-02-26 10:46:49 +00:00
|
|
|
|
raise ValidationError('This service name is already in use')
|
2016-01-04 14:00:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-11 13:15:10 +00:00
|
|
|
|
class ServiceNameForm(Form):
|
2016-01-18 16:01:04 +00:00
|
|
|
|
name = StringField(u'New name')
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ConfirmPasswordForm(Form):
|
2016-01-22 16:34:36 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, validate_password_func, *args, **kwargs):
|
|
|
|
|
|
self.validate_password_func = validate_password_func
|
|
|
|
|
|
super(ConfirmPasswordForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-11 13:15:10 +00:00
|
|
|
|
password = PasswordField(u'Enter password')
|
|
|
|
|
|
|
2016-01-22 16:34:36 +00:00
|
|
|
|
def validate_password(self, field):
|
|
|
|
|
|
if not self.validate_password_func(field.data):
|
|
|
|
|
|
raise ValidationError('Invalid password')
|
|
|
|
|
|
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
class SMSTemplateForm(Form):
|
2016-01-19 15:54:12 +00:00
|
|
|
|
name = StringField(
|
|
|
|
|
|
u'Template name',
|
|
|
|
|
|
validators=[DataRequired(message="Template name cannot be empty")])
|
2016-01-22 12:19:15 +00:00
|
|
|
|
|
2016-01-22 12:15:47 +00:00
|
|
|
|
template_content = TextAreaField(
|
2016-01-19 15:54:12 +00:00
|
|
|
|
u'Message',
|
|
|
|
|
|
validators=[DataRequired(message="Template content cannot be empty")])
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
class EmailTemplateForm(SMSTemplateForm):
|
|
|
|
|
|
|
|
|
|
|
|
subject = StringField(
|
|
|
|
|
|
u'Subject',
|
|
|
|
|
|
validators=[DataRequired(message="Subject cannot be empty")])
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-05 17:52:09 +00:00
|
|
|
|
class ForgotPasswordForm(Form):
|
2016-01-08 12:00:52 +00:00
|
|
|
|
email_address = email_address()
|
2016-01-04 14:00:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-06 17:37:07 +00:00
|
|
|
|
class NewPasswordForm(Form):
|
2016-01-08 12:00:52 +00:00
|
|
|
|
new_password = password()
|
2016-01-11 15:00:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-12 11:25:46 +00:00
|
|
|
|
class ChangePasswordForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, validate_password_func, *args, **kwargs):
|
|
|
|
|
|
self.validate_password_func = validate_password_func
|
|
|
|
|
|
super(ChangePasswordForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-12 11:25:46 +00:00
|
|
|
|
old_password = password('Current password')
|
|
|
|
|
|
new_password = password('New password')
|
|
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def validate_old_password(self, field):
|
|
|
|
|
|
if not self.validate_password_func(field.data):
|
|
|
|
|
|
raise ValidationError('Invalid password')
|
|
|
|
|
|
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
2016-01-11 15:00:51 +00:00
|
|
|
|
class CsvUploadForm(Form):
|
2016-02-04 12:20:24 +00:00
|
|
|
|
file = FileField('Add recipients', validators=[DataRequired(
|
2016-01-12 10:43:23 +00:00
|
|
|
|
message='Please pick a file'), CsvFileValidator()])
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChangeNameForm(Form):
|
|
|
|
|
|
new_name = StringField(u'Your name')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChangeEmailForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, validate_email_func, *args, **kwargs):
|
|
|
|
|
|
self.validate_email_func = validate_email_func
|
|
|
|
|
|
super(ChangeEmailForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
email_address = email_address()
|
|
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def validate_email_address(self, field):
|
|
|
|
|
|
is_valid = self.validate_email_func(field.data)
|
|
|
|
|
|
if not is_valid:
|
|
|
|
|
|
raise ValidationError("The email address is already in use")
|
|
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
class ConfirmEmailForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, validate_code_func, *args, **kwargs):
|
|
|
|
|
|
self.validate_code_func = validate_code_func
|
|
|
|
|
|
super(ConfirmEmailForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
email_code = email_code()
|
|
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def validate_email_code(self, field):
|
|
|
|
|
|
is_valid, msg = self.validate_code_func(field.data)
|
|
|
|
|
|
if not is_valid:
|
|
|
|
|
|
raise ValidationError(msg)
|
|
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
class ChangeMobileNumberForm(Form):
|
|
|
|
|
|
mobile_number = mobile_number()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ConfirmMobileNumberForm(Form):
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, validate_code_func, *args, **kwargs):
|
|
|
|
|
|
self.validate_code_func = validate_code_func
|
|
|
|
|
|
super(ConfirmMobileNumberForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
sms_code = sms_code()
|
2016-01-19 09:55:13 +00:00
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
|
def validate_sms_code(self, field):
|
|
|
|
|
|
is_valid, msg = self.validate_code_func(field.data)
|
|
|
|
|
|
if not is_valid:
|
|
|
|
|
|
raise ValidationError(msg)
|
|
|
|
|
|
|
2016-01-19 09:55:13 +00:00
|
|
|
|
|
|
|
|
|
|
class CreateKeyForm(Form):
|
2016-01-21 14:15:36 +00:00
|
|
|
|
def __init__(self, existing_key_names=[], *args, **kwargs):
|
2016-01-21 16:52:01 +00:00
|
|
|
|
self.existing_key_names = [x.lower() for x in existing_key_names]
|
2016-01-21 14:15:36 +00:00
|
|
|
|
super(CreateKeyForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
key_name = StringField(u'Description of key', validators=[
|
|
|
|
|
|
DataRequired(message='You need to give the key a name')
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
def validate_key_name(self, key_name):
|
2016-01-21 16:52:01 +00:00
|
|
|
|
if key_name.data.lower() in self.existing_key_names:
|
2016-01-21 14:15:36 +00:00
|
|
|
|
raise ValidationError('A key with this name already exists')
|