1 | from DateTime import DateTime |
---|
2 | |
---|
3 | from zope.interface import Interface |
---|
4 | from zope.component import adapts |
---|
5 | from zope.i18n import MessageFactory |
---|
6 | |
---|
7 | try: |
---|
8 | from plone.app.z3cform import inline_validation |
---|
9 | except ImportError: |
---|
10 | # BBB Plone < 4.3 compatibility |
---|
11 | from plone.app.form.kss import validation as inline_validation |
---|
12 | |
---|
13 | from Products.CMFCore.utils import getToolByName |
---|
14 | |
---|
15 | from quintagroup.captcha.core.utils import (decrypt, parseKey, encrypt1, |
---|
16 | getWord, detectInlineValidation) |
---|
17 | |
---|
18 | from z3c.form.validator import SimpleFieldValidator |
---|
19 | |
---|
20 | from quintagroup.z3cform.captcha.interfaces import ICaptcha |
---|
21 | |
---|
22 | _ = MessageFactory('quintagroup.z3cform.captcha') |
---|
23 | |
---|
24 | |
---|
25 | class CaptchaValidator(SimpleFieldValidator): |
---|
26 | """Captcha validator""" |
---|
27 | |
---|
28 | adapts(Interface, Interface, Interface, ICaptcha, Interface) |
---|
29 | |
---|
30 | def validate(self, value): |
---|
31 | # Verify the user input against the captcha |
---|
32 | |
---|
33 | # Captcha validation is one-time process to prevent hacking |
---|
34 | # This is the reason for in-line validation to be disabled. |
---|
35 | if detectInlineValidation(inline_validation): |
---|
36 | return |
---|
37 | |
---|
38 | context = self.context |
---|
39 | request = self.request |
---|
40 | value = value or '' |
---|
41 | captcha_type = context.getCaptchaType() |
---|
42 | if captcha_type in ['static', 'dynamic']: |
---|
43 | hashkey = request.get('%shashkey' % self.widget.form.prefix, '') |
---|
44 | decrypted_key = decrypt(context.captcha_key, hashkey) |
---|
45 | parsed_key = parseKey(decrypted_key) |
---|
46 | |
---|
47 | index = parsed_key['key'] |
---|
48 | date = parsed_key['date'] |
---|
49 | |
---|
50 | if captcha_type == 'static': |
---|
51 | img = getattr(context, '%s.jpg' % index) |
---|
52 | solution = img.title |
---|
53 | enc = encrypt1(value) |
---|
54 | else: |
---|
55 | enc = value |
---|
56 | solution = getWord(int(index)) |
---|
57 | |
---|
58 | captcha_tool = getToolByName(context, 'portal_captchas') |
---|
59 | captcha_tool_has_key = captcha_tool.has_key |
---|
60 | if (enc != solution) or (captcha_tool_has_key(decrypted_key)) or \ |
---|
61 | (DateTime().timeTime() - float(date) > 3600): |
---|
62 | raise ValueError(_(u'Please re-enter validation code.')) |
---|
63 | else: |
---|
64 | captcha_tool.addExpiredKey(decrypted_key) |
---|