| 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 |