Mercurial > hg > CAPTCHAmiddleware
view captchamiddleware/middleware.py @ 2:c861518b2a44
fix bug whereby forbidden characters cause issues
author | k0s <k0scist@gmail.com> |
---|---|
date | Tue, 23 Feb 2010 19:50:23 -0500 |
parents | 478d13061336 |
children | b0ef5452a740 |
line wrap: on
line source
""" 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) # characters skimpygimpy doesnt know about forbidden_characters = set(["'"]) self.words = [ i.strip() for i in f.readlines() if (len(i.strip()) > self.minimum_length) and not forbidden_characters.intersection(i) ] random.shuffle(self.words) def __call__(self, environ, start_response): request = Request(environ) if request.method == 'POST' and not request.remote_user: import pdb; pdb.set_trace() 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"/><input type="text" name="captcha"/></div>' % (captcha, key) addition = etree.fromstring(string) insertion_point = element.find('.' + self.path) insertion_point.addprevious(addition) return tree