Projet

Général

Profil

0002-forms-add-a-new-option-to-prepend-a-CAPTCHA-page-for.patch

Frédéric Péters, 18 août 2015 14:05

Télécharger (6,1 ko)

Voir les différences:

Subject: [PATCH 2/2] forms: add a new option to prepend a CAPTCHA page for
 anonymous users (#7859)

 tests/test_form_pages.py | 30 ++++++++++++++++++++++++++++++
 wcs/admin/forms.py       |  7 ++++++-
 wcs/formdef.py           |  4 +++-
 wcs/forms/root.py        | 31 +++++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 2 deletions(-)
tests/test_form_pages.py
941 941
    assert resp.location == 'http://example.net/?foo=bar'
942 942

  
943 943
    os.unlink(os.path.join(pub.app_dir, 'site-options.cfg'))
944

  
945
def test_form_captcha(pub):
946
    user = create_user(pub)
947
    formdef = create_formdef()
948
    formdef.data_class().wipe()
949
    formdef.fields = [fields.StringField(id='0', label='Some field')]
950
    formdef.has_captcha = True
951
    formdef.store()
952

  
953
    # test authentic users are not presented with a captcha
954
    resp = login(get_app(pub), username='foo', password='foo').get('/')
955
    resp = resp.click('test')
956
    assert 'Some field' in resp.body
957

  
958
    # check anonymous user gets the captcha
959
    app = get_app(pub)
960
    resp = app.get('/')
961
    resp = resp.click('test')
962
    assert 'form_captcha' in resp.body
963

  
964
    session_id = app.cookies.values()[0].strip('"')
965
    session = BasicSession.get(session_id)
966
    resp.forms[0]['captcha$q'] = session.get_captcha_token(resp.forms[0]['captcha$token'].value)['answer']
967
    resp = resp.forms[0].submit()
968
    assert 'Some field' in resp.body
969

  
970
    # and check it gets it only once
971
    resp = app.get('/')
972
    resp = resp.click('test')
973
    assert 'Some field' in resp.body
wcs/admin/forms.py
342 342
            r += htmltext('<li>%s</li>') % _('Publication Date: %s') % self.formdef.publication_date
343 343
        if self.formdef.expiration_date:
344 344
            r += htmltext('<li>%s</li>') % _('Expiration Date: %s') % self.formdef.expiration_date
345
        if self.formdef.has_captcha:
346
            r += htmltext('<li>%s</li>') % _('Add CAPTCHA for anonymous users')
345 347
        r += htmltext('</ul>')
346 348
        r += htmltext('</div>')
347 349
        r += htmltext('</div>')
......
614 616
        form.add(DateTimeWidget, 'expiration_date',
615 617
                 title=_('Expiration Date'),
616 618
                 value=self.formdef.expiration_date)
619
        form.add(CheckboxWidget, 'has_captcha',
620
                title=_('Prepend a CAPTCHA page for anonymous users'),
621
                value=self.formdef.has_captcha)
617 622

  
618 623
        form.add_submit('submit', _('Submit'))
619 624
        form.add_submit('cancel', _('Cancel'))
......
624 629
            attrs = ['confirmation', 'only_allow_one', 'disabled',
625 630
                    'enable_tracking_codes', 'private_status_and_history',
626 631
                    'disabled_redirection', 'publication_date',
627
                    'expiration_date', 'always_advertise']
632
                    'expiration_date', 'always_advertise', 'has_captcha']
628 633
            for f in attrs:
629 634
                widget = form.get_widget(f)
630 635
                if widget:
wcs/formdef.py
78 78
    always_advertise = False
79 79
    publication_date = None
80 80
    expiration_date = None
81
    has_captcha = False
81 82

  
82 83
    acl_read = 'owner'  # one of ('none', 'owner', 'roles', 'all')
83 84
    private_status_and_history = False
......
93 94
            'disabled_redirection',]
94 95
    BOOLEAN_ATTRIBUTES = ['discussion', 'detailed_emails', 'disabled',
95 96
            'only_allow_one', 'enable_tracking_codes',
96
            'always_advertise', 'private_status_and_history']
97
            'always_advertise', 'private_status_and_history',
98
            'has_captcha']
97 99

  
98 100
    def migrate(self):
99 101
        changed = False
wcs/forms/root.py
294 294
        r += htmltext('</ol></div>')
295 295
        return r.getvalue()
296 296

  
297
    def initial_captcha_page(self):
298
        form = Form()
299
        form.add_captcha(hint='')
300
        form.add_submit('submit', _('Next'))
301
        form.add_submit('cancel', _('Cancel'))
302

  
303
        if form.get_submit() == 'cancel':
304
            return redirect(get_publisher().get_root_url())
305

  
306
        if not form.is_submitted() or form.has_errors():
307
            self.html_top(self.formdef.name)
308
            r = TemplateIO(html=True)
309
            r += TextsDirectory.get_html_text('captcha-page')
310
            r += form.render()
311
            return r.getvalue()
312

  
313
        return self.page(0)
314

  
297 315
    def page(self, page_no, page_change = True, log_detail = None, editing = None):
298 316
        r = TemplateIO(html=True)
299 317
        displayed_fields = []
300 318

  
301 319
        session = get_session()
302 320

  
321
        if page_no == 0 and self.formdef.has_captcha:
322
            if not session.get_user() and not session.won_captcha:
323
                return self.initial_captcha_page()
324

  
303 325
        if page_no > 0:
304 326
            magictoken = get_request().form['magictoken']
305 327
            self.feed_current_data(magictoken)
......
1370 1392
TextsDirectory.register('welcome-unlogged',
1371 1393
        N_('Welcome text on home page for unlogged users'))
1372 1394

  
1395
TextsDirectory.register('captcha-page',
1396
        N_('Explanation text on the CAPTCHA page'),
1397
        default = N_('''<h3>Verification</h3>
1398

  
1399
<p>
1400
In order to proceed you need to complete this simple question.
1401
</p>'''))
1402

  
1403

  
1373 1404
TextsDirectory.register('form-recorded',
1374 1405
        N_('Message when a form has been recorded'),
1375 1406
        hint = N_('Available variables: date, number'),
1376
-