Mercurial > hg > bitsyauth
annotate bitsyauth/__init__.py @ 5:2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
author | k0s <k0scist@gmail.com> |
---|---|
date | Sat, 26 Dec 2009 22:56:56 -0500 |
parents | 4db4c02ed1ea |
children | 40fa556252a7 |
rev | line source |
---|---|
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
1 import markup |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
2 import random |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
3 import re |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
4 import sys |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
5 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
6 from cStringIO import StringIO |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
7 from markup.form import Form |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
8 from paste.auth import basic, cookie, digest, form, multi, auth_tkt |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
9 from webob import Request, Response, exc |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
10 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
11 try: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
12 from skimpyGimpy import skimpyAPI |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
13 CAPTCHA = True |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
14 except ImportError: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
15 CAPTCHA = False |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
16 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
17 dictionary_file = '/usr/share/dict/american-english' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
18 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
19 def random_word(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
20 """generate a random word for CAPTCHA auth""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
21 min_length = 5 # minimum word length |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
22 if not globals().has_key('dictionary'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
23 # read the dictionary -- this may be platform dependent |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
24 # XXX could use a backup dictionary |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
25 _dictionary = file(dictionary_file).readlines() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
26 _dictionary = [ i.strip() for i in _dictionary ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
27 _dictionary = [ i.lower() for i in _dictionary |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
28 if i.isalpha() and i > min_length ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
29 globals()['dictionary'] = _dictionary |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
30 return random.Random().choice(dictionary) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
31 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
32 class BitsyAuthInnerWare(object): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
33 """inner auth; does login checking""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
34 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
35 def __init__(self, app, passwords, newuser=None, site=None, realm=None): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
36 """a simple reimplementation of auth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
37 * app: the WSGI app to be wrapped |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
38 * passwords: callable that return a dictionary of {'user': 'password'} |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
39 * newuser: callable to make a new user, taking name + pw |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
40 * site: name of the site |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
41 * realm: realm for HTTP digest authentication |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
42 """ |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
43 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
44 self.app = app |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
45 self.passwords = passwords |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
46 self.site = site or '' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
47 self.realm = realm or self.site |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
48 self.captcha = True |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
49 self.urls = { 'login': '/login', 'join': '/join', } |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
50 self.keys = {} # keys, words for CAPTCHA request |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
51 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
52 self.content_type = { 'image_captcha': 'image/png', |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
53 'wav_captcha': 'audio/wav' } |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
54 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
55 if newuser: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
56 self.newuser = newuser |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
57 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
58 self.urls.pop('join') # don't do joining |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
59 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
60 # WSGI app securely wrapped |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
61 self.wrapped_app = self.security_wrapper() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
62 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
63 if not CAPTCHA: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
64 self.captcha = False |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
65 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
66 ### WSGI/HTTP layer |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
67 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
68 def __call__(self, environ, start_response): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
69 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
70 self.request = Request(environ) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
71 self.request.path_info = self.request.path_info.rstrip('/') |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
72 self.redirect_to = self.request.script_name |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
73 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
74 # URLs intrinsic to BitsyAuth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
75 if self.request.path_info == '/logout': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
76 response = self.redirect() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
77 return response(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
78 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
79 if self.request.path_info in self.url_lookup(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
80 response = self.make_response() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
81 return response(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
82 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
83 # digest auth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
84 if self.request.headers.has_key('Authorization'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
85 return self.wrapped_app(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
86 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
87 response = self.request.get_response(self.app) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
88 # respond to 401s |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
89 if response.status_int == 401: # Unauthorized |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
90 if self.request.environ.get('REMOTE_USER'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
91 return exc.HTTPForbidden() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
92 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
93 response = self.request.get_response(self.wrapped_app) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
94 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
95 user = self.request.environ.get('REMOTE_USER') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
96 if user: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
97 self.request.environ['paste.auth_tkt.set_user'](user) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
98 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
99 return response(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
100 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
101 ### authentication function |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
102 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
103 def digest_authfunc(self, environ, realm, user): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
104 return self.passwords()[user] # passwords stored in m5 digest |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
105 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
106 def authfunc(self, environ, user, password): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
107 return self.hash(user, password) == self.passwords()[user] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
108 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
109 def hash(self, user, password): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
110 # use md5 digest for now |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
111 return digest.digest_password(self.realm, user, password) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
112 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
113 def security_wrapper(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
114 """return the app securely wrapped""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
115 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
116 multi_auth = multi.MultiHandler(self.app) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
117 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
118 # digest authentication |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
119 multi_auth.add_method('digest', digest.middleware, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
120 self.realm, self.digest_authfunc) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
121 multi_auth.set_query_argument('digest', key='auth') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
122 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
123 # form authentication |
4
4db4c02ed1ea
remove strange useless string for action
k0s <k0scist@gmail.com>
parents:
3
diff
changeset
|
124 template = self.login(wrap=True) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
125 multi_auth.add_method('form', form.middleware, self.authfunc, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
126 template=template) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
127 multi_auth.set_default('form') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
128 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
129 return multi_auth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
130 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
131 # might have to wrap cookie.middleware(BitsyAuth(multi(app))) ::shrug:: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
132 return cookie.middleware(multi_auth) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
133 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
134 ### methods dealing with intrinsic URLs |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
135 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
136 def url_lookup(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
137 retval = dict([ (value, key) for key, value |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
138 in self.urls.items() ]) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
139 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
140 retval.update(dict([(('/join/%s.png' % key), 'image_captcha') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
141 for key in self.keys])) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
142 return retval |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
143 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
144 def get_response(self, text, content_type='text/html'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
145 res = Response(content_type=content_type, body=text) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
146 res.content_length = len(res.body) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
147 return res |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
148 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
149 def make_response(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
150 url_lookup = self.url_lookup() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
151 path = self.request.path_info |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
152 assert path in url_lookup |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
153 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
154 # login and join shouldn't be accessible when logged in |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
155 if self.request.environ.get('REMOTE_USER'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
156 return self.redirect("You are already logged in") |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
157 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
158 handler = url_lookup[path] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
159 function = getattr(self, handler) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
160 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
161 if self.request.method == 'GET': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
162 # XXX could/should do this with decorators |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
163 return self.get_response(function(wrap=True), |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
164 content_type=self.content_type.get(handler,'text/html')) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
165 if self.request.method == 'POST': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
166 post_func = getattr(self, handler + "_post") |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
167 errors = post_func() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
168 if errors: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
169 return self.get_response(function(errors=errors, wrap=True)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
170 else: |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
171 location = self.request.POST.get('referer') |
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
172 return self.redirect("Welcome!", location=location) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
173 |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
174 def redirect(self, message='', location=None): |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
175 """redirect from instrinsic urls""" |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
176 return exc.HTTPSeeOther(message, location=location or self.redirect_to) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
177 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
178 def image_captcha(self, wrap=True): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
179 """return data for the image""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
180 key = self.request.path_info.split('/join/')[-1] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
181 key = int(key.split('.png')[0]) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
182 return skimpyAPI.Png(self.keys[key], scale=3.0).data() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
183 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
184 ### forms and their display methods |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
185 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
186 ### login |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
187 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
188 def login_form(self, referer=None, action=None): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
189 if action is None: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
190 action = self.urls['login'] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
191 form = Form(action='', submit='Login') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
192 form.add_element('textfield', 'Name', input_name='username') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
193 form.add_element('password', 'Password', input_name='password') |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
194 if referer: |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
195 form.add_element('hidden', 'referer', value=referer) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
196 return form |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
197 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
198 def login(self, errors=None, wrap=False, action=None): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
199 """login div""" |
5
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
200 referer = None |
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
201 if hasattr(self, 'request'): |
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
202 referer = self.request.referer |
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
203 |
2693b81f5960
fix redirection behaviour (though ultimately the whole class should be refactored not to store request on it)
k0s <k0scist@gmail.com>
parents:
4
diff
changeset
|
204 form = self.login_form(action=action, referer=referer) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
205 join = self.urls.get('join') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
206 retval = form(errors) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
207 if join: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
208 retval += '<br/>\n' + markup.a('join', href="%s" % join) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
209 retval = markup.div(retval) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
210 if wrap: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
211 title = 'login' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
212 if self.site: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
213 pagetitle = '%s - %s' % (title, self.site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
214 retval = markup.wrap(markup.h1(title.title()) + retval, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
215 pagetitle=pagetitle) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
216 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
217 return retval |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
218 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
219 def login_post(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
220 """handle a login POST request""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
221 user = self.request.POST.get('username') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
222 password = self.request.POST.get('password') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
223 passwords = self.passwords() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
224 error = False |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
225 if user not in passwords: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
226 error = True |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
227 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
228 error = not self.authfunc(self.request.environ, user, password) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
229 if error: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
230 return { 'Name': 'Wrong username or password' } |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
231 self.request.environ['REMOTE_USER'] = user |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
232 self.request.environ['paste.auth_tkt.set_user'](user) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
233 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
234 ### join |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
235 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
236 def captcha_pre(self, word, key): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
237 """CAPTCHA with pre-formatted text""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
238 return skimpyAPI.Pre(word, scale=1.2).data() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
239 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
240 def captcha_png(self, word, key): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
241 """CAPTCHA with a PNG image""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
242 return markup.image('/join/%s.png' % key) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
243 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
244 def join_form(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
245 captcha = '' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
246 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
247 # data for CAPTCHA |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
248 key = random.Random().randint(0, sys.maxint) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
249 word = random_word() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
250 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
251 self.keys[key] = word |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
252 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
253 captcha = StringIO() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
254 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
255 captcha_text = "Please type the word below so I know you're not a computer:" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
256 captcha_help = "(please %s if the page is unreadable)" % markup.link('/join?captcha=image', 'go here') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
257 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
258 print >> captcha, markup.p('%s<br/> %s' % (captcha_text, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
259 markup.i(captcha_help))) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
260 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
261 # determine type of CAPTCHA |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
262 captchas = ' '.join(self.request.GET.getall('captcha')) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
263 if not captchas: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
264 captchas = 'pre' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
265 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
266 captcha_funcs=dict(pre=self.captcha_pre, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
267 image=self.captcha_png,) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
268 captchas = [ captcha_funcs[i](word, key) for i in captchas.split() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
269 if i in captcha_funcs ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
270 captchas = '\n'.join([markup.p(i) for i in captchas]) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
271 print >> captcha, captchas |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
272 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
273 print >> captcha, markup.p(markup.input(None, **dict(name='captcha', type='text'))) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
274 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
275 captcha = captcha.getvalue() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
276 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
277 form = Form(action=self.urls['join'], submit='Join', post_html=captcha) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
278 form.add_element('textfield', 'Name') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
279 form.add_password_confirmation() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
280 form.add_element('hidden', 'key', value=str(key)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
281 return form |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
282 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
283 def join(self, errors=None, wrap=False): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
284 """join div or page if wrap""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
285 form = self.join_form() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
286 retval = markup.div(form(errors)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
287 if wrap: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
288 pagetitle = title = 'join' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
289 if self.site: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
290 pagetitle = '%s - %s' % (title, self.site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
291 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
292 errors = errors or {} |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
293 captcha_err = errors.get('CAPTCHA', '') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
294 if captcha_err: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
295 captcha_err = markup.p(markup.em(captcha_err), |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
296 **{'class': 'error'}) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
297 retval = markup.wrap(markup.h1(title.title()) + captcha_err + retval, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
298 pagetitle=pagetitle) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
299 return retval |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
300 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
301 def join_post(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
302 """handle a join POST request""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
303 form = self.join_form() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
304 errors = form.validate(self.request.POST) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
305 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
306 # validate captcha |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
307 if CAPTCHA: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
308 key = self.request.POST.get('key') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
309 try: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
310 key = int(key) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
311 except ValueError: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
312 key = None |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
313 if not key: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
314 errors['CAPTCHA'] = 'Please type the funky looking word' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
315 word = self.keys.pop(key, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
316 if not word: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
317 errors['CAPTCHA'] = 'Please type the funky looking word' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
318 if word != self.request.POST.get('captcha','').lower(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
319 errors['CAPTCHA'] = 'Sorry, you typed the wrong word' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
320 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
321 name = self.request.POST.get('Name', '') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
322 if not name: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
323 if not errors.has_key('Name'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
324 errors['Name'] = [] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
325 errors['Name'].append('Please enter a user name') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
326 if name in self.passwords(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
327 if not errors.has_key('Name'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
328 errors['Name'] = [] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
329 errors['Name'].append('The name %s is already taken' % name) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
330 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
331 if not errors: # create a new user |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
332 self.newuser(name, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
333 self.hash(name, self.request.POST['Password'])) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
334 self.request.environ['REMOTE_USER'] = name # login the new user |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
335 self.request.environ['paste.auth_tkt.set_user'](name) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
336 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
337 return errors |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
338 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
339 class BitsyAuth(object): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
340 """outer middleware for auth; does the cookie handling and wrapping""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
341 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
342 def __init__(self, app, global_conf, passwords, newuser, site='', secret='secret'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
343 self.app = app |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
344 self.path = '/logout' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
345 self.cookie = '__ac' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
346 auth = BitsyAuthInnerWare(app, passwords=passwords, newuser=newuser, site=site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
347 self.hash = auth.hash |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
348 # paste.auth.cookie |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
349 # self.cookie_handler = cookie.middleware(auth, cookie_name=self.cookie, timeout=90) # minutes |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
350 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
351 # paste.auth.auth_tkt |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
352 self.cookie_handler = auth_tkt.make_auth_tkt_middleware(auth, global_conf, secret, cookie_name=self.cookie, logout_path='/logout') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
353 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
354 def __call__(self, environ, start_response): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
355 if environ['PATH_INFO'] == '/logout': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
356 pass |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
357 return self.cookie_handler(environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
358 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
359 def logout(self, environ): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
360 req = Request(environ) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
361 keys = [ 'REMOTE_USER' ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
362 # keys = [ 'REMOTE_USER', 'AUTH_TYPE', 'paste.auth.cookie', 'paste.cookies', 'HTTP_COOKIE' ] # XXX zealous kill |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
363 for key in keys: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
364 req.environ.pop(key, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
365 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
366 body = '<html><head><title>logout</title></head><body>logout</body></html>' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
367 res = Response(content_type='text/html', body=body) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
368 res.content_length = len(res.body) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
369 req.cookies.pop(self.cookie, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
370 res.delete_cookie(self.cookie) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
371 res.unset_cookie(self.cookie) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
372 return res(environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
373 |