changeset 11:6fc4f426b8d4

add untested minimal bitsyauth filter that checks basicauth headers against bitsyblog passwords but doesn't issue any challenges of its own
author ejucovy@socialplanning
date Tue, 05 Jan 2010 12:54:28 -0500
parents 16c33fd5fb20
children 2efb1b30da4a
files bitsyauth/minimal.py
diffstat 1 files changed, 67 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bitsyauth/minimal.py	Tue Jan 05 12:54:28 2010 -0500
@@ -0,0 +1,67 @@
+from webob import Request
+
+import os
+
+def pw(basedir, user):
+    file = os.path.join(basedir, user, '.password')
+
+    try:
+        fp = open(file)
+    except IOError:
+        return None
+
+    pw = fp.read().strip()
+    fp.close()
+    return pw
+
+# from paste.auth.digest
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
+def hash(user, pw, realm):
+    return md5("%s:%s:%s" (user, realm, pw)).hexdigest()
+
+class BitsyblogFilespaceAuth(object):
+    def __init__(self, realm, basedir):
+        self.realm = realm
+        self.basedir = basedir
+    def __call__(self, user, pw):
+        stored = pw(self.basedir, user)
+        if stored is None:
+            return False
+        return hash(user, pw, self.realm) == stored
+
+def filter_factory(app, global_conf, realm, basedir):
+    #from paste.util.import_string import eval_import
+    #authfunc = eval_import(authfunc)
+
+    authfunc = BitsyblogFilespaceAuth(realm, basedir)
+
+    return BasicAuthMiddleware(app, realm, authfunc)
+
+class BasicAuthMiddleware(object):
+    def __init__(self, app, realm, auth_checker):
+        self.app = app
+        self.realm = realm
+        self.auth_checker = auth_checker
+
+    def __call__(self, environ, start_response):
+        req = Request(environ)
+
+        header = req.headers.get('AUTHORIZATION')
+        if not header:
+            return self.app(environ, start_response)
+
+        (method, auth) = header.split(' ', 1)
+        if method != 'basic':
+            return self.app(environ, start_response)
+
+        auth = auth.strip().decode('base64')
+        
+        username, password = auth.split(':', 1)
+
+        if self.auth_checker(username, password):
+            environ['REMOTE_USER'] = username
+        
+        return self.app(environ, start_response)