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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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