Mercurial > hg > CAPTCHAmiddleware
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/captchamiddleware/middleware.py Sun Jan 24 23:15:57 2010 -0500 @@ -0,0 +1,73 @@ +""" +CAPTCHA middleware +""" + +import os +import random +import sys +from lxml import etree +from lxmlmiddleware import LXMLMiddleware +from skimpyGimpy import skimpyAPI +from urllib2 import urlopen +from webob import Request, exc + + +class CAPTCHAmiddleware(LXMLMiddleware): + """ + put CAPTCHAs on forms for unauthorized users + """ + + ### class level variables + defaults = { + 'dictionary': '/usr/share/dict/words', + 'error': '<span class="error">Please type the CAPTCHA</span>', + 'minimum_length': 5, + 'path': "/input[@type='submit']", + } + + def __init__(self, app, **kw): + self.app = app + + # set instance parameters from kw and defaults + for key in self.defaults: + setattr(self, key, kw.get(key, self.defaults[key])) + self.minimum_length = int(self.minimum_length) + assert os.path.exists(self.dictionary) + + # get dictionary + if self.dictionary.startswith('http://') or self.dictionary.startswith('https://'): + f = urlopen(self.dictionary) + else: + f = file(self.dictionary) + self.words = [ i.strip() for i in f.readlines() + if len(i.strip()) > self.minimum_length ] + random.shuffle(self.words) + + + def __call__(self, environ, start_response): + request = Request(environ) + if request.method == 'post' and not request.remote_user: + pass # TODO: check CAPTCHA + + return LXMLMiddleware.__call__(self, environ, start_response) + + def manipulate(self, environ, tree): + """manipulate the DOM; should return an etree._Element""" + + request = Request(environ) + + # don't use CAPTCHAs for authorized users + if request.remote_user: + return tree + + for element in tree.findall(".//form[@method='post']"): + key = random.Random().randint(0, len(self.words)) + word = self.words[key] + captcha = skimpyAPI.Pre(word).data() + string = '<div class="captcha">%s<input type="hidden" value="%s"/></div>' % (captcha, key) + addition = etree.fromstring(string) + insertion_point = element.find('.' + self.path) + insertion_point.addprevious(addition) + + return tree +