[captcha] handle captcha validation properly in the captcha widget stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 26 Mar 2010 13:23:25 +0100
branchstable
changeset 5037 7778a2bbdf9d
parent 5036 3e436a494ce3
child 5038 90493551b1eb
[captcha] handle captcha validation properly in the captcha widget also, avoid error if pil isn't installed (only a recommendation)
i18n/en.po
i18n/es.po
i18n/fr.po
web/captcha.py
web/views/editviews.py
--- a/i18n/en.po	Fri Mar 26 13:21:25 2010 +0100
+++ b/i18n/en.po	Fri Mar 26 13:23:25 2010 +0100
@@ -2514,6 +2514,9 @@
 msgid "incontext"
 msgstr "in-context"
 
+msgid "incorrect captcha value"
+msgstr ""
+
 #, python-format
 msgid "incorrect value (%(value)s) for type \"%(type)s\""
 msgstr ""
@@ -3721,6 +3724,9 @@
 msgid "ui.time-format"
 msgstr "time format"
 
+msgid "unable to check captcha, please try again"
+msgstr ""
+
 msgid "unaccessible"
 msgstr ""
 
--- a/i18n/es.po	Fri Mar 26 13:21:25 2010 +0100
+++ b/i18n/es.po	Fri Mar 26 13:23:25 2010 +0100
@@ -2572,6 +2572,9 @@
 msgid "incontext"
 msgstr "En el contexto"
 
+msgid "incorrect captcha value"
+msgstr ""
+
 #, python-format
 msgid "incorrect value (%(value)s) for type \"%(type)s\""
 msgstr "valor %(value)s incorrecto para el tipo \"%(type)s\""
@@ -3802,6 +3805,9 @@
 msgid "ui.time-format"
 msgstr ""
 
+msgid "unable to check captcha, please try again"
+msgstr ""
+
 msgid "unaccessible"
 msgstr "inaccesible"
 
--- a/i18n/fr.po	Fri Mar 26 13:21:25 2010 +0100
+++ b/i18n/fr.po	Fri Mar 26 13:23:25 2010 +0100
@@ -2604,6 +2604,9 @@
 msgid "incontext"
 msgstr "dans le contexte"
 
+msgid "incorrect captcha value"
+msgstr "valeur de captcha incorrecte"
+
 #, python-format
 msgid "incorrect value (%(value)s) for type \"%(type)s\""
 msgstr "valeur %(value)s incorrecte pour le type \"%(type)s\""
@@ -3838,6 +3841,9 @@
 msgid "ui.time-format"
 msgstr "format de l'heure"
 
+msgid "unable to check captcha, please try again"
+msgstr "impossible de vérifier le captcha, veuillez réessayer"
+
 msgid "unaccessible"
 msgstr "inaccessible"
 
--- a/web/captcha.py	Fri Mar 26 13:21:25 2010 +0100
+++ b/web/captcha.py	Fri Mar 26 13:23:25 2010 +0100
@@ -17,7 +17,7 @@
 from time import time
 
 from cubicweb import tags
-from cubicweb.web import formwidgets as fw
+from cubicweb.web import ProcessFormError, formwidgets as fw
 
 
 def pil_captcha(text, fontfile, fontsize):
@@ -63,7 +63,22 @@
 class CaptchaWidget(fw.TextInput):
     def render(self, form, field, renderer=None):
         # t=int(time()*100) to make sure img is not cached
-        src = form._cw.build_url('view', vid='captcha', t=int(time()*100))
+        src = form._cw.build_url('view', vid='captcha', t=int(time()*100),
+                                 captchakey=field.input_name(form))
         img = tags.img(src=src, alt=u'captcha')
         img = u'<div class="captcha">%s</div>' % img
         return img + super(CaptchaWidget, self).render(form, field, renderer)
+
+    def process_field_data(self, form, field):
+        captcha = form._cw.get_session_data(field.input_name(form), None,
+                                            pop=True)
+        val = super(CaptchaWidget, self).process_field_data(form, field)
+        if val is None:
+            return val # required will be checked by field
+        if captcha is None:
+            msg = form._cw._('unable to check captcha, please try again')
+            raise ProcessFormError(msg)
+        elif val.lower() != captcha.lower():
+            msg = form._cw._('incorrect captcha value')
+            raise ProcessFormError(msg)
+        return val
--- a/web/views/editviews.py	Fri Mar 26 13:21:25 2010 +0100
+++ b/web/views/editviews.py	Fri Mar 26 13:23:25 2010 +0100
@@ -15,7 +15,7 @@
 from cubicweb.view import EntityView, StartupView
 from cubicweb.selectors import (one_line_rset, non_final_entity,
                                 match_search_state)
-from cubicweb.web import httpcache, captcha
+from cubicweb.web import httpcache
 from cubicweb.web.views import baseviews, linksearch_select_url
 
 
@@ -95,17 +95,23 @@
         else:
             super(EditableFinalView, self).cell_call(row, col, props)
 
-
-class CaptchaView(StartupView):
-    __regid__ = 'captcha'
+try:
+    from cubicweb.web import captcha
+except ImportError:
+    # PIL not installed
+    pass
+else:
+    class CaptchaView(StartupView):
+        __regid__ = 'captcha'
 
-    http_cache_manager = httpcache.NoHTTPCacheManager
-    binary = True
-    templatable = False
-    content_type = 'image/jpg'
+        http_cache_manager = httpcache.NoHTTPCacheManager
+        binary = True
+        templatable = False
+        content_type = 'image/jpg'
 
-    def call(self):
-        text, data = captcha.captcha(self._cw.vreg.config['captcha-font-file'],
-                                     self._cw.vreg.config['captcha-font-size'])
-        self._cw.set_session_data('captcha', text)
-        self.w(data.read())
+        def call(self):
+            text, data = captcha.captcha(self._cw.vreg.config['captcha-font-file'],
+                                         self._cw.vreg.config['captcha-font-size'])
+            key = self._cw.form.get('captchakey', 'captcha')
+            self._cw.set_session_data(key, text)
+            self.w(data.read())