Projet

Général

Profil

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

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

Télécharger (6,09 ko)

Voir les différences:

Subject: [PATCH 1/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
355 355
            r += htmltext('<li>%s</li>') % _('Publication Date: %s') % self.formdef.publication_date
356 356
        if self.formdef.expiration_date:
357 357
            r += htmltext('<li>%s</li>') % _('Expiration Date: %s') % self.formdef.expiration_date
358
        if self.formdef.has_captcha:
359
            r += htmltext('<li>%s</li>') % _('Add CAPTCHA for anonymous users')
358 360
        r += htmltext('</ul>')
359 361
        r += htmltext('</div>')
360 362
        r += htmltext('</div>')
......
596 598
        form.add(DateTimeWidget, 'expiration_date',
597 599
                 title=_('Expiration Date'),
598 600
                 value=self.formdef.expiration_date)
601
        form.add(CheckboxWidget, 'has_captcha',
602
                title=_('Prepend a CAPTCHA page for anonymous users'),
603
                value=self.formdef.has_captcha)
599 604

  
600 605
        form.add_submit('submit', _('Submit'))
601 606
        form.add_submit('cancel', _('Cancel'))
......
606 611
            attrs = ['confirmation', 'only_allow_one', 'disabled',
607 612
                    'enable_tracking_codes', 'private_status_and_history',
608 613
                    'disabled_redirection', 'publication_date',
609
                    'expiration_date', 'always_advertise']
614
                    'expiration_date', 'always_advertise', 'has_captcha']
610 615
            for f in attrs:
611 616
                widget = form.get_widget(f)
612 617
                if widget:
wcs/formdef.py
77 77
    always_advertise = False
78 78
    publication_date = None
79 79
    expiration_date = None
80
    has_captcha = False
80 81

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

  
97 99
    def migrate(self):
98 100
        changed = False
wcs/forms/root.py
291 291
        r += htmltext('</ol></div>')
292 292
        return r.getvalue()
293 293

  
294
    def initial_captcha_page(self):
295
        form = Form()
296
        form.add_captcha(hint='')
297
        form.add_submit('submit', _('Next'))
298
        form.add_submit('cancel', _('Cancel'))
299

  
300
        if form.get_submit() == 'cancel':
301
            return redirect(get_publisher().get_root_url())
302

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

  
310
        return self.page(0)
311

  
294 312
    def page(self, page_no, page_change = True, log_detail = None, editing = None):
295 313
        r = TemplateIO(html=True)
296 314
        displayed_fields = []
297 315

  
298 316
        session = get_session()
299 317

  
318
        if page_no == 0 and self.formdef.has_captcha:
319
            if not session.get_user() and not session.won_captcha:
320
                return self.initial_captcha_page()
321

  
300 322
        if page_no > 0:
301 323
            magictoken = get_request().form['magictoken']
302 324
            self.feed_current_data(magictoken)
......
1356 1378
TextsDirectory.register('welcome-unlogged',
1357 1379
        N_('Welcome text on home page for unlogged users'))
1358 1380

  
1381
TextsDirectory.register('captcha-page',
1382
        N_('Explanation text on the CAPTCHA page'),
1383
        default = N_('''<h3>Verification</h3>
1384

  
1385
<p>
1386
In order to proceed you need to complete this simple question.
1387
</p>'''))
1388

  
1389

  
1359 1390
TextsDirectory.register('form-recorded',
1360 1391
        N_('Message when a form has been recorded'),
1361 1392
        hint = N_('Available variables: date, number'),
1362
-