OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 | |
5 """DEPRECATED. | |
6 | |
7 You probably should be using twisted.web.woven.guard instead. | |
8 """ | |
9 | |
10 # System Imports | |
11 import string, traceback | |
12 from cStringIO import StringIO | |
13 | |
14 from twisted.python import log | |
15 | |
16 # Sibling Imports | |
17 import error | |
18 import html | |
19 import resource | |
20 import widgets | |
21 from server import NOT_DONE_YET | |
22 | |
23 import warnings | |
24 warnings.warn("Please use twisted.web.woven.guard", DeprecationWarning, 2) | |
25 | |
26 | |
27 class _Detacher: | |
28 """Detach a web session from an attached perspective. | |
29 | |
30 This will happen when the session expires. | |
31 """ | |
32 | |
33 def __init__(self, session, identity, perspective): | |
34 self.session = session | |
35 self.identity = identity | |
36 self.perspective = perspective | |
37 session.notifyOnExpire(self.detach) | |
38 | |
39 def detach(self): | |
40 self.perspective.detached(self.session, self.identity) | |
41 del self.session | |
42 del self.identity | |
43 del self.perspective | |
44 | |
45 | |
46 class AuthForm(widgets.Form): | |
47 formFields = [ | |
48 ['string','Identity','username',''], | |
49 ['password','Password','password',''], | |
50 ['string','Perspective','perspective',''] | |
51 ] | |
52 | |
53 formAcceptExtraArgs = 1 | |
54 | |
55 def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None): | |
56 """Initialize, specifying various options. | |
57 | |
58 @param reqauth: a web.resource.Resource instance, indicating which | |
59 resource a user will be logging into with this form; this must | |
60 specify a serviceName attribute which indicates the name of the | |
61 service from which perspectives will be requested. | |
62 | |
63 @param sessionIdentity: if specified, the name of the attribute on | |
64 the user's session to set for the identity they get from logging | |
65 in to this form. | |
66 | |
67 @param sessionPerspective: if specified, the name of the attribute on | |
68 the user's session to set for the perspective they get from | |
69 logging in to this form. | |
70 """ | |
71 self.reqauth = reqauth | |
72 self.sessionPerspective = sessionPerspective | |
73 self.sessionIdentity = sessionIdentity | |
74 | |
75 def gotPerspective(self, perspective, request, ident): | |
76 # TODO: fix this... | |
77 resKey = string.join(['AUTH',self.reqauth.service.serviceName], '_') | |
78 sess = request.getSession() | |
79 setattr(sess, resKey, perspective) | |
80 if self.sessionPerspective: | |
81 setattr(sess, self.sessionPerspective, perspective) | |
82 if self.sessionIdentity: | |
83 setattr(sess, self.sessionIdentity, ident) | |
84 p = perspective.attached(sess, ident) | |
85 _Detacher(sess, ident, p) | |
86 return self.reqauth.reallyRender(request) | |
87 | |
88 def didntGetPerspective(self, error, request): | |
89 log.msg('Password not verified! Error: %s' % error) | |
90 io = StringIO() | |
91 io.write(self.formatError("Login incorrect.")) | |
92 self.format(self.getFormFields(request), io.write, request) | |
93 return [io.getvalue()] | |
94 | |
95 def gotIdentity(self, ident, password, request, perspectiveName): | |
96 pwrq = ident.verifyPlainPassword(password) | |
97 pwrq.addCallback(self.passwordIsOk, ident, password, | |
98 request, perspectiveName) | |
99 pwrq.addErrback(self.didntGetPerspective, request) | |
100 pwrq.needsHeader = 1 | |
101 return [pwrq] | |
102 | |
103 def passwordIsOk(self, msg, ident, password, request, perspectiveName): | |
104 ret = ident.requestPerspectiveForKey(self.reqauth.service.serviceName, | |
105 perspectiveName).addCallbacks( | |
106 self.gotPerspective, self.didntGetPerspective, | |
107 callbackArgs=(request,ident), | |
108 errbackArgs=(request,)) | |
109 ret.needsHeader = 1 | |
110 return [ret] | |
111 | |
112 def didntGetIdentity(self, unauth, request): | |
113 io = StringIO() | |
114 io.write(self.formatError("Login incorrect.")) | |
115 self.format(self.getFormFields(request), io.write, request) | |
116 return io.getvalue() | |
117 | |
118 def process(self, write, request, submit, username, password, perspective): | |
119 """Process the form results. | |
120 """ | |
121 # must be done before page is displayed so cookie can get set! | |
122 request.getSession() | |
123 # this site must be tagged with an application. | |
124 idrq = self.reqauth.service.authorizer.getIdentityRequest(username) | |
125 idrq.needsHeader = 1 | |
126 idrq.addCallbacks(self.gotIdentity, self.didntGetIdentity, | |
127 callbackArgs=(password,request,perspective or username
), | |
128 errbackArgs=(request,)) | |
129 return [idrq] | |
130 | |
131 class AuthPage(widgets.Page): | |
132 template = ''' | |
133 <html><head><title>Authorization Required</title></head> | |
134 <body> | |
135 <center> | |
136 %%%%authForm%%%% | |
137 </center> | |
138 </body> | |
139 </html> | |
140 ''' | |
141 authForm = None | |
142 def __init__(self, reqauth, sessionIdentity=None, sessionPerspective=None): | |
143 widgets.Page.__init__(self) | |
144 self.authForm = AuthForm(reqauth, sessionPerspective, sessionIdentity) | |
145 | |
146 | |
147 class WidgetGuard(widgets.Widget): | |
148 | |
149 def __init__(self, wid, service, | |
150 sessionIdentity=None, | |
151 sessionPerspective=None): | |
152 self.wid = wid | |
153 self.service = service | |
154 self.sessionPerspective = sessionPerspective | |
155 self.sessionIdentity = sessionIdentity | |
156 | |
157 def reallyRender(self, request): | |
158 return widgets.possiblyDeferWidget(self.wid, request) | |
159 | |
160 def display(self, request): | |
161 session = request.getSession() | |
162 resKey = string.join(['AUTH',self.service.serviceName], '_') | |
163 if hasattr(session, resKey): | |
164 return self.wid.display(request) | |
165 else: | |
166 return AuthForm(self).display(request) | |
167 | |
168 | |
169 | |
170 # TODO hiding forms behind a ResourceGuard sucks, because if | |
171 # ResourceGuard needs to authenticate the user, it will 1) complain | |
172 # about the form submitted, 2) throw the data away. This happens if | |
173 # you use "foo?a=b" -style URLs and the user hasn't authenticated yet, | |
174 # or with session expiry. | |
175 | |
176 class ResourceGuard(resource.Resource): | |
177 | |
178 isLeaf = 1 | |
179 | |
180 def __init__(self, res, service, sessionIdentity=None, sessionPerspective=No
ne): | |
181 resource.Resource.__init__(self) | |
182 self.res = res | |
183 self.service = service | |
184 self.sessionPerspective = sessionPerspective | |
185 self.sessionIdentity = sessionIdentity | |
186 | |
187 def __getattr__(self, k): | |
188 if not self.__dict__.has_key("res"): | |
189 raise AttributeError, k | |
190 return getattr(self.res, k) | |
191 | |
192 def __getstate__(self): | |
193 return self.__dict__.copy() | |
194 | |
195 def listNames(self): | |
196 return self.res.listNames() | |
197 | |
198 def reallyRender(self, request): | |
199 # it's authenticated already... | |
200 res = resource.getChildForRequest(self.res, request) | |
201 val = res.render(request) | |
202 if val != NOT_DONE_YET: | |
203 request.write(val) | |
204 request.finish() | |
205 return widgets.FORGET_IT | |
206 | |
207 def render(self, request): | |
208 session = request.getSession() | |
209 resKey = string.join(['AUTH',self.service.serviceName], '_') | |
210 if hasattr(session, resKey): | |
211 self.reallyRender(request) | |
212 return NOT_DONE_YET | |
213 else: | |
214 return AuthPage(self, | |
215 self.sessionPerspective, | |
216 self.sessionIdentity).render(request) | |
217 | |
OLD | NEW |