2017-02-15 15:06:47 +00:00
|
|
|
|
import re
|
2016-08-07 09:17:49 +01:00
|
|
|
|
import pytz
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
2017-07-26 10:59:10 +01:00
|
|
|
|
from flask_wtf import FlaskForm as Form
|
2016-08-07 09:17:49 +01:00
|
|
|
|
from datetime import datetime, timedelta
|
2017-08-07 11:30:25 +01:00
|
|
|
|
|
2016-04-14 12:00:55 +01:00
|
|
|
|
from notifications_utils.recipients import (
|
2016-03-31 15:17:05 +01:00
|
|
|
|
validate_phone_number,
|
|
|
|
|
|
InvalidPhoneError
|
|
|
|
|
|
)
|
2017-05-25 09:40:37 +01:00
|
|
|
|
from notifications_utils.columns import Columns
|
2016-01-12 10:43:23 +00:00
|
|
|
|
from wtforms import (
|
2017-06-21 17:34:22 +01:00
|
|
|
|
widgets,
|
2016-05-11 09:43:55 +01:00
|
|
|
|
validators,
|
2016-01-12 10:43:23 +00:00
|
|
|
|
StringField,
|
|
|
|
|
|
PasswordField,
|
|
|
|
|
|
ValidationError,
|
|
|
|
|
|
TextAreaField,
|
2016-01-19 15:54:12 +00:00
|
|
|
|
FileField,
|
2016-03-02 15:25:04 +00:00
|
|
|
|
BooleanField,
|
2016-05-11 09:43:55 +01:00
|
|
|
|
HiddenField,
|
2016-06-29 17:10:49 +01:00
|
|
|
|
IntegerField,
|
2016-09-20 12:30:00 +01:00
|
|
|
|
RadioField,
|
2016-12-28 14:44:53 +00:00
|
|
|
|
FieldList,
|
2017-01-18 15:11:34 +00:00
|
|
|
|
DateField,
|
2017-10-18 14:51:26 +01:00
|
|
|
|
)
|
2017-03-14 10:46:38 +00:00
|
|
|
|
from wtforms.fields.html5 import EmailField, TelField, SearchField
|
2016-09-20 12:30:00 +01:00
|
|
|
|
from wtforms.validators import (DataRequired, Email, Length, Regexp, Optional)
|
2017-07-28 15:17:50 +01:00
|
|
|
|
from flask_wtf.file import FileField as FileField_wtf, FileAllowed
|
2016-01-11 15:00:51 +00:00
|
|
|
|
|
2017-02-13 13:11:29 +00:00
|
|
|
|
from app.main.validators import (Blacklist, CsvFileValidator, ValidGovEmail, NoCommasInPlaceHolders, OnlyGSMCharacters)
|
2016-02-01 16:57:40 +00:00
|
|
|
|
|
2015-11-27 09:47:29 +00:00
|
|
|
|
|
2016-08-07 09:17:49 +01:00
|
|
|
|
def get_time_value_and_label(future_time):
|
|
|
|
|
|
return (
|
|
|
|
|
|
future_time.replace(tzinfo=None).isoformat(),
|
2016-10-11 14:11:10 +01:00
|
|
|
|
'{} at {}'.format(
|
|
|
|
|
|
get_human_day(future_time.astimezone(pytz.timezone('Europe/London'))),
|
|
|
|
|
|
get_human_time(future_time.astimezone(pytz.timezone('Europe/London')))
|
|
|
|
|
|
)
|
2016-08-07 09:17:49 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_human_time(time):
|
|
|
|
|
|
return {
|
2016-10-11 14:11:10 +01:00
|
|
|
|
'0': 'midnight',
|
|
|
|
|
|
'12': 'midday'
|
2016-08-07 09:17:49 +01:00
|
|
|
|
}.get(
|
|
|
|
|
|
time.strftime('%-H'),
|
|
|
|
|
|
time.strftime('%-I%p').lower()
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-11 17:59:09 +01:00
|
|
|
|
def get_human_day(time, prefix_today_with='T'):
|
2016-10-11 14:11:10 +01:00
|
|
|
|
# Add 1 hour to get ‘midnight today’ instead of ‘midnight tomorrow’
|
|
|
|
|
|
time = (time - timedelta(hours=1)).strftime('%A')
|
|
|
|
|
|
if time == datetime.utcnow().strftime('%A'):
|
2016-10-11 17:59:09 +01:00
|
|
|
|
return '{}oday'.format(prefix_today_with)
|
2016-10-11 14:11:10 +01:00
|
|
|
|
if time == (datetime.utcnow() + timedelta(days=1)).strftime('%A'):
|
|
|
|
|
|
return 'Tomorrow'
|
|
|
|
|
|
return time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_furthest_possible_scheduled_time():
|
|
|
|
|
|
return (datetime.utcnow() + timedelta(days=4)).replace(hour=0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_next_hours_until(until):
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
hours = int((until - now).total_seconds() / (60 * 60))
|
2016-08-07 09:17:49 +01:00
|
|
|
|
return [
|
|
|
|
|
|
(now + timedelta(hours=i)).replace(minute=0, second=0).replace(tzinfo=pytz.utc)
|
|
|
|
|
|
for i in range(1, hours + 1)
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-11 14:11:10 +01:00
|
|
|
|
def get_next_days_until(until):
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
days = int((until - now).total_seconds() / (60 * 60 * 24))
|
|
|
|
|
|
return [
|
2016-10-11 17:59:09 +01:00
|
|
|
|
get_human_day(
|
|
|
|
|
|
(now + timedelta(days=i)).replace(tzinfo=pytz.utc),
|
|
|
|
|
|
prefix_today_with='Later t'
|
|
|
|
|
|
)
|
2016-10-11 14:11:10 +01:00
|
|
|
|
for i in range(0, days + 1)
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-26 14:01:01 +01:00
|
|
|
|
def email_address(label='Email address', gov_user=True):
|
|
|
|
|
|
validators = [
|
2016-01-08 12:00:52 +00:00
|
|
|
|
Length(min=5, max=255),
|
2016-04-04 10:42:04 +01:00
|
|
|
|
DataRequired(message='Can’t be empty'),
|
2016-10-26 14:01:01 +01:00
|
|
|
|
Email(message='Enter a valid email address')
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
if gov_user:
|
2016-10-28 10:45:05 +01:00
|
|
|
|
validators.append(ValidGovEmail())
|
2016-10-26 14:01:01 +01:00
|
|
|
|
return EmailField(label, validators)
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
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:
|
2016-03-08 07:17:39 +00:00
|
|
|
|
validate_phone_number(self.data)
|
2016-02-01 16:57:40 +00:00
|
|
|
|
except InvalidPhoneError as e:
|
2016-12-20 14:38:34 +00:00
|
|
|
|
raise ValidationError(str(e))
|
2016-01-12 18:10:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-05-25 09:40:37 +01:00
|
|
|
|
class InternationalPhoneNumber(TelField):
|
|
|
|
|
|
def pre_validate(self, form):
|
|
|
|
|
|
try:
|
2017-11-10 12:35:21 +00:00
|
|
|
|
if self.data:
|
|
|
|
|
|
validate_phone_number(self.data, international=True)
|
2017-05-25 09:40:37 +01:00
|
|
|
|
except InvalidPhoneError as e:
|
|
|
|
|
|
raise ValidationError(str(e))
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-08-29 14:52:24 +01:00
|
|
|
|
def uk_mobile_number(label='Mobile number'):
|
2017-05-25 09:40:37 +01:00
|
|
|
|
return UKMobileNumber(label,
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-05-25 09:40:37 +01:00
|
|
|
|
def international_phone_number(label='Mobile number'):
|
|
|
|
|
|
return InternationalPhoneNumber(
|
|
|
|
|
|
label,
|
|
|
|
|
|
validators=[DataRequired(message='Can’t be empty')]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-04-07 14:12:40 +01:00
|
|
|
|
def password(label='Password'):
|
2016-01-12 11:25:46 +00:00
|
|
|
|
return PasswordField(label,
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty'),
|
2016-09-26 09:29:50 +01:00
|
|
|
|
Length(8, 255, message='Must be at least 8 characters'),
|
2016-09-27 11:37:20 +01:00
|
|
|
|
Blacklist(message='Choose a password that’s harder to guess')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sms_code():
|
|
|
|
|
|
verify_code = '^\d{5}$'
|
2016-02-02 15:41:54 +00:00
|
|
|
|
return StringField('Text message code',
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty'),
|
2016-01-08 12:00:52 +00:00
|
|
|
|
Regexp(regex=verify_code,
|
2017-02-15 14:56:22 +00:00
|
|
|
|
message='Code not found')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-05 12:06:40 +01:00
|
|
|
|
def organisation_type():
|
|
|
|
|
|
return RadioField(
|
|
|
|
|
|
'Who runs this service?',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('central', 'Central government'),
|
|
|
|
|
|
('local', 'Local government'),
|
|
|
|
|
|
('nhs', 'NHS'),
|
|
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
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),
|
2016-04-04 10:42:04 +01:00
|
|
|
|
DataRequired(message='Can’t 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):
|
2015-12-02 15:23:03 +00:00
|
|
|
|
name = StringField('Full name',
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty')])
|
2016-01-08 12:00:52 +00:00
|
|
|
|
email_address = email_address()
|
2017-08-29 14:52:24 +01:00
|
|
|
|
mobile_number = international_phone_number()
|
2016-01-08 12:00:52 +00:00
|
|
|
|
password = password()
|
2017-11-13 13:39:31 +00:00
|
|
|
|
# always register as sms type
|
|
|
|
|
|
auth_type = HiddenField('auth_type', default='sms_auth')
|
2015-12-04 16:21:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-02 15:25:04 +00:00
|
|
|
|
class RegisterUserFromInviteForm(Form):
|
2017-11-14 15:53:38 +00:00
|
|
|
|
def __init__(self, invited_user):
|
|
|
|
|
|
super().__init__(
|
|
|
|
|
|
service=invited_user['service'],
|
|
|
|
|
|
email_address=invited_user['email_address'],
|
|
|
|
|
|
auth_type=invited_user['auth_type'],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2017-11-10 12:35:21 +00:00
|
|
|
|
name = StringField(
|
|
|
|
|
|
'Full name',
|
|
|
|
|
|
validators=[DataRequired(message='Can’t be empty')]
|
|
|
|
|
|
)
|
|
|
|
|
|
mobile_number = InternationalPhoneNumber('Mobile number', validators=[])
|
2016-03-02 15:25:04 +00:00
|
|
|
|
password = password()
|
|
|
|
|
|
service = HiddenField('service')
|
2016-03-08 16:29:05 +00:00
|
|
|
|
email_address = HiddenField('email_address')
|
2017-11-13 13:39:31 +00:00
|
|
|
|
auth_type = HiddenField('auth_type', validators=[DataRequired()])
|
2016-03-02 15:25:04 +00:00
|
|
|
|
|
2017-11-10 12:35:21 +00:00
|
|
|
|
def validate_mobile_number(self, field):
|
2017-11-13 13:39:31 +00:00
|
|
|
|
if self.auth_type.data == 'sms_auth' and not field.data:
|
2017-11-10 12:35:21 +00:00
|
|
|
|
raise ValidationError('Can’t be empty')
|
|
|
|
|
|
|
2016-03-02 15:25:04 +00:00
|
|
|
|
|
2016-03-22 13:18:06 +00:00
|
|
|
|
class PermissionsForm(Form):
|
|
|
|
|
|
send_messages = BooleanField("Send messages from existing templates")
|
2017-08-17 11:14:26 +01:00
|
|
|
|
manage_templates = BooleanField("Add and edit templates")
|
|
|
|
|
|
manage_service = BooleanField("Modify this service and its team")
|
2016-03-22 13:18:06 +00:00
|
|
|
|
manage_api_keys = BooleanField("Create and revoke API keys")
|
2017-11-01 15:36:27 +00:00
|
|
|
|
login_authentication = RadioField(
|
|
|
|
|
|
'Sign in using',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('sms_auth', 'Text message code'),
|
|
|
|
|
|
('email_auth', 'Email link'),
|
|
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()]
|
|
|
|
|
|
)
|
2016-03-09 17:42:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-22 13:18:06 +00:00
|
|
|
|
class InviteUserForm(PermissionsForm):
|
2016-10-26 14:01:01 +01:00
|
|
|
|
email_address = email_address(gov_user=False)
|
2016-03-09 13:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
def __init__(self, invalid_email_address, *args, **kwargs):
|
|
|
|
|
|
super(InviteUserForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
self.invalid_email_address = invalid_email_address.lower()
|
|
|
|
|
|
|
|
|
|
|
|
def validate_email_address(self, field):
|
|
|
|
|
|
if field.data.lower() == self.invalid_email_address:
|
2016-04-04 10:42:04 +01:00
|
|
|
|
raise ValidationError("You can’t send an invitation to yourself")
|
2016-03-09 13:00:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
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()
|
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-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):
|
2017-08-29 14:52:24 +01:00
|
|
|
|
mobile_number = international_phone_number()
|
2015-12-15 15:35:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-04 11:49:32 +01:00
|
|
|
|
class RenameServiceForm(Form):
|
2016-03-10 14:29:31 +00:00
|
|
|
|
name = StringField(
|
2016-06-20 13:33:29 +01:00
|
|
|
|
u'Service name',
|
2016-03-10 14:29:31 +00:00
|
|
|
|
validators=[
|
2016-04-04 10:42:04 +01:00
|
|
|
|
DataRequired(message='Can’t be empty')
|
2016-03-10 14:29:31 +00:00
|
|
|
|
])
|
|
|
|
|
|
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
2017-10-04 11:49:32 +01:00
|
|
|
|
class CreateServiceForm(Form):
|
|
|
|
|
|
name = StringField(
|
|
|
|
|
|
u'What’s your service called?',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired(message='Can’t be empty')
|
|
|
|
|
|
])
|
2017-10-05 12:06:40 +01:00
|
|
|
|
organisation_type = organisation_type()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OrganisationTypeForm(Form):
|
|
|
|
|
|
organisation_type = organisation_type()
|
2017-10-04 11:49:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-05 13:49:43 +01:00
|
|
|
|
class FreeSMSAllowance(Form):
|
|
|
|
|
|
free_sms_allowance = IntegerField(
|
|
|
|
|
|
'Numbers of text message fragments per year',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired(message='Can’t be empty')
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2017-02-15 15:06:47 +00:00
|
|
|
|
class BaseTemplateForm(Form):
|
2016-01-19 15:54:12 +00:00
|
|
|
|
name = StringField(
|
|
|
|
|
|
u'Template name',
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message="Can’t be empty")])
|
2016-01-22 12:19:15 +00:00
|
|
|
|
|
2016-01-22 12:15:47 +00:00
|
|
|
|
template_content = TextAreaField(
|
2016-06-20 11:37:42 +01:00
|
|
|
|
u'Message',
|
2016-04-07 16:02:06 +01:00
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired(message="Can’t be empty"),
|
2017-02-15 15:06:47 +00:00
|
|
|
|
NoCommasInPlaceHolders()
|
2016-04-07 16:02:06 +01:00
|
|
|
|
]
|
|
|
|
|
|
)
|
2017-01-19 09:35:34 +00:00
|
|
|
|
process_type = RadioField(
|
|
|
|
|
|
'Use priority queue?',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('priority', 'Yes'),
|
|
|
|
|
|
('normal', 'No'),
|
|
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()],
|
|
|
|
|
|
default='normal'
|
|
|
|
|
|
)
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-15 15:06:47 +00:00
|
|
|
|
class SMSTemplateForm(BaseTemplateForm):
|
|
|
|
|
|
def validate_template_content(self, field):
|
|
|
|
|
|
OnlyGSMCharacters()(None, field)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EmailTemplateForm(BaseTemplateForm):
|
2016-04-14 14:04:41 +01:00
|
|
|
|
subject = TextAreaField(
|
2016-02-22 14:45:13 +00:00
|
|
|
|
u'Subject',
|
2016-04-04 10:42:04 +01:00
|
|
|
|
validators=[DataRequired(message="Can’t be empty")])
|
2016-02-22 14:45:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-08 13:12:07 +00:00
|
|
|
|
class LetterTemplateForm(EmailTemplateForm):
|
2017-03-13 10:55:15 +00:00
|
|
|
|
|
|
|
|
|
|
subject = TextAreaField(
|
2017-05-10 11:27:45 +01:00
|
|
|
|
u'Main heading',
|
2017-03-13 10:55:15 +00:00
|
|
|
|
validators=[DataRequired(message="Can’t be empty")])
|
|
|
|
|
|
|
|
|
|
|
|
template_content = TextAreaField(
|
|
|
|
|
|
u'Body',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired(message="Can’t be empty"),
|
|
|
|
|
|
NoCommasInPlaceHolders()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
2016-11-08 13:12:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-01-05 17:52:09 +00:00
|
|
|
|
class ForgotPasswordForm(Form):
|
2016-10-26 14:01:01 +01:00
|
|
|
|
email_address = email_address(gov_user=False)
|
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-05-11 09:43:55 +01: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 ChangeMobileNumberForm(Form):
|
2017-08-29 14:52:24 +01:00
|
|
|
|
mobile_number = international_phone_number()
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-08-07 09:17:49 +01:00
|
|
|
|
class ChooseTimeForm(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
super(ChooseTimeForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
self.scheduled_for.choices = [('', 'Now')] + [
|
2016-10-11 14:11:10 +01:00
|
|
|
|
get_time_value_and_label(hour) for hour in get_next_hours_until(
|
|
|
|
|
|
get_furthest_possible_scheduled_time()
|
|
|
|
|
|
)
|
2016-08-07 09:17:49 +01:00
|
|
|
|
]
|
2016-10-11 14:17:29 +01:00
|
|
|
|
self.scheduled_for.categories = get_next_days_until(get_furthest_possible_scheduled_time())
|
2016-08-07 09:17:49 +01:00
|
|
|
|
|
|
|
|
|
|
scheduled_for = RadioField(
|
|
|
|
|
|
'When should Notify send these messages?',
|
|
|
|
|
|
default='',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
2016-06-29 17:10:49 +01:00
|
|
|
|
key_type = RadioField(
|
2017-04-26 13:21:27 +01:00
|
|
|
|
'Type of key',
|
2016-06-29 17:10:49 +01:00
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-01-21 14:15:36 +00:00
|
|
|
|
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')
|
2016-04-19 13:51:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:25:43 +00:00
|
|
|
|
class SupportType(Form):
|
|
|
|
|
|
support_type = RadioField(
|
|
|
|
|
|
'How can we help you?',
|
|
|
|
|
|
choices=[
|
2017-11-28 11:59:11 +00:00
|
|
|
|
('report-problem', 'Report a problem'),
|
|
|
|
|
|
('ask-question-give-feedback', 'Ask a question or give feedback'),
|
2016-12-12 11:25:43 +00:00
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-21 14:55:49 +00:00
|
|
|
|
class Feedback(Form):
|
2016-04-19 13:51:16 +01:00
|
|
|
|
name = StringField('Name')
|
|
|
|
|
|
email_address = StringField('Email address')
|
2016-12-12 11:25:43 +00:00
|
|
|
|
feedback = TextAreaField('Your message', validators=[DataRequired(message="Can’t be empty")])
|
2016-04-26 13:31:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-12-21 14:55:49 +00:00
|
|
|
|
class Problem(Feedback):
|
|
|
|
|
|
email_address = email_address(label='Email address', gov_user=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
class Triage(Form):
|
|
|
|
|
|
severe = RadioField(
|
|
|
|
|
|
'Is it an emergency?',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('yes', 'Yes'),
|
|
|
|
|
|
('no', 'No'),
|
|
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-04-26 13:31:57 +01:00
|
|
|
|
class RequestToGoLiveForm(Form):
|
2016-11-01 11:31:39 +00:00
|
|
|
|
mou = RadioField(
|
|
|
|
|
|
(
|
|
|
|
|
|
'Has your organisation accepted the GOV.UK Notify data sharing and financial '
|
|
|
|
|
|
'agreement (Memorandum of Understanding)?'
|
|
|
|
|
|
),
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('yes', 'Yes'),
|
2016-11-02 15:46:22 +00:00
|
|
|
|
('no', 'No'),
|
|
|
|
|
|
('don’t know', 'I don’t know')
|
2016-11-01 11:31:39 +00:00
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()]
|
|
|
|
|
|
)
|
2017-09-27 10:46:52 +01:00
|
|
|
|
channel_email = BooleanField('Emails')
|
|
|
|
|
|
channel_sms = BooleanField('Text messages')
|
|
|
|
|
|
channel_letter = BooleanField('Letters')
|
2016-10-24 15:46:22 +01:00
|
|
|
|
start_date = StringField(
|
2016-10-24 16:10:41 +01:00
|
|
|
|
'When will you be ready to start sending messages?',
|
|
|
|
|
|
validators=[DataRequired(message='Can’t be empty')]
|
2016-10-24 15:46:22 +01:00
|
|
|
|
)
|
2016-10-24 13:38:55 +01:00
|
|
|
|
start_volume = StringField(
|
2016-11-01 11:30:03 +00:00
|
|
|
|
'How many messages do you expect to send to start with?',
|
2016-10-24 16:10:41 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty')]
|
2016-10-24 13:38:55 +01:00
|
|
|
|
)
|
|
|
|
|
|
peak_volume = StringField(
|
2016-11-01 11:30:03 +00:00
|
|
|
|
'Will the number of messages increase and when will that start?',
|
2016-10-24 16:10:41 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty')]
|
2016-10-24 13:38:55 +01:00
|
|
|
|
)
|
2016-10-31 15:05:22 +00:00
|
|
|
|
upload_or_api = RadioField(
|
2016-10-31 15:21:29 +00:00
|
|
|
|
'How are you going to send messages?',
|
2016-10-31 15:05:22 +00:00
|
|
|
|
choices=[
|
|
|
|
|
|
('File upload', 'Upload a spreadsheet of recipients'),
|
|
|
|
|
|
('API', 'Integrate with the GOV.UK Notify API'),
|
|
|
|
|
|
('API and file upload', 'Both')
|
|
|
|
|
|
],
|
|
|
|
|
|
validators=[DataRequired()]
|
2016-10-24 13:38:55 +01:00
|
|
|
|
)
|
2016-05-11 09:43:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ProviderForm(Form):
|
|
|
|
|
|
priority = IntegerField('Priority', [validators.NumberRange(min=1, max=100, message="Must be between 1 and 100")])
|
2016-05-16 13:09:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-09-25 15:14:13 +01:00
|
|
|
|
class ServiceReplyToEmailForm(Form):
|
2016-08-23 14:16:07 +01:00
|
|
|
|
email_address = email_address(label='Email reply to address')
|
2017-09-26 15:34:19 +01:00
|
|
|
|
is_default = BooleanField("Make this email address the default")
|
2016-07-01 13:47:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 14:30:43 +00:00
|
|
|
|
class ServiceSmsSenderForm(Form):
|
2016-08-22 16:10:57 +01:00
|
|
|
|
sms_sender = StringField(
|
|
|
|
|
|
'Text message sender',
|
|
|
|
|
|
validators=[
|
2017-05-19 17:12:44 +01:00
|
|
|
|
DataRequired(message="Can’t be empty"),
|
2017-02-27 15:49:42 +00:00
|
|
|
|
Length(max=11, message="Enter 11 characters or fewer")
|
2016-08-22 16:10:57 +01:00
|
|
|
|
]
|
|
|
|
|
|
)
|
2017-10-24 15:37:44 +01:00
|
|
|
|
is_default = BooleanField("Make this text message sender the default")
|
2016-07-01 13:47:22 +01:00
|
|
|
|
|
2017-10-27 10:56:03 +01:00
|
|
|
|
def validate_sms_sender(self, field):
|
2017-03-02 15:56:28 +00:00
|
|
|
|
if field.data and not re.match(r'^[a-zA-Z0-9\s]+$', field.data):
|
2016-08-22 16:10:57 +01:00
|
|
|
|
raise ValidationError('Use letters and numbers only')
|
2016-08-08 10:28:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 14:30:43 +00:00
|
|
|
|
class ServiceEditInboundNumberForm(Form):
|
|
|
|
|
|
is_default = BooleanField("Make this text message sender the default")
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-05 15:47:12 +01:00
|
|
|
|
class ServiceLetterContactBlockForm(Form):
|
2017-05-17 15:35:21 +01:00
|
|
|
|
letter_contact_block = TextAreaField(
|
|
|
|
|
|
validators=[
|
2017-09-26 14:41:07 +01:00
|
|
|
|
DataRequired(message="Can’t be empty"),
|
2017-05-17 15:35:21 +01:00
|
|
|
|
NoCommasInPlaceHolders()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
2017-10-05 15:47:12 +01:00
|
|
|
|
is_default = BooleanField("Set as your default address")
|
2017-03-02 15:56:28 +00:00
|
|
|
|
|
2017-10-27 10:56:03 +01:00
|
|
|
|
def validate_letter_contact_block(self, field):
|
2017-03-03 16:15:15 +00:00
|
|
|
|
line_count = field.data.strip().count('\n')
|
|
|
|
|
|
if line_count >= 10:
|
|
|
|
|
|
raise ValidationError(
|
|
|
|
|
|
'Contains {} lines, maximum is 10'.format(line_count + 1)
|
|
|
|
|
|
)
|
2017-03-02 15:56:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-08-08 10:28:40 +01:00
|
|
|
|
class ServiceBrandingOrg(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, organisations=[], *args, **kwargs):
|
|
|
|
|
|
self.organisation.choices = organisations
|
|
|
|
|
|
super(ServiceBrandingOrg, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
branding_type = RadioField(
|
|
|
|
|
|
'Branding',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('govuk', 'GOV.UK only'),
|
|
|
|
|
|
('both', 'GOV.UK and organisation'),
|
2017-09-19 13:32:42 +01:00
|
|
|
|
('org', 'Organisation only'),
|
|
|
|
|
|
('org_banner', 'Organisation banner')
|
2016-08-08 10:28:40 +01:00
|
|
|
|
],
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
organisation = RadioField(
|
|
|
|
|
|
'Organisation',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
2016-09-20 12:30:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-07-28 15:17:50 +01:00
|
|
|
|
class ServiceSelectOrg(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, organisations=[], *args, **kwargs):
|
|
|
|
|
|
self.organisation.choices = organisations
|
|
|
|
|
|
super(ServiceSelectOrg, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
organisation = RadioField(
|
|
|
|
|
|
'Organisation',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ServiceManageOrg(Form):
|
|
|
|
|
|
|
|
|
|
|
|
name = StringField('Name')
|
|
|
|
|
|
|
|
|
|
|
|
colour = StringField('Colour', render_kw={'onkeyup': 'update_colour_span()', 'onblur': 'update_colour_span()'})
|
|
|
|
|
|
file = FileField_wtf('Upload a PNG logo', validators=[FileAllowed(['png'], 'PNG Images only!')])
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-04-19 16:11:28 +01:00
|
|
|
|
class LetterBranding(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, choices=[], *args, **kwargs):
|
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
self.dvla_org_id.choices = choices
|
|
|
|
|
|
|
|
|
|
|
|
dvla_org_id = RadioField(
|
|
|
|
|
|
'Which logo should this service’s letter have?',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-09-20 12:30:00 +01:00
|
|
|
|
class Whitelist(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def populate(self, email_addresses, phone_numbers):
|
|
|
|
|
|
for form_field, existing_whitelist in (
|
|
|
|
|
|
(self.email_addresses, email_addresses),
|
|
|
|
|
|
(self.phone_numbers, phone_numbers)
|
|
|
|
|
|
):
|
|
|
|
|
|
for index, value in enumerate(existing_whitelist):
|
|
|
|
|
|
form_field[index].data = value
|
|
|
|
|
|
|
|
|
|
|
|
email_addresses = FieldList(
|
|
|
|
|
|
EmailField(
|
|
|
|
|
|
'',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
Optional(),
|
|
|
|
|
|
Email(message='Enter valid email addresses')
|
|
|
|
|
|
],
|
|
|
|
|
|
default=''
|
|
|
|
|
|
),
|
|
|
|
|
|
min_entries=5,
|
|
|
|
|
|
max_entries=5,
|
|
|
|
|
|
label="Email addresses"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
phone_numbers = FieldList(
|
2017-08-29 14:52:24 +01:00
|
|
|
|
InternationalPhoneNumber(
|
2016-09-20 12:30:00 +01:00
|
|
|
|
'',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
Optional()
|
|
|
|
|
|
],
|
|
|
|
|
|
default=''
|
|
|
|
|
|
),
|
|
|
|
|
|
min_entries=5,
|
|
|
|
|
|
max_entries=5,
|
|
|
|
|
|
label="Mobile numbers"
|
|
|
|
|
|
)
|
2017-01-03 10:45:06 +00:00
|
|
|
|
|
2017-01-03 16:14:25 +00:00
|
|
|
|
|
2017-01-03 10:45:06 +00:00
|
|
|
|
class DateFilterForm(Form):
|
|
|
|
|
|
start_date = DateField("Start Date", [validators.optional()])
|
2017-01-03 16:14:25 +00:00
|
|
|
|
end_date = DateField("End Date", [validators.optional()])
|
|
|
|
|
|
include_from_test_key = BooleanField("Include test keys", default="checked", false_values={"N"})
|
2017-02-28 12:16:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChooseTemplateType(Form):
|
|
|
|
|
|
|
|
|
|
|
|
template_type = RadioField(
|
|
|
|
|
|
'What kind of template do you want to add?',
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired()
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, include_letters=False, *args, **kwargs):
|
|
|
|
|
|
|
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
self.template_type.choices = filter(None, [
|
|
|
|
|
|
('email', 'Email'),
|
|
|
|
|
|
('sms', 'Text message'),
|
|
|
|
|
|
('letter', 'Letter') if include_letters else None
|
|
|
|
|
|
])
|
2017-03-14 10:46:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SearchTemplatesForm(Form):
|
|
|
|
|
|
|
|
|
|
|
|
search = SearchField('Search by name')
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-05-30 13:51:25 +01:00
|
|
|
|
class SearchNotificationsForm(Form):
|
|
|
|
|
|
|
|
|
|
|
|
to = SearchField('Search by phone number or email address')
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-04 09:30:55 +01:00
|
|
|
|
class PlaceholderForm(Form):
|
|
|
|
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-21 17:34:22 +01:00
|
|
|
|
class PasswordFieldShowHasContent(StringField):
|
|
|
|
|
|
widget = widgets.PasswordInput(hide_value=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-24 15:37:44 +01:00
|
|
|
|
class ServiceInboundNumberForm(Form):
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
self.inbound_number.choices = kwargs['inbound_number_choices']
|
|
|
|
|
|
|
|
|
|
|
|
inbound_number = RadioField(
|
|
|
|
|
|
"Select your inbound number",
|
|
|
|
|
|
validators=[
|
|
|
|
|
|
DataRequired("Option must be selected")
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-15 16:20:07 +01:00
|
|
|
|
class ServiceInboundApiForm(Form):
|
2017-11-03 16:02:43 +00:00
|
|
|
|
url = StringField("Callback URL",
|
2017-06-15 16:20:07 +01:00
|
|
|
|
validators=[DataRequired(message='Can’t be empty'),
|
|
|
|
|
|
Regexp(regex="^https.*",
|
2017-11-03 16:02:43 +00:00
|
|
|
|
message='Must be a valid https URL')]
|
2017-06-15 16:20:07 +01:00
|
|
|
|
)
|
2017-06-21 17:34:22 +01:00
|
|
|
|
bearer_token = PasswordFieldShowHasContent("Bearer token",
|
|
|
|
|
|
validators=[DataRequired(message='Can’t be empty'),
|
|
|
|
|
|
Length(min=10, message='Must be at least 10 characters')])
|
2017-06-15 16:20:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-09-26 14:05:02 +01:00
|
|
|
|
class InternationalSMSForm(Form):
|
|
|
|
|
|
enabled = RadioField(
|
|
|
|
|
|
'Send text messages to international phone numbers',
|
|
|
|
|
|
choices=[
|
|
|
|
|
|
('on', 'On'),
|
|
|
|
|
|
('off', 'Off'),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-11-03 15:01:41 +00:00
|
|
|
|
class SMSPrefixForm(Form):
|
|
|
|
|
|
enabled = RadioField(
|
2017-11-06 14:12:25 +00:00
|
|
|
|
'',
|
2017-11-03 15:01:41 +00:00
|
|
|
|
choices=[
|
|
|
|
|
|
('on', 'On'),
|
|
|
|
|
|
('off', 'Off'),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-04 09:30:55 +01:00
|
|
|
|
def get_placeholder_form_instance(
|
|
|
|
|
|
placeholder_name,
|
|
|
|
|
|
dict_to_populate_from,
|
2017-05-25 09:40:37 +01:00
|
|
|
|
optional_placeholder=False,
|
|
|
|
|
|
allow_international_phone_numbers=False,
|
2017-05-04 09:30:55 +01:00
|
|
|
|
):
|
|
|
|
|
|
|
2017-05-25 09:40:37 +01:00
|
|
|
|
if Columns.make_key(placeholder_name) == 'emailaddress':
|
|
|
|
|
|
field = email_address(label=placeholder_name, gov_user=False)
|
|
|
|
|
|
elif Columns.make_key(placeholder_name) == 'phonenumber':
|
|
|
|
|
|
if allow_international_phone_numbers:
|
|
|
|
|
|
field = international_phone_number(label=placeholder_name)
|
|
|
|
|
|
else:
|
2017-08-29 14:52:24 +01:00
|
|
|
|
field = uk_mobile_number(label=placeholder_name)
|
2017-05-25 09:40:37 +01:00
|
|
|
|
elif optional_placeholder:
|
|
|
|
|
|
field = StringField(placeholder_name)
|
|
|
|
|
|
else:
|
|
|
|
|
|
field = StringField(placeholder_name, validators=[
|
2017-05-04 09:30:55 +01:00
|
|
|
|
DataRequired(message='Can’t be empty')
|
2017-05-25 09:40:37 +01:00
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
PlaceholderForm.placeholder_value = field
|
2017-05-04 09:30:55 +01:00
|
|
|
|
|
|
|
|
|
|
return PlaceholderForm(
|
|
|
|
|
|
placeholder_value=dict_to_populate_from.get(placeholder_name, '')
|
|
|
|
|
|
)
|
2017-10-16 16:35:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SetSenderForm(Form):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
self.sender.choices = kwargs['sender_choices']
|
|
|
|
|
|
self.sender.label.text = kwargs['sender_label']
|
|
|
|
|
|
|
|
|
|
|
|
sender = RadioField()
|