forms: add a new option to prepend a CAPTCHA page for anonymous users (#7859)

This commit is contained in:
Frédéric Péters 2015-08-18 11:09:33 +02:00
parent e264d59ff4
commit d779b1aa87
4 changed files with 70 additions and 2 deletions

View File

@ -941,3 +941,33 @@ query_string_allowed_vars = foo,bar
assert resp.location == 'http://example.net/?foo=bar'
os.unlink(os.path.join(pub.app_dir, 'site-options.cfg'))
def test_form_captcha(pub):
user = create_user(pub)
formdef = create_formdef()
formdef.data_class().wipe()
formdef.fields = [fields.StringField(id='0', label='Some field')]
formdef.has_captcha = True
formdef.store()
# test authentic users are not presented with a captcha
resp = login(get_app(pub), username='foo', password='foo').get('/')
resp = resp.click('test')
assert 'Some field' in resp.body
# check anonymous user gets the captcha
app = get_app(pub)
resp = app.get('/')
resp = resp.click('test')
assert 'form_captcha' in resp.body
session_id = app.cookies.values()[0].strip('"')
session = BasicSession.get(session_id)
resp.forms[0]['captcha$q'] = session.get_captcha_token(resp.forms[0]['captcha$token'].value)['answer']
resp = resp.forms[0].submit()
assert 'Some field' in resp.body
# and check it gets it only once
resp = app.get('/')
resp = resp.click('test')
assert 'Some field' in resp.body

View File

@ -355,6 +355,8 @@ class FormDefPage(Directory):
r += htmltext('<li>%s</li>') % _('Publication Date: %s') % self.formdef.publication_date
if self.formdef.expiration_date:
r += htmltext('<li>%s</li>') % _('Expiration Date: %s') % self.formdef.expiration_date
if self.formdef.has_captcha:
r += htmltext('<li>%s</li>') % _('Add CAPTCHA for anonymous users')
r += htmltext('</ul>')
r += htmltext('</div>')
r += htmltext('</div>')
@ -586,6 +588,9 @@ class FormDefPage(Directory):
form.add(DateTimeWidget, 'expiration_date',
title=_('Expiration Date'),
value=self.formdef.expiration_date)
form.add(CheckboxWidget, 'has_captcha',
title=_('Prepend a CAPTCHA page for anonymous users'),
value=self.formdef.has_captcha)
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))
@ -596,7 +601,7 @@ class FormDefPage(Directory):
attrs = ['confirmation', 'only_allow_one', 'disabled',
'enable_tracking_codes', 'private_status_and_history',
'disabled_redirection', 'publication_date',
'expiration_date', 'always_advertise']
'expiration_date', 'always_advertise', 'has_captcha']
for f in attrs:
widget = form.get_widget(f)
if widget:

View File

@ -77,6 +77,7 @@ class FormDef(StorableObject):
always_advertise = False
publication_date = None
expiration_date = None
has_captcha = False
acl_read = 'owner' # one of ('none', 'owner', 'roles', 'all')
private_status_and_history = False
@ -92,7 +93,8 @@ class FormDef(StorableObject):
'disabled_redirection',]
BOOLEAN_ATTRIBUTES = ['discussion', 'detailed_emails', 'disabled',
'only_allow_one', 'enable_tracking_codes',
'always_advertise', 'private_status_and_history']
'always_advertise', 'private_status_and_history',
'has_captcha']
def migrate(self):
changed = False

View File

@ -291,12 +291,34 @@ class FormPage(Directory):
r += htmltext('</ol></div>')
return r.getvalue()
def initial_captcha_page(self):
form = Form()
form.add_captcha(hint='')
form.add_submit('submit', _('Next'))
form.add_submit('cancel', _('Cancel'))
if form.get_submit() == 'cancel':
return redirect(get_publisher().get_root_url())
if not form.is_submitted() or form.has_errors():
html_top(self.formdef.name)
r = TemplateIO(html=True)
r += TextsDirectory.get_html_text('captcha-page')
r += form.render()
return r.getvalue()
return self.page(0)
def page(self, page_no, page_change = True, log_detail = None, editing = None):
r = TemplateIO(html=True)
displayed_fields = []
session = get_session()
if page_no == 0 and self.formdef.has_captcha:
if not session.get_user() and not session.won_captcha:
return self.initial_captcha_page()
if page_no > 0:
magictoken = get_request().form['magictoken']
self.feed_current_data(magictoken)
@ -1356,6 +1378,15 @@ TextsDirectory.register('welcome-logged',
TextsDirectory.register('welcome-unlogged',
N_('Welcome text on home page for unlogged users'))
TextsDirectory.register('captcha-page',
N_('Explanation text on the CAPTCHA page'),
default = N_('''<h3>Verification</h3>
<p>
In order to proceed you need to complete this simple question.
</p>'''))
TextsDirectory.register('form-recorded',
N_('Message when a form has been recorded'),
hint = N_('Available variables: date, number'),