Mercurial > hg > bitsyauth
annotate bitsyauth/__init__.py @ 45:54a53bbe5be9
bitsyauth/__init__.py example/persona.html
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Sun, 29 Dec 2013 20:20:38 -0800 |
parents | 158b469a10e9 |
children | aabc968611bc |
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): |
44 | 36 """ |
37 a simple auth implementation: inner middleware | |
38 | |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
39 * app: the WSGI app to be wrapped |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
40 * passwords: callable that return a dictionary of {'user': 'password'} |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
41 * 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
|
42 * site: name of the site |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
43 * realm: realm for HTTP digest authentication |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
44 """ |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
45 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
46 self.app = app |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
47 self.passwords = passwords |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
48 self.site = site or '' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
49 self.realm = realm or self.site |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
50 self.captcha = True |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
51 self.urls = { 'login': '/login', 'join': '/join', } |
45
54a53bbe5be9
bitsyauth/__init__.py example/persona.html
Jeff Hammel <jhammel@mozilla.com>
parents:
44
diff
changeset
|
52 |
54a53bbe5be9
bitsyauth/__init__.py example/persona.html
Jeff Hammel <jhammel@mozilla.com>
parents:
44
diff
changeset
|
53 # CAPTCHAs |
54a53bbe5be9
bitsyauth/__init__.py example/persona.html
Jeff Hammel <jhammel@mozilla.com>
parents:
44
diff
changeset
|
54 # using skimpygimpy (for now) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
55 self.keys = {} # keys, words for CAPTCHA request |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
56 self.content_type = { 'image_captcha': 'image/png', |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
57 'wav_captcha': 'audio/wav' } |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
58 |
45
54a53bbe5be9
bitsyauth/__init__.py example/persona.html
Jeff Hammel <jhammel@mozilla.com>
parents:
44
diff
changeset
|
59 # new user creation |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
60 if newuser: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
61 self.newuser = newuser |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
62 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
63 self.urls.pop('join') # don't do joining |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
64 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
65 # WSGI app securely wrapped |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
66 self.wrapped_app = self.security_wrapper() |
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 if not CAPTCHA: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
69 self.captcha = False |
21 | 70 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
71 ### WSGI/HTTP layer |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
72 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
73 def __call__(self, environ, start_response): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
74 |
8 | 75 orig_environ = dict(environ) |
76 | |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
77 self.request = Request(environ) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
78 self.request.path_info = self.request.path_info.rstrip('/') |
20
9f4369b769d0
this *may* be more portable?
Jeff Hammel <jhammel@mozilla.com>
parents:
19
diff
changeset
|
79 |
8 | 80 self.redirect_to = '/' + self.request.script_name.lstrip('/') |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
81 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
82 # URLs intrinsic to BitsyAuth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
83 if self.request.path_info == '/logout': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
84 response = self.redirect() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
85 return response(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 if self.request.path_info in self.url_lookup(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
88 response = self.make_response() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
89 return response(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
90 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
91 # digest auth |
20
9f4369b769d0
this *may* be more portable?
Jeff Hammel <jhammel@mozilla.com>
parents:
19
diff
changeset
|
92 if 'Authorization' in self.request.headers.keys(): |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
93 return self.wrapped_app(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
94 |
8 | 95 response = Request(orig_environ).get_response(self.app) |
96 | |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
97 # respond to 401s |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
98 if response.status_int == 401: # Unauthorized |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
99 if self.request.environ.get('REMOTE_USER'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
100 return exc.HTTPForbidden() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
101 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
102 response = self.request.get_response(self.wrapped_app) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
103 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
104 user = self.request.environ.get('REMOTE_USER') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
105 if user: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
106 self.request.environ['paste.auth_tkt.set_user'](user) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
107 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
108 return response(self.request.environ, start_response) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
109 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
110 ### authentication function |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
111 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
112 def digest_authfunc(self, environ, realm, user): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
113 return self.passwords()[user] # passwords stored in m5 digest |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
114 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
115 def authfunc(self, environ, user, password): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
116 return self.hash(user, password) == self.passwords()[user] |
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 def hash(self, user, password): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
119 # use md5 digest for now |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
120 return digest.digest_password(self.realm, user, password) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
121 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
122 def security_wrapper(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
123 """return the app securely wrapped""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
124 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
125 multi_auth = multi.MultiHandler(self.app) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
126 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
127 # digest authentication |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
128 multi_auth.add_method('digest', digest.middleware, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
129 self.realm, self.digest_authfunc) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
130 multi_auth.set_query_argument('digest', key='auth') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
131 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
132 # form authentication |
6 | 133 template = self.login(wrap=True, action='%s') |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
134 multi_auth.add_method('form', form.middleware, self.authfunc, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
135 template=template) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
136 multi_auth.set_default('form') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
137 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
138 return multi_auth |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
139 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
140 # 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
|
141 return cookie.middleware(multi_auth) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
142 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
143 ### methods dealing with intrinsic URLs |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
144 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
145 def url_lookup(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
146 retval = dict([ (value, key) for key, value |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
147 in self.urls.items() ]) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
148 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
149 retval.update(dict([(('/join/%s.png' % key), 'image_captcha') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
150 for key in self.keys])) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
151 return retval |
21 | 152 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
153 def get_response(self, text, content_type='text/html'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
154 res = Response(content_type=content_type, body=text) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
155 res.content_length = len(res.body) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
156 return res |
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 def make_response(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
159 url_lookup = self.url_lookup() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
160 path = self.request.path_info |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
161 assert path in url_lookup |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
162 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
163 # 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
|
164 if self.request.environ.get('REMOTE_USER'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
165 return self.redirect("You are already logged in") |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
166 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
167 handler = url_lookup[path] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
168 function = getattr(self, handler) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
169 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
170 if self.request.method == 'GET': |
21 | 171 # XXX could/should do this with decorators |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
172 return self.get_response(function(wrap=True), |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
173 content_type=self.content_type.get(handler,'text/html')) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
174 if self.request.method == 'POST': |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
175 post_func = getattr(self, handler + "_post") |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
176 errors = post_func() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
177 if errors: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
178 return self.get_response(function(errors=errors, wrap=True)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
179 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
|
180 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
|
181 return self.redirect("Welcome!", location=location) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
182 |
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
|
183 def redirect(self, message='', location=None): |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
184 """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
|
185 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
|
186 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
187 def image_captcha(self, wrap=True): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
188 """return data for the image""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
189 key = self.request.path_info.split('/join/')[-1] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
190 key = int(key.split('.png')[0]) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
191 return skimpyAPI.Png(self.keys[key], scale=3.0).data() |
21 | 192 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
193 ### forms and their display methods |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
194 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
195 ### login |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
196 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
197 def login_form(self, referer=None, action=None): |
6 | 198 form = Form(action=action or '', submit='Login') |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
199 form.add_element('textfield', 'Name', input_name='username') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
200 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
|
201 if referer: |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
202 form.add_element('hidden', 'referer', value=referer) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
203 return form |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
204 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
205 def login(self, errors=None, wrap=False, action=None): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
206 """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
|
207 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
|
208 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
|
209 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
|
210 form = self.login_form(action=action, referer=referer) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
211 join = self.urls.get('join') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
212 retval = form(errors) |
21 | 213 if join: |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
214 retval += '<br/>\n' + markup.a('join', href="%s" % join) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
215 retval = markup.div(retval) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
216 if wrap: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
217 title = 'login' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
218 if self.site: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
219 pagetitle = '%s - %s' % (title, self.site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
220 retval = markup.wrap(markup.h1(title.title()) + retval, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
221 pagetitle=pagetitle) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
222 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
223 return retval |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
224 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
225 def login_post(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
226 """handle a login POST request""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
227 user = self.request.POST.get('username') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
228 password = self.request.POST.get('password') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
229 passwords = self.passwords() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
230 error = False |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
231 if user not in passwords: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
232 error = True |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
233 else: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
234 error = not self.authfunc(self.request.environ, user, password) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
235 if error: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
236 return { 'Name': 'Wrong username or password' } |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
237 self.request.environ['REMOTE_USER'] = user |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
238 self.request.environ['paste.auth_tkt.set_user'](user) |
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 ### join |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
241 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
242 def captcha_pre(self, word, key): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
243 """CAPTCHA with pre-formatted text""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
244 return skimpyAPI.Pre(word, scale=1.2).data() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
245 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
246 def captcha_png(self, word, key): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
247 """CAPTCHA with a PNG image""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
248 return markup.image('/join/%s.png' % key) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
249 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
250 def join_form(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
251 captcha = '' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
252 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
253 # data for CAPTCHA |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
254 key = random.Random().randint(0, sys.maxint) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
255 word = random_word() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
256 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
257 self.keys[key] = word |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
258 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
259 captcha = StringIO() |
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 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
|
262 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
|
263 |
19 | 264 print >> captcha, markup.p('%s<br/> %s' % (captcha_text, |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
265 markup.i(captcha_help))) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
266 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
267 # determine type of CAPTCHA |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
268 captchas = ' '.join(self.request.GET.getall('captcha')) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
269 if not captchas: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
270 captchas = 'pre' |
19 | 271 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
272 captcha_funcs=dict(pre=self.captcha_pre, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
273 image=self.captcha_png,) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
274 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
|
275 if i in captcha_funcs ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
276 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
|
277 print >> captcha, captchas |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
278 print >> captcha, markup.p(markup.input(None, **dict(name='captcha', type='text'))) |
19 | 279 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
280 captcha = captcha.getvalue() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
281 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
282 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
|
283 form.add_element('textfield', 'Name') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
284 form.add_password_confirmation() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
285 form.add_element('hidden', 'key', value=str(key)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
286 return form |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
287 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
288 def join(self, errors=None, wrap=False): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
289 """join div or page if wrap""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
290 form = self.join_form() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
291 retval = markup.div(form(errors)) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
292 if wrap: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
293 pagetitle = title = 'join' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
294 if self.site: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
295 pagetitle = '%s - %s' % (title, self.site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
296 if self.captcha: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
297 errors = errors or {} |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
298 captcha_err = errors.get('CAPTCHA', '') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
299 if captcha_err: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
300 captcha_err = markup.p(markup.em(captcha_err), |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
301 **{'class': 'error'}) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
302 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
|
303 pagetitle=pagetitle) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
304 return retval |
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 def join_post(self): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
307 """handle a join POST request""" |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
308 form = self.join_form() |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
309 errors = form.validate(self.request.POST) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
310 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
311 # validate captcha |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
312 if CAPTCHA: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
313 key = self.request.POST.get('key') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
314 try: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
315 key = int(key) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
316 except ValueError: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
317 key = None |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
318 if not key: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
319 errors['CAPTCHA'] = 'Please type the funky looking word' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
320 word = self.keys.pop(key, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
321 if not word: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
322 errors['CAPTCHA'] = 'Please type the funky looking word' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
323 if word != self.request.POST.get('captcha','').lower(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
324 errors['CAPTCHA'] = 'Sorry, you typed the wrong word' |
19 | 325 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
326 name = self.request.POST.get('Name', '') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
327 if not name: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
328 if not errors.has_key('Name'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
329 errors['Name'] = [] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
330 errors['Name'].append('Please enter a user name') |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
331 if name in self.passwords(): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
332 if not errors.has_key('Name'): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
333 errors['Name'] = [] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
334 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
|
335 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
336 if not errors: # create a new user |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
337 self.newuser(name, |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
338 self.hash(name, self.request.POST['Password'])) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
339 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
|
340 self.request.environ['paste.auth_tkt.set_user'](name) |
18 | 341 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
342 return errors |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
343 |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
344 class BitsyAuth(object): |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
345 """outer middleware for auth; does the cookie handling and wrapping""" |
18 | 346 |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
347 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
|
348 self.app = app |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
349 self.path = '/logout' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
350 self.cookie = '__ac' |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
351 auth = BitsyAuthInnerWare(app, passwords=passwords, newuser=newuser, site=site) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
352 self.hash = auth.hash |
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 # paste.auth.auth_tkt |
9
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
355 self.cookie_handler = auth_tkt.make_auth_tkt_middleware( |
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
356 auth, global_conf, secret, |
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
357 cookie_name=self.cookie, logout_path='/logout') |
0
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 __call__(self, environ, start_response): |
42 | 360 |
9
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
361 try: |
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
362 return self.cookie_handler(environ, start_response) |
15
431bd76aabb7
slightly less stupid exception handling
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
363 except auth_tkt.BadTicket: |
431bd76aabb7
slightly less stupid exception handling
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
364 environ.pop('HTTP_COOKIE') # kill all cookies! bad! XXX |
431bd76aabb7
slightly less stupid exception handling
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
365 return self.cookie_handler(environ, start_response) |
9
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
366 return self.logout(environ, start_response) |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
367 |
9
73b2b5bccd52
* allow logout to pass through instead of failing
egj@socialplanning.org
parents:
8
diff
changeset
|
368 def logout(self, environ, start_response): |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
369 req = Request(environ) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
370 keys = [ 'REMOTE_USER' ] |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
371 # 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
|
372 for key in keys: |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
373 req.environ.pop(key, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
374 |
43 | 375 # return response |
0
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
376 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
|
377 res = Response(content_type='text/html', body=body) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
378 req.cookies.pop(self.cookie, None) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
379 res.delete_cookie(self.cookie) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
380 res.unset_cookie(self.cookie) |
284621b3effd
initial commit of bitsyauth, initially from bitsyblog
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
381 return res(environ, start_response) |
17 | 382 |