comparison captchamiddleware/middleware.py @ 0:21ec6325ae0e

initial import of CAPTCHA middleware; unfinished
author k0s <k0scist@gmail.com>
date Sun, 24 Jan 2010 23:15:57 -0500
parents
children 478d13061336
comparison
equal deleted inserted replaced
-1:000000000000 0:21ec6325ae0e
1 """
2 CAPTCHA middleware
3 """
4
5 import os
6 import random
7 import sys
8 from lxml import etree
9 from lxmlmiddleware import LXMLMiddleware
10 from skimpyGimpy import skimpyAPI
11 from urllib2 import urlopen
12 from webob import Request, exc
13
14
15 class CAPTCHAmiddleware(LXMLMiddleware):
16 """
17 put CAPTCHAs on forms for unauthorized users
18 """
19
20 ### class level variables
21 defaults = {
22 'dictionary': '/usr/share/dict/words',
23 'error': '<span class="error">Please type the CAPTCHA</span>',
24 'minimum_length': 5,
25 'path': "/input[@type='submit']",
26 }
27
28 def __init__(self, app, **kw):
29 self.app = app
30
31 # set instance parameters from kw and defaults
32 for key in self.defaults:
33 setattr(self, key, kw.get(key, self.defaults[key]))
34 self.minimum_length = int(self.minimum_length)
35 assert os.path.exists(self.dictionary)
36
37 # get dictionary
38 if self.dictionary.startswith('http://') or self.dictionary.startswith('https://'):
39 f = urlopen(self.dictionary)
40 else:
41 f = file(self.dictionary)
42 self.words = [ i.strip() for i in f.readlines()
43 if len(i.strip()) > self.minimum_length ]
44 random.shuffle(self.words)
45
46
47 def __call__(self, environ, start_response):
48 request = Request(environ)
49 if request.method == 'post' and not request.remote_user:
50 pass # TODO: check CAPTCHA
51
52 return LXMLMiddleware.__call__(self, environ, start_response)
53
54 def manipulate(self, environ, tree):
55 """manipulate the DOM; should return an etree._Element"""
56
57 request = Request(environ)
58
59 # don't use CAPTCHAs for authorized users
60 if request.remote_user:
61 return tree
62
63 for element in tree.findall(".//form[@method='post']"):
64 key = random.Random().randint(0, len(self.words))
65 word = self.words[key]
66 captcha = skimpyAPI.Pre(word).data()
67 string = '<div class="captcha">%s<input type="hidden" value="%s"/></div>' % (captcha, key)
68 addition = etree.fromstring(string)
69 insertion_point = element.find('.' + self.path)
70 insertion_point.addprevious(addition)
71
72 return tree
73