Usted está aquí: Inicio CS-Workshop CS-Workshop Blog Topics forms

forms

Using collective.captcha in custom forms

by Mikel Larreategi — última modificación 27/01/2009 11:25
Etiquetas:

collective.captcha provides a simple way to create and verify captcha image and sounds to protect your forms from spambots.

We are using Plone for some community sites with blogs and newsitems with comments and we were attacked by spambots and found ourselves writing spam-deleting scripts until we found collective.captcha.

collective.captcha provides a very simple browser view to generate captcha images (and also sound-captchas) and to verify user input. We are using it in Plone 2.5.x and also in 3.x (like in this blog) and it works great in both of them.

First of all, you need to include in your buildout, both in eggs and zcml sections of your instance and then run the buildout to get it installed.

Then you need to integrate the captcha generated image and the form to get user input, we use a simple page template for that, called captcha_widget with the following content:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
i18n:domain="ataria">

<body>

<span metal:define-macro="captcha">

<div class="field"
tal:define="error errors/captcha|nothing;"
tal:attributes="class python:test(error, 'field error', 'field')">
<label for="captcha" i18n:translate="label_captcha">Captcha</label>

<span class="fieldRequired" title="Required"
i18n:attributes="title"
i18n:domain="plone"
i18n:translate="label_required">(Required)</span>

<div class="formHelp" i18n:translate="help_captcha">
Provide the text in the image. Just to avoid spambots
</div>
<p tal:replace="structure here/@@captcha/image_tag" />

<div>
<input type="text"
name="captcha"
id="captcha"
value="" />
</div>
</div>

</span>

</body>
</html>

The relevant part in this page template is the line in which the captcha image is rendered:

<p tal:replace="structure here/@@captcha/image_tag" />

The first part is completed. Now we just have to check that the user input and the string shown in the captcha are the same. We mainly use collective.captcha together with qPloneComments and we use CMFFormController based forms so we need to create the .cpt with the form in which we include the captcha with the following sentence:

<metal:captcha use-macro="here/captcha_widget/macros/captcha" />

After that you have to write the validator script and tie together with the .metadata file of your form. The script we use is this:

from Products.CMFPlone import PloneMessageFactory as _

captcha = context.REQUEST.get('captcha')

view = context.restrictedTraverse('@@captcha')

if not view.verify(captcha):
state.setError('captcha', _(u'Are you a bot? Try again...'))
state.set(status='failure')

return state

With this, you will have your form protected from spambots.

But collective.captcha has some sort of bug (or at least it has a bug with our configuration) in which zope can't start if you do not override the captcha view in your product. We reported the error in plone-users but had no input about it, so I just reproduce it here.

To get collective.captcha work correctly and zope start, you have to add an overrides.zcml file to your product and add the following ZCML snippet in it:

<browser:page
name="captcha"
for="*"
permission="zope2.Public"
allowed_interface="collective.captcha.browser.interfaces.ICaptchaView"
class="collective.captcha.browser.captcha.Captcha"
/>

So now you know how to protect your hand-made plone forms with collective.captcha.