Ϫf!dZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZmZeeGd d ZeeGd d Zy )a A guard implementation which supports HTTP header-based authentication schemes. If no I{Authorization} header is supplied, an anonymous login will be attempted by using a L{Anonymous} credentials object. If such a header is supplied and does not contain allowed credentials, or if anonymous login is denied, a 401 will be sent in the response along with I{WWW-Authenticate} headers for each of the allowed authentication schemes. ) implementer)error) Anonymous)Logger)proxyForInterface)util) IResource_UnsafeErrorPagec,eZdZdZdZdZdZdZdZy)UnauthorizedResourcez6 Simple IResource to escape Resource dispatch Tc||_yN)_credentialFactories)self factoriess ;/usr/lib/python3/dist-packages/twisted/web/_auth/wrapper.py__init__zUnauthorizedResource.__init__#s $-!cdfd}d|jd|jD]@}|j|}|jj d||j |B|j dk(ryy) z= Send www-authenticate headers to the client cHt|tr|jdS|S)Nascii) isinstancestrencodess r ensureBytesz0UnauthorizedResource.render..ensureBytes+s(21c(:188G$ A Arcg}|jD]2\}}|}|}|j|dz|z4dj|dj|gS)N= s, )itemsappendjoin)scheme challengelstkvr quoteStrings rgenerateWWWAuthenticatez.generateWWWAuthenticate.skC!) 61NN 1t8k!n45 699fejjo67 7rcRd|jddjddzdzS)N"\s\\s\")replacers rr)z0UnauthorizedResource.render..quoteString6s*!))E62::4HH4O Oriswww-authenticatesHEADrs Unauthorized)setResponseCoder getChallengeresponseHeaders addRawHeaderr$method)rrequestr*factr%rr)s @@rrenderzUnauthorizedResource.render&s  B 8 P $-- D))'2I  # # 0 0#%>W $rc|S)z+ Disable resource dispatch rpathr4s rgetChildWithDefaultz(UnauthorizedResource.getChildWithDefaultCs  rctrNotImplementedErrorrr:childs rputChildzUnauthorizedResource.putChildI !##rN) __name__ __module__ __qualname____doc__isLeafrr6r;rAr8rrr r s"F.: $rr cXeZdZdZdZeZdZdZdZ dZ dZ dZ d Z d Zd Zy ) HTTPAuthSessionWrapperaa Wrap a portal, enforcing supported header-based authentication schemes. @ivar _portal: The L{Portal} which will be used to retrieve L{IResource} avatars. @ivar _credentialFactories: A list of L{ICredentialFactory} providers which will be used to decode I{Authorization} headers into L{ICredentials} providers. Fc ||_||_y)a[ Initialize a session wrapper @type portal: C{Portal} @param portal: The portal that will authenticate the remote client @type credentialFactories: C{Iterable} @param credentialFactories: The portal that will authenticate the remote client based on one submitted C{ICredentialFactory} N)_portalr)rportalcredentialFactoriess rrzHTTPAuthSessionWrapper.__init__^s $7!rc|jd}|s,tj|jt S|j |\}}|t |jS |j||}tj|j|S#tj$rt |jcYSt$r+|jjdtdddcYSwxYw)a Get the L{IResource} which the given request is authorized to receive. If the proper authorization headers are present, the resource will be requested from the portal. If not, an anonymous login attempt will be made. s authorizationz+Unexpected failure from credentials factoryInternal Error) getHeaderrDeferredResource_loginr_selectParseHeaderr rdecoder LoginFailed BaseException_logfailurer )rr4 authheaderfactory respString credentialss r_authorizedResourcez*HTTPAuthSessionWrapper._authorizedResourcels&&'78 ((Y[)AB B"55jA ?'(A(AB B C!..W=K(([)AB B    C'(A(AB B ? II  K L#C)92> > ?s,B""(C? 0C?>C?cB|j|j|S)z Find the L{IResource} avatar suitable for the given request, if possible, and render it. Otherwise, perhaps render an error page requiring authorization or describing an internal server failure. )r_r6)rr4s rr6zHTTPAuthSessionWrapper.renders ''077@@rc|jjd|jj|j |S)a\ Inspect the Authorization HTTP header, and return a deferred which, when fired after successful authentication, will return an authorized C{Avatar}. On authentication failure, an C{UnauthorizedResource} will be returned, essentially halting further dispatch on the wrapped resource and all children r)postpathinsertprepathpopr_r9s rr;z*HTTPAuthSessionWrapper.getChildWithDefaults8 7??#6#6#89''00rc|jj|dt}|j|j|j |S)z Get the L{IResource} avatar for the given credentials. @return: A L{Deferred} which will be called back with an L{IResource} avatar or which will errback if authentication fails. N)rKloginr addCallbacks_loginSucceeded _loginFailed)rr^ds rrTzHTTPAuthSessionWrapper._logins; LL  {D) < t++T->->?rcZ|\}}Gfddttd|S)z Handle login success by wrapping the resulting L{IResource} avatar so that the C{logout} callback will be invoked when rendering is complete. c0eZdZdZfdZfdZxZS)?HTTPAuthSessionWrapper._loginSucceeded..ResourceWrappera Wrap an L{IResource} so that whenever it or a child of it completes rendering, the cred logout hook will be invoked. An assumption is made here that exactly one L{IResource} from among C{avatar} and all of its children will be rendered. If more than one is rendered, C{logout} will be invoked multiple times and probably earlier than desired. cH|jj||S)z Pass through the lookup to the wrapped resource, wrapping the result in L{ResourceWrapper} to ensure C{logout} is called when rendering of the child is complete. )resourcer;)rnamer4ResourceWrappers rr;zSHTTPAuthSessionWrapper._loginSucceeded..ResourceWrapper.getChildWithDefaults! 't}}'H'Hw'WXXrcf|jjfdt| |S)z Hook into response generation so that when rendering has finished completely (with or without error), C{logout} is called. cSrr8)ignlogouts rzXHTTPAuthSessionWrapper._loginSucceeded..ResourceWrapper.render..s 68r) notifyFinishaddBothsuperr6)rr4 __class__rvs rr6zFHTTPAuthSessionWrapper._loginSucceeded..ResourceWrapper.renders, $$&../CDw~g..r)rCrDrErFr;r6 __classcell__)r{rrrvs@rrrrns  Y / /rrrrp)rr )rargs interfaceavatarrrrvs @@rriz&HTTPAuthSessionWrapper._loginSucceededs2 %)! 66 // :F /8v&&rc|jtjtjrt |j S|j jd|tdddS)z Handle login failure by presenting either another challenge (for expected authentication/authorization-related failures) or a server error page (for anything else). zGHTTPAuthSessionWrapper.getChildWithDefault encountered unexpected error)rZrOrPrQ) checkr UnauthorizedrWr rrYrZr )rresults rrjz#HTTPAuthSessionWrapper._loginFaileds` <<**E,=,= >'(A(AB B II  #   $C)92> >rc|jd}|dj}|jD])}|j|k(s|dj |ddfcSy)aV Choose an C{ICredentialFactory} from C{_credentialFactories} suitable to use to decode the given I{Authenticate} header. @return: A two-tuple of a factory and the remaining portion of the header value to be decoded or a two-tuple of L{None} if no factory can decode the header value. r rN)NN)splitlowerrr$r#)rheaderelementsr$r5s rrUz)HTTPAuthSessionWrapper._selectParseHeadersd<<%!""$-- 7D{{f$dii 566 7rctrr=r?s rrAzHTTPAuthSessionWrapper.putChildrBrN)rCrDrErFrGrrYrr_r6r;rTrirjrUrAr8rrrIrINsE F 8D 8C0A 1 $'L?  $rrIN)rFzope.interfacer twisted.credrtwisted.cred.credentialsrtwisted.loggerrtwisted.python.componentsr twisted.webrtwisted.web.resourcer r r rIr8rrrsa '.!7< Y/$/$/$d Y]$]$]$r