2
# Twisted, the Framework of Your Internet
3
# Copyright (C) 2001 Matthew W. Lefkowitz
5
# This library is free software; you can redistribute it and/or
6
# modify it under the terms of version 2.1 of the GNU Lesser General Public
7
# License as published by the Free Software Foundation.
9
# This library is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# Lesser General Public License for more details.
14
# You should have received a copy of the GNU Lesser General Public
15
# License along with this library; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
import string, traceback
20
from cStringIO import StringIO
27
from server import NOT_DONE_YET
31
"""Detach a web session from an attached perspective.
33
This will happen when the session expires.
36
def __init__(self, session, identity, perspective):
37
self.session = session
38
self.identity = identity
39
self.perspective = perspective
40
session.notifyOnExpire(self.detach)
43
self.perspective.detached(self.session, self.identity)
49
class AuthForm(widgets.Form):
51
['string','Identity','username',''],
52
['password','Password','password',''],
53
['string','Perspective','perspective','']
56
def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None):
57
"""Initialize, specifying various options.
61
* reqauth: a web.resource.Resource instance, indicating which
62
resource a user will be logging into with this form; this must
63
specify a serviceName attribute which indicates the name of the
64
service from which perspectives will be requested.
66
* [sessionIdentity]: if specified, the name of the attribute on
67
the user's session to set for the identity they get from logging
70
* [sessionPerspective]: if specified, the name of the attribute on
71
the user's session to set for the perspective they get from
72
logging in to this form.
74
self.reqauth = reqauth
75
self.sessionPerspective = sessionPerspective
76
self.sessionIdentity = sessionIdentity
78
def gotPerspective(self, perspective, request, ident):
80
resKey = string.join(['AUTH',self.reqauth.service.serviceName], '_')
81
sess = request.getSession()
82
setattr(sess, resKey, perspective)
83
if self.sessionPerspective:
84
setattr(sess, self.sessionPerspective, perspective)
85
if self.sessionIdentity:
86
setattr(sess, self.sessionIdentity, ident)
87
p = perspective.attached(sess, ident)
88
_Detacher(sess, ident, p)
89
return self.reqauth.reallyRender(request)
91
def didntGetPerspective(self, error, request):
92
print 'Password not verified! Error:', error
94
io.write(self.formatError("Login incorrect."))
95
self.format(self.getFormFields(request), io.write, request)
96
return [io.getvalue()]
98
def gotIdentity(self, ident, password, request, perspectiveName):
99
if ident.verifyPlainPassword(password):
100
ret = ident.requestPerspectiveForKey(self.reqauth.service.serviceName,
101
perspectiveName).addCallbacks(
102
self.gotPerspective, self.didntGetPerspective,
103
callbackArgs=(request,ident),
104
errbackArgs=(request,))
108
return self.didntGetPerspective("no such identity", request)
110
def didntGetIdentity(self, unauth, request):
112
io.write(self.formatError("Login incorrect."))
113
self.format(self.getFormFields(request), io.write, request)
116
def process(self, write, request, submit, username, password, perspective):
117
"""Process the form results.
119
# must be done before page is displayed so cookie can get set!
121
# this site must be tagged with an application.
122
idrq = self.reqauth.service.application.authorizer.getIdentityRequest(username)
124
idrq.addCallbacks(self.gotIdentity, self.didntGetIdentity,
125
callbackArgs=(password,request,perspective or username),
126
errbackArgs=(request,))
129
class AuthPage(widgets.Page):
131
<html><head><title>Authorization Required</title></head>
140
def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None):
141
widgets.Page.__init__(self)
142
self.authForm = AuthForm(reqauth, sessionPerspective, sessionIdentity)
145
class WidgetGuard(widgets.Widget):
147
def __init__(self, wid, service,
148
sessionIdentity=None,
149
sessionPerspective=None):
151
self.service = service
152
self.sessionPerspective = sessionPerspective
153
self.sessionIdentity = sessionIdentity
155
def reallyRender(self, request):
156
return widgets.possiblyDeferWidget(self.wid, request)
158
def display(self, request):
159
session = request.getSession()
160
resKey = string.join(['AUTH',self.service.serviceName], '_')
161
if hasattr(session, resKey):
162
return self.wid.display(request)
164
return AuthForm(self).display(request)
168
class ResourceGuard(resource.Resource):
170
def __init__(self, res, service, sessionIdentity=None, sessionPerspective=None):
172
self.service = service
173
self.sessionPerspective = sessionPerspective
174
self.sessionIdentity = sessionIdentity
176
def reallyRender(self, request):
177
# it's authenticated already...
178
res = self.res.getChildForRequest(request)
179
val = res.render(request)
180
if val != NOT_DONE_YET:
183
return widgets.FORGET_IT
185
def render(self, request):
186
session = request.getSession()
187
resKey = string.join(['AUTH',self.service.serviceName], '_')
188
if hasattr(session, resKey):
189
self.reallyRender(request)
192
return AuthPage(self,
193
self.sessionPerspective,
194
self.sessionIdentity).render(request)