annotate bitsyblog/auth_factory.py @ 62:4038c2a052da

add http-basic authenticator middleware filter
author ejucovy@socialplanning
date Tue, 19 Jan 2010 14:50:44 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
62
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
1 from webob import Request
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
2
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
3 import os
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
4
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
5 def getpw(basedir, user):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
6 file = os.path.join(basedir, user, '.password')
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
7
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
8 try:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
9 fp = open(file)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
10 except IOError:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
11 return None
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
12
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
13 pw = fp.read().strip()
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
14 fp.close()
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
15 return pw
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
16
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
17 # from paste.auth.digest
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
18 try:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
19 from hashlib import md5
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
20 except ImportError:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
21 from md5 import md5
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
22 def hash(user, pw, realm):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
23 return md5("%s:%s:%s" % (user, realm, pw)).hexdigest()
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
24
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
25 class BitsyblogFilespaceAuth(object):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
26 def __init__(self, realm, basedir):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
27 self.realm = realm
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
28 self.basedir = basedir
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
29 def __call__(self, user, pw):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
30 stored = getpw(self.basedir, user)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
31 if stored is None:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
32 return False
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
33 return hash(user, pw, self.realm) == stored
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
34
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
35 def filter_factory(global_conf, realm=None, basedir=None):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
36 #from paste.util.import_string import eval_import
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
37 #authfunc = eval_import(authfunc)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
38
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
39 authfunc = BitsyblogFilespaceAuth(realm, basedir)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
40
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
41 def filter(app):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
42 return BasicAuthMiddleware(app, realm, authfunc)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
43 return filter
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
44
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
45 class BasicAuthMiddleware(object):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
46 def __init__(self, app, realm, auth_checker):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
47 self.app = app
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
48 self.realm = realm
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
49 self.auth_checker = auth_checker
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
50
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
51 def __call__(self, environ, start_response):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
52 req = Request(environ)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
53
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
54 header = req.authorization
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
55 if not header:
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
56 return self.app(environ, start_response)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
57
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
58 (method, auth) = header.split(' ', 1)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
59 if method.lower() != 'basic':
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
60 return self.app(environ, start_response)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
61
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
62 auth = auth.strip().decode('base64')
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
63
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
64 username, password = auth.split(':', 1)
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
65
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
66 if self.auth_checker(username, password):
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
67 environ['REMOTE_USER'] = username
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
68
4038c2a052da add http-basic authenticator middleware filter
ejucovy@socialplanning
parents:
diff changeset
69 return self.app(environ, start_response)