Mercurial > hg > CAPTCHAmiddleware
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 |