def test_form_validation(app):
app.config['WTF_CSRF_ENABLED'] = False
class TestForm(SanicForm):
msg = StringField('Note', validators=[DataRequired(), Length(max=10)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
async def index(request):
form = TestForm(request)
if request.method == 'POST' and form.validate():
return response.text('validated')
content = render_form(form)
return response.html(content)
req, resp = app.test_client.get('/')
assert resp.status == 200
# we disabled it
assert 'csrf_token' not in resp.text
# this is longer than 10
payload = {'msg': 'love is beautiful'}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
assert 'validated' not in resp.text
payload = {'msg': 'happy'}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
assert 'validated' in resp.text
python类StringField()的实例源码
def test_form_csrf_validation(app):
app.config['WTF_CSRF_SECRET_KEY'] = 'top secret !!!'
class TestForm(SanicForm):
msg = StringField('Note', validators=[DataRequired(), Length(max=10)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
async def index(request):
form = TestForm(request)
if request.method == 'POST' and form.validate():
return response.text('validated')
content = render_form(form)
return response.html(content)
req, resp = app.test_client.get('/')
assert resp.status == 200
assert 'csrf_token' in resp.text
token = re.findall(csrf_token_pattern, resp.text)[0]
assert token
payload = {'msg': 'happy', 'csrf_token': token}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
assert 'validated' in resp.text
payload = {'msg': 'happy'}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
# should fail, no CSRF token in payload
assert 'validated' not in resp.text
def test_csrf_token(app):
app.config['WTF_CSRF_SECRET_KEY'] = 'top secret !!!'
app.config['WTF_CSRF_FIELD_NAME'] = 'csrf_token'
class TestForm(SanicForm):
msg = StringField('Note', validators=[DataRequired(), Length(max=10)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
async def index(request):
form = TestForm(request)
return response.text(form.csrf_token)
req, resp = app.test_client.get('/')
assert resp.status == 200
assert 'csrf_token' in resp.text
token = re.findall(csrf_token_pattern, resp.text)[0]
assert token
def test_no_request_disable_csrf(app):
app.config['WTF_CSRF_ENABLED'] = True
app.config['WTF_CSRF_SECRET_KEY'] = 'look ma'
class TestForm(SanicForm):
msg = StringField('Note', validators=[DataRequired(), Length(max=10)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
async def index(request):
form = TestForm(formdata=request.form)
if request.method == 'POST' and form.validate():
return response.text('validated')
content = render_form(form)
return response.html(content)
payload = {'msg': 'happy'}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
# should be okay, no request means CSRF was disabled
assert 'validated' in resp.text
def test_validate_on_submit(app):
app.config['WTF_CSRF_SECRET_KEY'] = 'top secret !!!'
class TestForm(SanicForm):
msg = StringField('Note', validators=[DataRequired(), Length(max=10)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
async def index(request):
form = TestForm(request)
if form.validate_on_submit():
return response.text('validated')
content = render_form(form)
return response.html(content)
req, resp = app.test_client.get('/')
assert resp.status == 200
assert 'csrf_token' in resp.text
token = re.findall(csrf_token_pattern, resp.text)[0]
assert token
payload = {'msg': 'happy', 'csrf_token': token}
req, resp = app.test_client.post('/', data=payload)
assert resp.status == 200
assert 'validated' in resp.text
def test_orcid_validation(test_form): # noqa
orcid_id = StringField("ORCID iD", [
validate_orcid_id_field,
])
orcid_id.data = "0000-0001-8228-7153"
validate_orcid_id_field(test_form, orcid_id)
orcid_id.data = "INVALID FORMAT"
with pytest.raises(ValueError) as excinfo:
validate_orcid_id_field(test_form, orcid_id)
assert "Invalid ORCID iD. It should be in the form of 'xxxx-xxxx-xxxx-xxxx' where x is a digit." in str(
excinfo.value)
orcid_id.data = "0000-0001-8228-7154"
with pytest.raises(ValueError) as excinfo:
validate_orcid_id_field(test_form, orcid_id)
assert "Invalid ORCID iD checksum. Make sure you have entered correct ORCID iD." in str(
excinfo.value)
def get_node_form(node_type):
"""Get a procedurally generated WTForm, based on the dyn_schema and
node_schema of a specific node_type.
:type node_type: dict
:param node_type: Describes the node type via dyn_schema, form_schema and
parent
"""
class ProceduralForm(Form):
pass
parent_prop = node_type['parent']
ProceduralForm.name = StringField('Name', validators=[DataRequired()])
# Parenting
if parent_prop:
parent_names = ", ".join(parent_prop)
ProceduralForm.parent = HiddenField('Parent ({0})'.format(parent_names))
ProceduralForm.description = TextAreaField('Description')
ProceduralForm.picture = FileSelectField('Picture', file_format='image')
ProceduralForm.node_type = HiddenField(default=node_type['name'])
add_form_properties(ProceduralForm, node_type)
return ProceduralForm()
def build_file_select_form(schema):
class FileSelectForm(Form):
pass
for field_name, field_schema in schema.items():
if field_schema['type'] == 'boolean':
field = BooleanField()
elif field_schema['type'] == 'string':
if 'allowed' in field_schema:
choices = [(c, c) for c in field_schema['allowed']]
field = SelectField(choices=choices)
else:
field = StringField()
elif field_schema['type'] == 'objectid':
field = FileSelectField('file')
else:
raise ValueError('field type %s not supported' % field_schema['type'])
setattr(FileSelectForm, field_name, field)
return FileSelectForm
def unique_username(form, field):
"""
Check if a user already exists with this name
:param form: The form which is being passed in
:type form: Form
:param field: The data value for the 'name' inserted by new User
:type field : StringField
"""
user = User.query.filter(User.name == field.data).first()
if user is not None:
raise ValidationError('There is already a user with this name')
def setUp(self):
app.config['TESTING'] = True
app.config['WTF_CSRF_ENABLED'] = False
class UserForm(BaseForm):
user_id = IntegerField()
timeout = StringField()
TemplateDestinationForm.user = FormField(UserForm)
def setUp(self):
self.view = BaseView()
ErrorExtractor.generic_patterns = GENERIC_PATTERN_ERRORS
ErrorExtractor.specific_patterns = SPECIFIC_PATTERN_ERRORS
ErrorExtractor.url_to_name_resources = URL_TO_NAME_RESOURCES
ErrorTranslator.generic_messages = GENERIC_MESSAGE_ERRORS
ErrorTranslator.specific_messages = SPECIFIC_MESSAGE_ERRORS
app.config['TESTING'] = True
app.config['WTF_CSRF_ENABLED'] = False
class MyForm(BaseForm):
attribute1 = StringField()
with app.test_request_context(method='POST', data={'attribute1': ''}):
self.form = MyForm()
def get_string_field(answer, label, guidance, error_messages):
validate_with = get_mandatory_validator(answer, error_messages, 'MANDATORY_TEXTFIELD')
return StringField(
label=label,
description=guidance,
validators=validate_with,
)
def get_date_form(answer=None, error_messages=None):
"""
Returns a date form metaclass with appropriate validators. Used in both date and
date range form creation.
:param error_messages: The messages during validation
:param answer: The answer on which to base this form
:return: The generated DateForm metaclass
"""
class DateForm(Form):
day = StringField()
year = StringField()
validate_with = [OptionalForm()]
if not error_messages:
date_messages = {}
else:
date_messages = error_messages.copy()
if answer['mandatory'] is True:
if 'validation' in answer and 'messages' in answer['validation'] \
and 'MANDATORY_DATE' in answer['validation']['messages']:
date_messages['MANDATORY_DATE'] = answer['validation']['messages']['MANDATORY_DATE']
validate_with = [DateRequired(message=date_messages['MANDATORY_DATE'])]
if 'validation' in answer and 'messages' in answer['validation'] \
and 'INVALID_DATE' in answer['validation']['messages']:
date_messages['INVALID_DATE'] = answer['validation']['messages']['INVALID_DATE']
validate_with += [DateCheck(date_messages['INVALID_DATE'])]
# Set up all the calendar month choices for select
month_choices = [('', 'Select month')] + [(str(x), calendar.month_name[x]) for x in range(1, 13)]
DateForm.month = SelectField(choices=month_choices, default='', validators=validate_with)
return DateForm
def get_month_year_form(answer, error_messages):
"""
Returns a month year form metaclass with appropriate validators. Used in both date and
date range form creation.
:param answer: The answer on which to base this form
:param error_messages: The messages to use upon this form during validation
:return: The generated MonthYearDateForm metaclass
"""
class MonthYearDateForm(Form):
year = StringField()
validate_with = [OptionalForm()]
if answer['mandatory'] is True:
error_message = error_messages['MANDATORY_DATE']
if 'validation' in answer and 'messages' in answer['validation'] \
and 'MANDATORY_DATE' in answer['validation']['messages']:
error_message = answer['validation']['messages']['MANDATORY_DATE']
validate_with = [DateRequired(message=error_message)]
if 'validation' in answer and 'messages' in answer['validation'] \
and 'INVALID_DATE' in answer['validation']['messages']:
error_message = answer['validation']['messages']['INVALID_DATE']
validate_with += [MonthYearCheck(error_message)]
else:
validate_with += [MonthYearCheck()]
# Set up all the calendar month choices for select
month_choices = [('', 'Select month')] + [(str(x), calendar.month_name[x]) for x in range(1, 13)]
MonthYearDateForm.month = SelectField(choices=month_choices, default='', validators=validate_with)
return MonthYearDateForm
def test_string_field(self):
textfield_json = {
"id": "job-title-answer",
"label": "Job title",
"mandatory": False,
"guidance": "<p>Please enter your job title in the space provided.</p>",
"type": "TextField"
}
unbound_field = get_field(textfield_json, textfield_json['label'], error_messages, self.answer_store)
self.assertTrue(unbound_field.field_class == StringField)
self.assertEquals(unbound_field.kwargs['label'], textfield_json['label'])
self.assertEquals(unbound_field.kwargs['description'], textfield_json['guidance'])
def factory(cls, data, **kwargs):
for d in data:
if d.key == 'default_search_quality':
setattr(cls, d.key, SelectMultipleField(d.name, choices=app.config.get('AVAILABLE_QUALITIES'), default=d.value, validators=[Optional()]))
elif d.type == 'list':
setattr(cls, d.key, SelectMultipleField(d.name, default=d.value))
elif d.type == 'string':
setattr(cls, d.key, StringField(d.name, default=d.value))
elif d.type == 'bool':
setattr(cls, d.key, BooleanField(d.name, default=d.value))
elif d.type == 'float':
setattr(cls, d.key, FloatField(d.name, default=d.value))
elif d.type == 'int':
setattr(cls, d.key, IntegerField(d.name, default=d.value))
return cls(**kwargs)
def make_form(model,
request,
default_str,
valid_type):
if not request.args:
valid_set = [] # no need to do expensive validation if no request
message = 'Please enter {}(s)'.format(valid_type)
print('Making form with empty validator')
elif valid_type == 'term':
valid_set = model.terms.set_
message = 'Found non-term.'
elif valid_type == 'probe':
valid_set = model.probe_store.probe_set
message = 'Found non-probe.'
elif valid_type == 'cat':
valid_set = model.probe_store.cat_set
message = 'Found non-category'
elif valid_type == 'int': # for specifying hidden unit ids
valid_set = [str(i) for i in range(GlobalConfigs.EMBED_SIZE)]
message = 'Found non-integer'
else:
raise AttributeError('rnnlab: Invalid arg to "valid_type".')
def term_cat_validator(form, field):
if default_str in field.data:
raise ValidationError(message)
if not field.data:
raise ValidationError('Input required')
elif any(map(lambda x: x not in valid_set, field.data.split())):
raise ValidationError(message)
else:
print('Form validated: "{}"'.format(field.data))
class TermsForm(Form):
field = StringField(validators=[term_cat_validator])
terms_form = TermsForm(request.args, field=default_str)
return terms_form
def validate(self):
check_validate = super().validate()
if not check_validate:
return False
sizes_list = self.sizes.data.replace(',', ' ').split()
if len(sizes_list) == 0:
self.sizes.errors.append('Must have at least one ')
return False
for elem in sizes_list:
try:
int(elem)
except ValueError:
self.sizes.errors.append('Could not parse "%s" as int' % elem)
return False
return True
# class UploadImages(Form):
#
#
# upload = SubmitField('Upload')
# from mothership.models import User
#
#
# class LoginForm(Form):
# username = StringField(u'Username', validators=[validators.required()])
# password = PasswordField(u'Password', validators=[validators.optional()])
#
# def validate(self):
# check_validate = super(LoginForm, self).validate()
#
# # if our validators do not pass
# if not check_validate:
# return False
#
# # Does our the exist
# user = User.query.filter_by(username=self.username.data).first()
# if not user:
# self.username.errors.append('Invalid username or password')
# return False
#
# # Do the passwords match
# if not user.check_password(self.password.data):
# self.username.errors.append('Invalid username or password')
# return False
#
# return True
def add_form_properties(form_class, node_type):
"""Add fields to a form based on the node and form schema provided.
:type node_schema: dict
:param node_schema: the validation schema used by Cerberus
:type form_class: class
:param form_class: The form class to which we append fields
:type form_schema: dict
:param form_schema: description of how to build the form (which fields to
show and hide)
"""
for prop_name, schema_prop, form_prop in iter_node_properties(node_type):
# Recursive call if detects a dict
field_type = schema_prop['type']
if field_type == 'dict':
assert prop_name == 'attachments'
field = attachments.attachment_form_group_create(schema_prop)
elif field_type == 'list':
if prop_name == 'files':
schema = schema_prop['schema']['schema']
file_select_form = build_file_select_form(schema)
field = FieldList(CustomFormField(file_select_form),
min_entries=1)
elif 'allowed' in schema_prop['schema']:
choices = [(c, c) for c in schema_prop['schema']['allowed']]
field = SelectMultipleField(choices=choices)
else:
field = SelectMultipleField(choices=[])
elif 'allowed' in schema_prop:
select = []
for option in schema_prop['allowed']:
select.append((str(option), str(option)))
field = SelectField(choices=select)
elif field_type == 'datetime':
if form_prop.get('dateonly'):
field = DateField(prop_name, default=date.today())
else:
field = DateTimeField(prop_name, default=datetime.now())
elif field_type == 'integer':
field = IntegerField(prop_name, default=0)
elif field_type == 'float':
field = FloatField(prop_name, default=0.0)
elif field_type == 'boolean':
field = BooleanField(prop_name)
elif field_type == 'objectid' and 'data_relation' in schema_prop:
if schema_prop['data_relation']['resource'] == 'files':
field = FileSelectField(prop_name)
else:
field = StringField(prop_name)
elif schema_prop.get('maxlength', 0) > 64:
field = TextAreaField(prop_name)
else:
field = StringField(prop_name)
setattr(form_class, prop_name, field)