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 |
