Commits

Ralph Bean committed 0afdcef

Validation.

Comments (0)

Files changed (3)

tw2/captcha/templates/captcha.mak

 		<img src="${w.audio_icon}" alt="Audio file" />
 	</a>
 % endif
-	<input type="text" ${tw.attrs(attrs=w.attrs)}/>
+	<input type="hidden"
+		id="${w.attrs['id']}:payload"
+		name="${w.attrs['id']}:payload"
+		value="${w.payload}"/>
+	<input type="text"
+		id="${w.attrs['id']}:value"
+		name="${w.attrs['id']}:value"/>
 </span>

tw2/captcha/validators.py

+import urllib2
+
+import kitchen.text.converters as convert
+import tw2.core as twc
+
+from datetime import datetime
+
+# TODO -- tw2 internationalization coming soon
+#from tw2.core import li8n as _
+_ = lambda s: s
+
+class CaptchaValidator(twc.Validator):
+    msgs = {
+        'incorrect': _("Incorrect value."),
+        'timeout': _("Too much time elapsed. Please try again."),
+    }
+    timeout = 5  # minutes
+
+    def validate_python(self, value, state):
+        import tw2.captcha
+
+        payload = urllib2.unquote(value['payload']).encode('utf-8')
+        try:
+            model = self.captcha_widget.model_from_payload(payload)
+        except:
+            raise twc.ValidationError('incorrect', self)
+
+        if model.plaintext != value['value']:
+            raise twc.ValidationError('incorrect', self)
+
+        elapsed = datetime.utcnow() - model.created
+        if elapsed.seconds > self.timeout * 60:
+            raise twc.ValidationError('timeout', self)

tw2/captcha/widgets.py

 from sha import new as sha_constructor
 from pkg_resources import iter_entry_points
 
+from tw2.captcha.validators import CaptchaValidator
+
 modname = '.'.join(__name__.split('.')[:-1])
 
 captcha_css = twc.CSSLink(modname=modname, filename="static/ext/captcha.css")
 captcha_img = twc.DirLink(modname=modname, filename="static/images/")
 
-class Captcha(twf.InputField):
+class Captcha(twf.TextField):
     template = "mako:tw2.captcha.templates.captcha"
     resources = [captcha_css, captcha_img]
 
         random.seed()
         cls.aes = AES.new(cls._key, AES.MODE_ECB)
 
+        # Set up our validator with a reference back to us.
+        cls.validator = CaptchaValidator(captcha_widget=cls)
+
     @classmethod
     def load_jpeg_generator(cls):
         name = cls.jpeg_generator
             output, error = proc.communicate()
         except Exception, err:
             print "ERROR: %s" % err
+
         f = open(filename)
         f.seek(0)
         content = f.read()
 
     def prepare(self):
         """ Called just before the widget is displayed. """
-
         if self.text_generator == None:
             raise ValueError("Captcha must have a text_generator")
         int(self.start_range)
         mw = twc.core.request_local()['middleware']
         mw.controllers.register(type(self), self.controller_prefix)
 
+        super(Captcha, self).prepare()
+
     def create_payload(self):
         "Create a payload that uniquely identifies the captcha."
         c = model.Captcha()