Ë
    ojè\  ã                   ó&  — d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
mZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z, ddl-m.Z. d„ Z/ G d„ d«      Z0 G d„ d«      Z1 G d„ de1e0ejd                  «      Z3 G d„ de1ejd                  «      Z4 G d„ d e1ejd                  «      Z5 eejl                  «        G d!„ d"«      Z7 G d#„ d$ejd                  «      Z8y)%z!
Tests for L{twisted.web._auth}.
é    N)Úimplementer)ÚverifyObject)ÚerrorÚportal)Ú	ANONYMOUSÚAllowAnonymousAccessÚ'InMemoryUsernamePasswordDatabaseDontUse)ÚIUsernamePassword)ÚIPv4Address)ÚConnectionDone)ÚEventLoggingObserver)ÚglobalLogPublisher)ÚFailure)Úunittest)ÚbasicÚdigest)ÚBasicCredentialFactory)ÚHTTPAuthSessionWrapperÚUnauthorizedResource)ÚICredentialFactory)Ú	IResourceÚResourceÚgetChildForRequest©ÚNOT_DONE_YET)ÚData)ÚDummyRequestc                 óH   — t        j                  | «      j                  «       S ©N)Úbase64Ú	b64encodeÚstrip)Úss    ú@/usr/lib/python3/dist-packages/twisted/web/test/test_httpauth.pyr!   r!   %   s   € Ü×Ñ˜AÓ×$Ñ$Ó&Ð&ó    c                   ó<   — e Zd ZdZd„ Zd
d„Zd„ Zd„ Zd„ Zd„ Z	d	„ Z
y)ÚBasicAuthTestsMixinz½
    L{TestCase} mixin class which defines a number of tests for
    L{basic.BasicCredentialFactory}.  Because this mixin defines C{setUp}, it
    must be inherited before L{TestCase}.
    c                 ó    — | j                  «       | _        d| _        d| _        d| _        t        j                  | j                  «      | _        y )Ns   foos   dreids   S3CuR1Ty)ÚmakeRequestÚrequestÚrealmÚusernameÚpasswordr   r   ÚcredentialFactory©Úselfs    r$   ÚsetUpzBasicAuthTestsMixin.setUp0   s>   € Ø×'Ñ'Ó)ˆŒØˆŒ
Ø ˆŒØ#ˆŒÜ!&×!=Ñ!=¸d¿j¹jÓ!IˆÕr%   Nc                 ó2   — t        | j                  ›d�«      ‚)zª
        Create a request object to be passed to
        L{basic.BasicCredentialFactory.decode} along with a response value.
        Override this in a subclass.
        z did not implement makeRequest)ÚNotImplementedErrorÚ	__class__)r0   ÚmethodÚclientAddresss      r$   r)   zBasicAuthTestsMixin.makeRequest7   s   € ô " T§^¡^Ð$6Ð6TÐ"UÓVÐVr%   c                 óV   — | j                  t        t        | j                  «      «       y)zM
        L{BasicCredentialFactory} implements L{ICredentialFactory}.
        N©Ú
assertTruer   r   r.   r/   s    r$   Útest_interfacez"BasicAuthTestsMixin.test_interface?   ó   € ð 	�‰œÔ%7¸×9OÑ9OÓPÕQr%   c                 ó¨  — t        dj                  | j                  d| j                  g«      «      }| j                  j                  || j                  «      }| j                  t        j                  |«      «       | j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       y)zÔ
        L{basic.BasicCredentialFactory.decode} turns a base64-encoded response
        into a L{UsernamePassword} object with a password which reflects the
        one which was encoded in the response.
        r%   ó   :s   wrongN)r!   Újoinr,   r-   r.   Údecoder*   r9   r
   Ú
providedByÚcheckPasswordÚassertFalse©r0   ÚresponseÚcredss      r$   Útest_usernamePasswordz)BasicAuthTestsMixin.test_usernamePasswordE   s—   € ô ˜SŸX™X t§}¡}°d¸D¿M¹MÐ&JÓKÓLˆà×&Ñ&×-Ñ-¨h¸¿¹ÓEˆØ�‰Ô)×4Ñ4°UÓ;Ô<Ø�‰˜×+Ñ+¨D¯M©MÓ:Ô;Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÕGr%   c                 óf  — t        dj                  | j                  d| j                  g«      «      }|j	                  d«      }| j
                  j                  || j                  «      }| j                  t        t        |«      «       | j                  |j                  | j                  «      «       y)zz
        L{basic.BasicCredentialFactory.decode} decodes a base64-encoded
        response with incorrect padding.
        r%   r=   ó   =N)r!   r>   r,   r-   r"   r.   r?   r*   r9   r   r
   rA   rC   s      r$   Útest_incorrectPaddingz)BasicAuthTestsMixin.test_incorrectPaddingR   s   € ô
 ˜SŸX™X t§}¡}°d¸D¿M¹MÐ&JÓKÓLˆØ—>‘> $Ó'ˆà×&Ñ&×-Ñ-¨h¸¿¹ÓEˆØ�‰œÔ%6¸Ó>Ô?Ø�‰˜×+Ñ+¨D¯M©MÓ:Õ;r%   c                 ó�   — d}| j                  t        j                  | j                  j                  || j                  «       «       y)zˆ
        L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} if passed
        a response which is not base64-encoded.
        ó   xN)ÚassertRaisesr   ÚLoginFailedr.   r?   r)   ©r0   rD   s     r$   Útest_invalidEncodingz(BasicAuthTestsMixin.test_invalidEncoding^   s>   € ð
 ˆØ×ÑÜ×ÑØ×"Ñ"×)Ñ)ØØ×ÑÓõ		
r%   c                 ó¢   — t        d«      }| j                  t        j                  | j                  j
                  || j                  «       «       y)z•
        L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} when
        passed a response which is not valid base64-encoded text.
        s   123abc+/N)r!   rL   r   rM   r.   r?   r)   rN   s     r$   Útest_invalidCredentialsz+BasicAuthTestsMixin.test_invalidCredentialsk   sC   € ô
 ˜[Ó)ˆØ×ÑÜ×ÑØ×"Ñ"×)Ñ)ØØ×ÑÓõ		
r%   ©ó   GETN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r1   r)   r:   rF   rI   rO   rQ   © r%   r$   r'   r'   )   s.   „ ñòJóWòRòHò
<ò
ó
r%   r'   c                   ó   — e Zd Zdd„Zy)ÚRequestMixinNc                 óV   — |€t        ddd«      }t        d«      }||_        ||_        |S )zo
        Create a L{DummyRequest} (change me to create a
        L{twisted.web.http.Request} instead).
        ÚTCPÚ	localhostiÒ  ó   /)r   r   r5   Úclient)r0   r5   r6   r*   s       r$   r)   zRequestMixin.makeRequestz   s5   € ð
 Ð Ü'¨¨{¸DÓAˆMÜ˜tÓ$ˆØˆŒØ&ˆŒØˆr%   rR   )rT   rU   rV   r)   rX   r%   r$   rZ   rZ   y   s   „ ô
r%   rZ   c                   ó   — e Zd ZdZy)ÚBasicAuthTestszK
    Basic authentication tests which use L{twisted.web.http.Request}.
    N)rT   rU   rV   rW   rX   r%   r$   ra   ra   ‡   s   „ òr%   ra   c                   ó.   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚDigestAuthTestszL
    Digest authentication tests which use L{twisted.web.http.Request}.
    c                 ó¨   — d| _         d| _        t        j                  | j                  | j                   «      | _        | j                  «       | _        y)z>
        Create a DigestCredentialFactory for testing
        ó
   test realmó   md5N)r+   Ú	algorithmr   ÚDigestCredentialFactoryr.   r)   r*   r/   s    r$   r1   zDigestAuthTests.setUp’   sD   € ð #ˆŒ
ØˆŒÜ!'×!?Ñ!?Ø�N‰N˜DŸJ™Jó"
ˆÔð ×'Ñ'Ó)ˆ�r%   c                 ó*  ‡ ‡‡‡‡— dŠdŠdgŠt        «       Šˆˆˆˆˆ fd„}‰ j                  ‰ j                  j                  d|«       ‰ j	                  ‰t        d‰d«      «      }‰ j                  j                  ‰|«       ‰ j                  ‰d   «       y	)
zÅ
        L{digest.DigestCredentialFactory.decode} calls the C{decode} method on
        L{twisted.cred.digest.DigestCredentialFactory} with the HTTP method and
        host of the request.
        s   169.254.0.1rS   Fc                 ó|   •— ‰j                  ‰| «       ‰j                  ‰|«       ‰j                  ‰|«       d‰d<   y )NTr   )ÚassertEqual)Ú	_responseÚ_methodÚ_hostÚdoneÚhostr5   rD   r0   s      €€€€€r$   Úcheckz*DigestAuthTests.test_decode.<locals>.check¨   s<   ø€ Ø×Ñ˜X yÔ1Ø×Ñ˜V WÔ-Ø×Ñ˜T 5Ô)ØˆD�ŠGr%   r?   r\   éQ   r   N)ÚobjectÚpatchr.   r   r)   r   r?   r9   )r0   rq   Úreqro   rp   r5   rD   s   `  @@@@r$   Útest_decodezDigestAuthTests.test_decode�   s†   ü€ ð ˆØˆØˆwˆÜ“8ˆ÷	ð 	ð 	�
‰
�4×)Ñ)×0Ñ0°(¸EÔBØ×Ñ˜v¤{°5¸$ÀÓ'CÓDˆØ×Ñ×%Ñ% h°Ô4Ø�‰˜˜Q™Õ r%   c                 óV   — | j                  t        t        | j                  «      «       y)zN
        L{DigestCredentialFactory} implements L{ICredentialFactory}.
        Nr8   r/   s    r$   r:   zDigestAuthTests.test_interface³   r;   r%   c                 ób  — | j                   j                  | j                  «      }| j                  |d   d«       | j                  |d   d«       | j                  |d   d«       | j	                  d|«       | j	                  d|«       |j                  «       D ]  }| j                  d	|«       Œ y
)ah  
        The challenge issued by L{DigestCredentialFactory.getChallenge} must
        include C{'qop'}, C{'realm'}, C{'algorithm'}, C{'nonce'}, and
        C{'opaque'} keys.  The values for the C{'realm'} and C{'algorithm'}
        keys must match the values supplied to the factory's initializer.
        None of the values may have newlines in them.
        Úqopó   authr+   re   rg   rf   ÚnonceÚopaqueó   
N)r.   ÚgetChallenger*   rk   ÚassertInÚvaluesÚassertNotIn)r0   Ú	challengeÚvs      r$   Útest_getChallengez!DigestAuthTests.test_getChallenge¹   s¡   € ð ×*Ñ*×7Ñ7¸¿¹ÓEˆ	Ø×Ñ˜ 5Ñ)¨7Ô3Ø×Ñ˜ 7Ñ+¨]Ô;Ø×Ñ˜ ;Ñ/°Ô8Ø�‰�g˜yÔ)Ø�‰�h 	Ô*Ø×!Ñ!Ó#ò 	'ˆAØ×Ñ˜U AÕ&ñ	'r%   c                 ó$  — | j                  dd«      }| j                  j                  |«      }| j                  |d   d«       | j                  |d   d«       | j                  |d   d«       | j	                  d	|«       | j	                  d
|«       y)z 
        L{DigestCredentialFactory.getChallenge} can issue a challenge even if
        the L{Request} it is passed returns L{None} from C{getClientIP}.
        rS   Nry   rz   r+   re   rg   rf   r{   r|   )r)   r.   r~   rk   r   )r0   r*   r‚   s      r$   Ú test_getChallengeWithoutClientIPz0DigestAuthTests.test_getChallengeWithoutClientIPÊ   s‡   € ð
 ×"Ñ" 6¨4Ó0ˆØ×*Ñ*×7Ñ7¸Ó@ˆ	Ø×Ñ˜ 5Ñ)¨7Ô3Ø×Ñ˜ 7Ñ+¨]Ô;Ø×Ñ˜ ;Ñ/°Ô8Ø�‰�g˜yÔ)Ø�‰�h 	Õ*r%   N)	rT   rU   rV   rW   r1   rv   r:   r„   r†   rX   r%   r$   rc   rc   �   s!   „ ñò	*ò!ò,Rò'ó"+r%   rc   c                   ó4   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)	ÚUnauthorizedResourceTestsz,
    Tests for L{UnauthorizedResource}.
    c                 ó¢   — t        g «      }| j                  |j                  dd«      |«       | j                  |j                  dd«      |«       y)zF
        An L{UnauthorizedResource} is every child of itself.
        ÚfooNÚbar)r   ÚassertIdenticalÚgetChildWithDefault)r0   Úresources     r$   Útest_getChildWithDefaultz2UnauthorizedResourceTests.test_getChildWithDefaultÝ   sH   € ô (¨Ó+ˆØ×Ñ˜X×9Ñ9¸%ÀÓFÈÔQØ×Ñ˜X×9Ñ9¸%ÀÓFÈÕQr%   c                 óà   — t        t        d«      g«      }|j                  |«       | j                  |j                  d«       | j                  |j
                  j                  d«      dg«       y)zç
        Render L{UnauthorizedResource} for the given request object and verify
        that the response code is I{Unauthorized} and that a I{WWW-Authenticate}
        header is set in the response containing a challenge.
        úexample.comé‘  ó   www-authenticates   basic realm="example.com"N)r   r   Úrenderrk   ÚresponseCodeÚresponseHeadersÚgetRawHeaders)r0   r*   rŽ   s      r$   Ú_unauthorizedRenderTestz1UnauthorizedResourceTests._unauthorizedRenderTestå   sb   € ô (Ô)?ÀÓ)NÐ(OÓPˆØ�‰�xÔ Ø×Ñ˜×-Ñ-¨sÔ3Ø×ÑØ×#Ñ#×1Ñ1Ð2EÓFØ)Ð*õ	
r%   c                 óœ   — | j                  «       }| j                  |«       | j                  ddj                  |j                  «      «       y)zº
        L{UnauthorizedResource} renders with a 401 response code and a
        I{WWW-Authenticate} header and puts a simple unauthorized message
        into the response body.
        s   Unauthorizedr%   N©r)   r˜   rk   r>   Úwritten©r0   r*   s     r$   Útest_renderz%UnauthorizedResourceTests.test_renderó   s=   € ð ×"Ñ"Ó$ˆØ×$Ñ$ WÔ-Ø×Ñ˜¨#¯(©(°7·?±?Ó*CÕDr%   c                 ó    — | j                  d¬«      }| j                  |«       | j                  ddj                  |j                  «      «       y)z´
        The rendering behavior of L{UnauthorizedResource} for a I{HEAD} request
        is like its handling of a I{GET} request, but no response body is
        written.
        s   HEAD)r5   r%   Nrš   rœ   s     r$   Útest_renderHEADz)UnauthorizedResourceTests.test_renderHEADý   sB   € ð ×"Ñ"¨'Ð"Ó2ˆØ×$Ñ$ WÔ-Ø×Ñ˜˜cŸh™h w§¡Ó7Õ8r%   c                 óÈ   — t        t        d«      g«      }| j                  «       }|j                  |«       | j	                  |j
                  j                  d«      dg«       y)z¾
        The realm value included in the I{WWW-Authenticate} header set in
        the response when L{UnauthorizedResounrce} is rendered has quotes
        and backslashes escaped.
        zexample\"foor“   s   basic realm="example\\\"foo"N)r   r   r)   r”   rk   r–   r—   )r0   rŽ   r*   s      r$   Útest_renderQuotesRealmz0UnauthorizedResourceTests.test_renderQuotesRealm  sZ   € ô (Ô)?ÀÓ)PÐ(QÓRˆØ×"Ñ"Ó$ˆØ�‰�xÔ Ø×ÑØ×#Ñ#×1Ñ1Ð2EÓFØ/Ð0õ	
r%   c                 ó
  — t        t        j                  dd«      g«      }| j                  «       }|j	                  |«       |j
                  j                  d«      d   }| j                  d|«       | j                  d|«       y)z¾
        The digest value included in the I{WWW-Authenticate} header
        set in the response when L{UnauthorizedResource} is rendered
        has quotes and backslashes escaped.
        rf   s   example\"foor“   r   s   realm="example\\\"foo"s   hm="md5N)r   r   rh   r)   r”   r–   r—   r   )r0   rŽ   r*   Ú
authHeaders       r$   Útest_renderQuotesDigestz1UnauthorizedResourceTests.test_renderQuotesDigest  sx   € ô (Ü×+Ñ+¨FÐ4DÓEÐFó
ˆð ×"Ñ"Ó$ˆØ�‰�xÔ Ø×,Ñ,×:Ñ:Ð;NÓOÐPQÑRˆ
Ø�‰Ð2°JÔ?Ø�‰�j *Õ-r%   N)
rT   rU   rV   rW   r�   r˜   r�   rŸ   r¡   r¤   rX   r%   r$   rˆ   rˆ   Ø   s'   „ ñòRò
òEò9ò
ó.r%   rˆ   c                   ó"   — e Zd ZdZd„ Zd„ Zd„ Zy)ÚRealmaJ  
    A simple L{IRealm} implementation which gives out L{WebAvatar} for any
    avatarId.

    @type loggedIn: C{int}
    @ivar loggedIn: The number of times C{requestAvatar} has been invoked for
        L{IResource}.

    @type loggedOut: C{int}
    @ivar loggedOut: The number of times the logout callback has been invoked.
    c                 ó.   — d| _         d| _        || _        y )Nr   )Ú	loggedOutÚloggedInÚavatarFactory)r0   rª   s     r$   Ú__init__zRealm.__init__5  s   € ØˆŒØˆŒØ*ˆÕr%   c                 ó”   — t         |v r7| xj                  dz  c_        t         | j                  |«      | j                  fS t	        «       ‚©Né   )r   r©   rª   Úlogoutr3   )r0   ÚavatarIdÚmindÚ
interfacess       r$   ÚrequestAvatarzRealm.requestAvatar:  s=   € Ü˜
Ñ"Ø�MŠM˜QÑ�MÜ˜d×0Ñ0°Ó:¸D¿K¹KÐGÐGÜ!Ó#Ð#r%   c                 ó.   — | xj                   dz  c_         y r­   )r¨   r/   s    r$   r¯   zRealm.logout@  s   € Ø�Š˜!ÑŽr%   N)rT   rU   rV   rW   r«   r³   r¯   rX   r%   r$   r¦   r¦   (  s   „ ñ
ò+ò
$ór%   r¦   c                   ó€   — e Zd ZdZeZd„ Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)ÚHTTPAuthHeaderTestsz.
    Tests for L{HTTPAuthSessionWrapper}.
    c                 ó¬  — d| _         d| _        d| _        d| _        d| _        t        «       | _        | j                  j                  | j                   | j                  «       t        | j                  d«      | _	        | j                  j                  | j                  t        | j                  d«      «       | j                   | j                  i| _        t        | j                  j                  «      | _        t        j                   | j                  | j                  g«      | _        g | _        t%        | j                  | j"                  «      | _        y)z\
        Create a realm, portal, and L{HTTPAuthSessionWrapper} to use in the tests.
        s   foo bars   bar bazs&   contents of the avatar resource itselfs	   foo-childs'   contents of the foo child of the avatarú
text/plainN)r,   r-   ÚavatarContentÚ	childNameÚchildContentr	   ÚcheckerÚaddUserr   ÚavatarÚputChildÚavatarsr¦   Úgetr+   r   ÚPortalÚcredentialFactoriesr   Úwrapperr/   s    r$   r1   zHTTPAuthHeaderTests.setUpK  sî   € ð #ˆŒØ"ˆŒØFˆÔØ%ˆŒØFˆÔÜ>Ó@ˆŒØ�‰×Ñ˜TŸ]™]¨D¯M©MÔ:Ü˜4×-Ñ-¨|Ó<ˆŒØ�‰×Ñ˜TŸ^™^¬T°$×2CÑ2CÀ\Ó-RÔSØŸ™ t§{¡{Ð3ˆŒÜ˜4Ÿ<™<×+Ñ+Ó,ˆŒ
Ü—m‘m D§J¡J°·±°Ó?ˆŒØ#%ˆÔ Ü-¨d¯k©k¸4×;SÑ;SÓTˆ�r%   c                 ó¶   — t        | j                  dz   | j                  z   «      }|j                  j	                  dd|z   «       t        | j                  |«      S )z¹
        Add an I{basic authorization} header to the given request and then
        dispatch it, starting from C{self.wrapper} and returning the resulting
        L{IResource}.
        r=   ó   authorizationó   Basic )r!   r,   r-   ÚrequestHeadersÚaddRawHeaderr   rÄ   )r0   r*   Úauthorizations      r$   Ú_authorizedBasicLoginz)HTTPAuthHeaderTests._authorizedBasicLogin^  sM   € ô " $§-¡-°$Ñ"6¸¿¹Ñ"FÓGˆØ×Ñ×+Ñ+Ð,<¸iÈ-Ñ>WÔXÜ! $§,¡,°Ó8Ð8r%   c                 óÞ   ‡ ‡— ‰ j                  ‰ j                  g«      Št        ‰ j                  ‰«      }‰j	                  «       }ˆˆ fd„}|j                  |«       ‰j                  |«       |S )z×
        Resource traversal which encounters an L{HTTPAuthSessionWrapper}
        results in an L{UnauthorizedResource} instance when the request does
        not have the required I{Authorization} headers.
        c                 ó>   •— ‰j                  ‰j                  d«       y ©Nr’   ©rk   r•   ©Úresultr*   r0   s    €€r$   Ú
cbFinishedz@HTTPAuthHeaderTests.test_getChildWithDefault.<locals>.cbFinishedr  ó   ø€ Ø×Ñ˜W×1Ñ1°3Õ7r%   )r)   rº   r   rÄ   ÚnotifyFinishÚaddCallbackr”   ©r0   ÚchildÚdrÒ   r*   s   `   @r$   r�   z,HTTPAuthHeaderTests.test_getChildWithDefaulth  s^   ù€ ð ×"Ñ" D§N¡NÐ#3Ó4ˆÜ" 4§<¡<°Ó9ˆØ× Ñ Ó"ˆõ	8ð 	
�‰�jÔ!Ø�‰�uÔØˆr%   c                 ó^  ‡ ‡— ‰ j                   j                  t        d«      «       ‰ j                  ‰ j                  g«      Š‰j
                  j                  d|«       t        ‰ j                  ‰«      }‰j                  «       }ˆˆ fd„}|j                  |«       ‰j                  |«       |S )a(  
        Create a request with the given value as the value of an
        I{Authorization} header and perform resource traversal with it,
        starting at C{self.wrapper}.  Assert that the result is a 401 response
        code.  Return a L{Deferred} which fires when this is all done.
        r‘   rÆ   c                 ó>   •— ‰j                  ‰j                  d«       y rÎ   rÏ   rÐ   s    €€r$   rÒ   zAHTTPAuthHeaderTests._invalidAuthorizationTest.<locals>.cbFinished†  rÓ   r%   )rÃ   Úappendr   r)   rº   rÈ   rÉ   r   rÄ   rÔ   rÕ   r”   )r0   rD   r×   rØ   rÒ   r*   s   `    @r$   Ú_invalidAuthorizationTestz-HTTPAuthHeaderTests._invalidAuthorizationTesty  s�   ù€ ð 	× Ñ ×'Ñ'Ô(>¸}Ó(MÔNØ×"Ñ" D§N¡NÐ#3Ó4ˆØ×Ñ×+Ñ+Ð,<¸hÔGÜ" 4§<¡<°Ó9ˆØ× Ñ Ó"ˆõ	8ð 	
�‰�jÔ!Ø�‰�uÔØˆr%   c                 ó<   — | j                  dt        d«      z   «      S )zÚ
        Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
        results in an L{UnauthorizedResource} when the request has an
        I{Authorization} header with a user which does not exist.
        rÇ   s   foo:bar)rÜ   r!   r/   s    r$   Ú(test_getChildWithDefaultUnauthorizedUserz<HTTPAuthHeaderTests.test_getChildWithDefaultUnauthorizedUser�  s   € ð ×-Ñ-¨i¼)ÀJÓ:OÑ.OÓPÐPr%   c                 óV   — | j                  dt        | j                  dz   «      z   «      S )zñ
        Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
        results in an L{UnauthorizedResource} when the request has an
        I{Authorization} header with a user which exists and the wrong
        password.
        rÇ   s   :bar)rÜ   r!   r,   r/   s    r$   Ú,test_getChildWithDefaultUnauthorizedPasswordz@HTTPAuthHeaderTests.test_getChildWithDefaultUnauthorizedPassword•  s-   € ð ×-Ñ-Øœ	 $§-¡-°'Ñ"9Ó:Ñ:ó
ð 	
r%   c                 ó$   — | j                  d«      S )zÕ
        Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
        results in an L{UnauthorizedResource} when the request has an
        I{Authorization} header with an unrecognized scheme.
        s   Quux foo bar baz)rÜ   r/   s    r$   Ú*test_getChildWithDefaultUnrecognizedSchemez>HTTPAuthHeaderTests.test_getChildWithDefaultUnrecognizedScheme   s   € ð ×-Ñ-Ð.AÓBÐBr%   c                 ó  ‡ ‡— ‰ j                   j                  t        d«      «       ‰ j                  ‰ j                  g«      Š‰ j                  ‰«      }‰j                  «       }ˆˆ fd„}|j                  |«       ‰j                  |«       |S )zû
        Resource traversal which encounters an L{HTTPAuthSessionWrapper}
        results in an L{IResource} which renders the L{IResource} avatar
        retrieved from the portal when the request has a valid I{Authorization}
        header.
        r‘   c                 óT   •— ‰j                  ‰j                  ‰j                  g«       y r   )rk   r›   r»   ©Úignoredr*   r0   s    €€r$   rÒ   zJHTTPAuthHeaderTests.test_getChildWithDefaultAuthorized.<locals>.cbFinished´  s    ø€ Ø×Ñ˜WŸ_™_¨t×/@Ñ/@Ð.AÕBr%   )	rÃ   rÛ   r   r)   rº   rË   rÔ   rÕ   r”   rÖ   s   `   @r$   Ú"test_getChildWithDefaultAuthorizedz6HTTPAuthHeaderTests.test_getChildWithDefaultAuthorized¨  sy   ù€ ð 	× Ñ ×'Ñ'Ô(>¸}Ó(MÔNØ×"Ñ" D§N¡NÐ#3Ó4ˆØ×*Ñ*¨7Ó3ˆØ× Ñ Ó"ˆõ	Cð 	
�‰�jÔ!Ø�‰�uÔØˆr%   c                 ó  ‡ ‡— ‰ j                   j                  t        d«      «       ‰ j                  g «      Š‰ j	                  ‰«      }‰j                  «       }ˆˆ fd„}|j                  |«       ‰j                  |«       |S )a   
        Resource traversal which terminates at an L{HTTPAuthSessionWrapper}
        and includes correct authentication headers results in the
        L{IResource} avatar (not one of its children) retrieved from the
        portal being rendered.
        r‘   c                 óT   •— ‰j                  ‰j                  ‰j                  g«       y r   )rk   r›   r¹   rå   s    €€r$   rÒ   z=HTTPAuthHeaderTests.test_renderAuthorized.<locals>.cbFinishedÈ  s    ø€ Ø×Ñ˜WŸ_™_¨t×/AÑ/AÐ.BÕCr%   )rÃ   rÛ   r   r)   rË   rÔ   rÕ   r”   rÖ   s   `   @r$   Útest_renderAuthorizedz)HTTPAuthHeaderTests.test_renderAuthorized»  sr   ù€ ð 	× Ñ ×'Ñ'Ô(>¸}Ó(MÔNà×"Ñ" 2Ó&ˆØ×*Ñ*¨7Ó3ˆØ× Ñ Ó"ˆõ	Dð 	
�‰�jÔ!Ø�‰�uÔØˆr%   c                 ó^  ‡ ‡‡— t        t        «       G d„ d«      «       } |«       Š‰ j                  j                  ‰«       ‰ j	                  ‰ j
                  g«      Št        ‰ j                  ‰«      }‰j                  «       }ˆˆˆ fd„}|j                  |«       ‰j                  |«       |S )zº
        When L{HTTPAuthSessionWrapper} finds an L{ICredentialFactory} to issue
        a challenge, it calls the C{getChallenge} method with the request as an
        argument.
        c                   ó   — e Zd ZdZd„ Zd„ Zy)úUHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactorys   dumbc                 ó   — g | _         y r   )Úrequestsr/   s    r$   r«   z^HTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactory.__init__Ú  s	   € Ø "�•r%   c                 ó<   — | j                   j                  |«       i S r   )rï   rÛ   rœ   s     r$   r~   zbHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactory.getChallengeÝ  s   € Ø—‘×$Ñ$ WÔ-Ø�	r%   N)rT   rU   rV   Úschemer«   r~   rX   r%   r$   ÚDumbCredentialFactoryrí   Ö  s   „ àˆFò#ór%   rò   c                 ó@   •— ‰j                  ‰j                  ‰g«       y r   )rk   rï   )ræ   Úfactoryr*   r0   s    €€€r$   rÒ   zJHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.cbFinishedç  s   ø€ Ø×Ñ˜W×-Ñ-°¨yÕ9r%   )r   r   rÃ   rÛ   r)   rº   r   rÄ   rÔ   rÕ   r”   )r0   rò   r×   rØ   rÒ   rô   r*   s   `    @@r$   Ú"test_getChallengeCalledWithRequestz6HTTPAuthHeaderTests.test_getChallengeCalledWithRequestÏ  s™   ú€ ô 
Ô'Ó	(÷	ð 	ó 
)ð	ñ (Ó)ˆØ× Ñ ×'Ñ'¨Ô0Ø×"Ñ" D§N¡NÐ#3Ó4ˆÜ" 4§<¡<°Ó9ˆØ× Ñ Ó"ˆö	:ð 	
�‰�jÔ!Ø�‰�uÔØˆr%   c                 óŠ  — | j                   j                  t        d«      «        G d„ dt        «      }| j                  j                  | j                   |«       «       | j                  | j                  g«      }| j                  |«      }|j                  |«       | j                  | j                  j                  d«       |S )a  
        Issue a request for an authentication-protected resource using valid
        credentials and then return the C{DummyRequest} instance which was
        used.

        This is a helper for tests about the behavior of the logout
        callback.
        r‘   c                   ó   — e Zd Zd„ Zy)ú7HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResourcec                 ó   — t         S r   r   rœ   s     r$   r”   z>HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResource.renderú  s   € Ü#Ð#r%   N)rT   rU   rV   r”   rX   r%   r$   ÚSlowerResourcerø   ù  s   „ ó$r%   rú   r   )rÃ   rÛ   r   r   r¾   r¿   rº   r)   rË   r”   rk   r+   r¨   )r0   rú   r*   r×   s       r$   Ú_logoutTestzHTTPAuthHeaderTests._logoutTestî  s™   € ð 	× Ñ ×'Ñ'Ô(>¸}Ó(MÔNô	$œXô 	$ð 	�‰×Ñ˜TŸ^™^©^Ó-=Ô>Ø×"Ñ" D§N¡NÐ#3Ó4ˆØ×*Ñ*¨7Ó3ˆØ�‰�uÔØ×Ñ˜Ÿ™×-Ñ-¨qÔ1Øˆr%   c                 ó�   — | j                  «       }|j                  «        | j                  | j                  j                  d«       y)zX
        The realm's logout callback is invoked after the resource is rendered.
        r®   N)rû   Úfinishrk   r+   r¨   rœ   s     r$   Útest_logoutzHTTPAuthHeaderTests.test_logout  s6   € ð ×"Ñ"Ó$ˆØ�‰ÔØ×Ñ˜Ÿ™×-Ñ-¨qÕ1r%   c                 ó¶   — | j                  «       }|j                  t        t        d«      «      «       | j	                  | j
                  j                  d«       y)zª
        The realm's logout callback is also invoked if there is an error
        generating the response (for example, if the client disconnects
        early).
        zSimulated disconnectr®   N)rû   ÚprocessingFailedr   r   rk   r+   r¨   rœ   s     r$   Útest_logoutOnErrorz&HTTPAuthHeaderTests.test_logoutOnError  sE   € ð ×"Ñ"Ó$ˆØ× Ñ ¤¬Ð8NÓ)OÓ!PÔQØ×Ñ˜Ÿ™×-Ñ-¨qÕ1r%   c                 ó  — | j                   j                  t        d«      «       | j                  | j                  g«      }|j
                  j                  dd«       t        | j                  |«      }| j                  |t        «       y)zã
        Resource traversal which enouncters an L{HTTPAuthSessionWrapper}
        results in an L{UnauthorizedResource} when the request has a I{Basic
        Authorization} header which cannot be decoded using base64.
        r‘   rÆ   s   Basic decode should failN)rÃ   rÛ   r   r)   rº   rÈ   rÉ   r   rÄ   ÚassertIsInstancer   )r0   r*   r×   s      r$   Útest_decodeRaisesz%HTTPAuthHeaderTests.test_decodeRaises  sr   € ð 	× Ñ ×'Ñ'Ô(>¸}Ó(MÔNØ×"Ñ" D§N¡NÐ#3Ó4ˆØ×Ñ×+Ñ+ØÐ9ô	
ô # 4§<¡<°Ó9ˆØ×Ñ˜eÔ%9Õ:r%   c                 ó  — d}| j                  | j                  j                  |«      d«       t        d«      }| j                  j                  |«       | j                  | j                  j                  |«      |df«       y)zì
        L{HTTPAuthSessionWrapper._selectParseHeader} returns a two-tuple giving
        the L{ICredentialFactory} to use to parse the header and a string
        containing the portion of the header which remains to be parsed.
        s   Basic abcdef123456)NNr‘   s   abcdef123456N)rk   rÄ   Ú_selectParseHeaderr   rÃ   rÛ   )r0   ÚbasicAuthorizationrô   s      r$   Útest_selectParseResponsez,HTTPAuthHeaderTests.test_selectParseResponse$  sv   € ð 3ÐØ×ÑØ�L‰L×+Ñ+Ð,>Ó?Àô	
ô )¨Ó7ˆØ× Ñ ×'Ñ'¨Ô0Ø×ÑØ�L‰L×+Ñ+Ð,>Ó?Ø�oÐ&õ	
r%   c                 ót  ‡— t        j                  | t        «      } G d„ dt        «      Š G ˆfd„d«      }| j                  j                   |«       «       | j                  | j                  g«      }|j                  j                  dd«       t        | j                  |«      }|j                  |«       | j                  |j                  d«       | j                  dt!        |«      «       | j#                  |d	   d
   j$                  ‰«       | j                  t!        | j'                  ‰«      «      d«       y)z´
        Any unexpected exception raised by the credential factory's C{decode}
        method results in a 500 response code and causes the exception to be
        logged.
        c                   ó   — e Zd Zy)úKHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.UnexpectedExceptionN©rT   rU   rV   rX   r%   r$   ÚUnexpectedExceptionr  =  ó   „ Ør%   r  c                   ó"   •— e Zd ZdZd„ Zˆ fd„Zy)úBHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactorys   badc                 ó   — i S r   rX   )r0   r_   s     r$   r~   zOHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.getChallengeC  s   € Ø�	r%   c                 ó   •—  ‰«       ‚r   rX   )r0   rD   r*   r  s      €r$   r?   zIHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.decodeF  ó   ø€ Ù)Ó+Ð+r%   N)rT   rU   rV   rñ   r~   r?   ©r  s   €r$   Ú
BadFactoryr  @  s   ø„ ØˆFòõ,r%   r  rÆ   s   Bad abcéô  r®   r   Úlog_failureN)r   ÚcreateWithCleanupr   Ú	ExceptionrÃ   rÛ   r)   rº   rÈ   rÉ   r   rÄ   r”   rk   r•   ÚassertEqualsÚlenr  ÚvalueÚflushLoggedErrors)r0   ÚlogObserverr  r*   r×   r  s        @r$   Útest_unexpectedDecodeErrorz.HTTPAuthHeaderTests.test_unexpectedDecodeError5  sü   ø€ ô +×<Ñ<¸TÔCUÓVˆô	¤)ô 	÷	,ó 	,ð 	× Ñ ×'Ñ'©
«Ô5Ø×"Ñ" D§N¡NÐ#3Ó4ˆØ×Ñ×+Ñ+Ð,<¸jÔIÜ" 4§<¡<°Ó9ˆØ�‰�uÔØ×Ñ˜×-Ñ-¨sÔ3Ø×Ñ˜!œS Ó-Ô.Ø×Ñ˜k¨!™n¨]Ñ;×AÑAÐCVÔWØ×Ñœ˜T×3Ñ3Ð4GÓHÓIÈ1ÕMr%   c                 óz  ‡— t        j                  | t        «      } G d„ dt        «      Š G ˆfd„d«      }| j                  j                   |«       «       | j                  j                  t        d«      «       | j                  | j                  g«      }| j                  |«      }|j                  |«       | j                  |j                  d«       | j                  dt!        |«      «       | j#                  |d   d	   j$                  ‰«       | j                  t!        | j'                  ‰«      «      d«       y
)z‰
        Any unexpected failure from L{Portal.login} results in a 500 response
        code and causes the failure to be logged.
        c                   ó   — e Zd Zy)úJHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.UnexpectedExceptionNr  rX   r%   r$   r  r"  Z  r  r%   r  c                   ó   •— e Zd ZefZˆ fd„Zy)úDHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.BrokenCheckerc                 ó   •—  ‰«       ‚r   rX   )r0   Úcredentialsr  s     €r$   ÚrequestAvatarIdzTHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.BrokenChecker.requestAvatarId`  r  r%   N)rT   rU   rV   r
   ÚcredentialInterfacesr'  r  s   €r$   ÚBrokenCheckerr$  ]  s   ø„ Ø$5Ð#7Ð õ,r%   r)  r‘   r  r®   r   r  N)r   r  r   r  r   ÚregisterCheckerrÃ   rÛ   r   r)   rº   rË   r”   rk   r•   r  r  r  r  r  )r0   r  r)  r*   r×   r  s        @r$   Útest_unexpectedLoginErrorz-HTTPAuthHeaderTests.test_unexpectedLoginErrorS  sý   ø€ ô
 +×<Ñ<¸TÔCUÓVˆô	¤)ô 	÷	,ó 	,ð 	�‰×#Ñ#¡M£OÔ4Ø× Ñ ×'Ñ'Ô(>¸}Ó(MÔNØ×"Ñ" D§N¡NÐ#3Ó4ˆØ×*Ñ*¨7Ó3ˆØ�‰�uÔØ×Ñ˜×-Ñ-¨sÔ3Ø×Ñ˜!œS Ó-Ô.Ø×Ñ˜k¨!™n¨]Ñ;×AÑAÐCVÔWØ×Ñœ˜T×3Ñ3Ð4GÓHÓIÈ1ÕMr%   c                 ó  ‡ ‡‡— dŠt        «       ‰ j                  t        <   ‰ j                  t           j                  ‰ j                  t        ‰d«      «       ‰ j                  j                  t        «       «       ‰ j                  j                  t        d«      «       ‰ j                  ‰ j                  g«      Št        ‰ j                  ‰«      }‰j                  «       }ˆˆ ˆfd„}|j!                  |«       ‰j#                  |«       |S )zl
        Anonymous requests are allowed if a L{Portal} has an anonymous checker
        registered.
        s*   contents of the unprotected child resourcer¸   r‘   c                 ó@   •— ‰j                  ‰j                  ‰g«       y r   )rk   r›   )ræ   r*   r0   ÚunprotectedContentss    €€€r$   rÒ   z<HTTPAuthHeaderTests.test_anonymousAccess.<locals>.cbFinished  s   ø€ Ø×Ñ˜WŸ_™_Ð/BÐ.CÕDr%   )r   rÀ   r   r¿   rº   r   r   r*  r   rÃ   rÛ   r   r)   r   rÄ   rÔ   rÕ   r”   )r0   r×   rØ   rÒ   r*   r.  s   `   @@r$   Útest_anonymousAccessz(HTTPAuthHeaderTests.test_anonymousAccessm  sÐ   ú€ ð
 LÐä"*£*ˆ�‰”YÑØ�‰”YÑ×(Ñ(Ø�N‰NœDÐ!4°lÓCô	
ð 	�‰×#Ñ#Ô$8Ó$:Ô;à× Ñ ×'Ñ'Ô(>¸}Ó(MÔNØ×"Ñ" D§N¡NÐ#3Ó4ˆÜ" 4§<¡<°Ó9ˆØ× Ñ Ó"ˆö	Eð 	
�‰�jÔ!Ø�‰�uÔØˆr%   N)rT   rU   rV   rW   r   r)   r1   rË   r�   rÜ   rÞ   rà   râ   rç   rê   rõ   rû   rþ   r  r  r  r  r+  r/  rX   r%   r$   r¶   r¶   D  sm   „ ñð €KòUò&9òò"ò(Qò	
òCòò&ò(ò>ò,2ò2ò;ò
ò"Nò<Nó4r%   r¶   )9rW   r    Úzope.interfacer   Úzope.interface.verifyr   Útwisted.credr   r   Útwisted.cred.checkersr   r   r	   Útwisted.cred.credentialsr
   Útwisted.internet.addressr   Útwisted.internet.errorr   Útwisted.internet.testingr   Útwisted.loggerr   Útwisted.python.failurer   Útwisted.trialr   Útwisted.web._authr   r   Útwisted.web._auth.basicr   Útwisted.web._auth.wrapperr   r   Útwisted.web.iwebr   Útwisted.web.resourcer   r   r   Útwisted.web.serverr   Útwisted.web.staticr   Útwisted.web.test.test_webr   r!   r'   rZ   ÚTestCasera   rc   rˆ   ÚIRealmr¦   r¶   rX   r%   r$   ú<module>rE     sá   ðñó
 å &Ý .ç &÷ñ õ
 7Ý 0Ý 1Ý 9Ý -Ý *Ý "ß +Ý :ß RÝ /ß HÑ HÝ +Ý #Ý 2ò'÷M
ñ M
÷`ñ ô�\Ð#6¸×8IÑ8Iô ôH+�l H×$5Ñ$5ô H+ôVJ. ¨h×.?Ñ.?ô J.ñZ ˆF�M‰MÔ ÷ñ ô8@˜(×+Ñ+õ @r%   