# HG changeset patch # User k0s # Date 1264392957 18000 # Node ID 21ec6325ae0ebb3b69c95b46e813495b461f89ba initial import of CAPTCHA middleware; unfinished diff -r 000000000000 -r 21ec6325ae0e captchamiddleware/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/captchamiddleware/__init__.py Sun Jan 24 23:15:57 2010 -0500 @@ -0,0 +1,2 @@ +# +from middleware import CAPTCHAmiddleware diff -r 000000000000 -r 21ec6325ae0e captchamiddleware/example.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/captchamiddleware/example.py Sun Jan 24 23:15:57 2010 -0500 @@ -0,0 +1,16 @@ +from webob import Response +from captchamiddleware import CAPTCHAmiddleware +from paste.httpexceptions import HTTPExceptionHandler + +def example_app(environ, start_response): + return Response('
Hello, world!
')(environ, start_response) + + +def factory(global_conf, **app_conf): + """create a webob view and wrap it in middleware""" + keystring = 'captcha.' + args = dict([(key.split(keystr, 1)[-1], value) + for key, value in app_conf.items() + if key.startswith(keystr) ]) + return HTTPExceptionHandler(CAPTCHAmiddleware(example_app, **args)) + diff -r 000000000000 -r 21ec6325ae0e captchamiddleware/middleware.py --- /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': 'Please type the CAPTCHA', + '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 = '
%s
' % (captcha, key) + addition = etree.fromstring(string) + insertion_point = element.find('.' + self.path) + insertion_point.addprevious(addition) + + return tree + diff -r 000000000000 -r 21ec6325ae0e example.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example.ini Sun Jan 24 23:15:57 2010 -0500 @@ -0,0 +1,21 @@ +#!/usr/bin/env paster + +[DEFAULT] +debug = true +email_to = k0scist@gmail.com +smtp_server = localhost +error_email_from = paste@localhost + +[server:main] +use = egg:Paste#http +host = 0.0.0.0 +port = 54954 + +[composite:main] +use = egg:Paste#urlmap +/ = captchamiddleware + +set debug = false + +[app:captchamiddleware] +paste.app_factory = captchamiddleware.example:factory diff -r 000000000000 -r 21ec6325ae0e setup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setup.py Sun Jan 24 23:15:57 2010 -0500 @@ -0,0 +1,30 @@ +from setuptools import setup, find_packages +import sys, os + +version = "0.1" + +setup(name='CAPTCHAmiddleware', + version=version, + description="put CAPTCHAs on forms", + long_description=""" +""", + classifiers=[], # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers + author='Jeff Hammel', + author_email='k0scist@gmail.com', + url='http://k0s.org', + license="GPL", + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + include_package_data=True, + zip_safe=False, + install_requires=[ + # -*- Extra requirements: -*- + 'lxmlmiddleware', + 'skimpygimpy' + ], + entry_points=""" + # -*- Entry points: -*- + [paste.app_factory] + example-captcha = captchamiddleware.example:factory + """, + ) +