U
    n5{iè\  ã                   @   sœ  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d„ Z/G dd„ dƒZ0G dd„ dƒZ1G dd„ de1e0ej2ƒZ3G dd„ de1ej2ƒZ4G d d!„ d!e1ej2ƒZ5eej6ƒ G d"d#„ d#ƒZ7G d$d%„ d%ej2ƒZ8dS )&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                 C   s   t  | ¡ ¡ S ©N)Úbase64Ú	b64encodeÚstrip)Ús© r"   úB/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/web/test/test_httpauth.pyr   %   s    r   c                   @   sJ   e Zd ZdZdd„ Zddd„Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dS )Ú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                 C   s.   |   ¡ | _d| _d| _d| _t | j¡| _d S )Ns   foos   dreids   S3CuR1Ty)ÚmakeRequestÚrequestÚrealmÚusernameÚpasswordr   r   ÚcredentialFactory©Úselfr"   r"   r#   ÚsetUp0   s
    
zBasicAuthTestsMixin.setUpó   GETNc                 C   s   t | j›d�ƒ‚dS )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 makeRequestN)ÚNotImplementedErrorÚ	__class__)r,   ÚmethodÚclientAddressr"   r"   r#   r%   7   s    zBasicAuthTestsMixin.makeRequestc                 C   s   |   tt| jƒ¡ dS )zM
        L{BasicCredentialFactory} implements L{ICredentialFactory}.
        N©Ú
assertTruer   r   r*   r+   r"   r"   r#   Útest_interface?   s    z"BasicAuthTestsMixin.test_interfacec                 C   sd   t d | jd| jg¡ƒ}| j || j¡}|  t 	|¡¡ |  | 
| j¡¡ |  | 
| jd ¡¡ dS )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.
        ó    ó   :s   wrongN)r   Újoinr(   r)   r*   Údecoder&   r4   r	   Z
providedByÚcheckPasswordZassertFalse©r,   ÚresponseÚcredsr"   r"   r#   Útest_usernamePasswordE   s
    z)BasicAuthTestsMixin.test_usernamePasswordc                 C   sX   t d | jd| jg¡ƒ}| d¡}| j || j¡}|  t	t
|ƒ¡ |  | | j¡¡ dS )zz
        L{basic.BasicCredentialFactory.decode} decodes a base64-encoded
        response with incorrect padding.
        r6   r7   ó   =N)r   r8   r(   r)   r    r*   r9   r&   r4   r   r	   r:   r;   r"   r"   r#   Útest_incorrectPaddingR   s
    
z)BasicAuthTestsMixin.test_incorrectPaddingc                 C   s"   d}|   tj| jj||  ¡ ¡ dS )zˆ
        L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} if passed
        a response which is not base64-encoded.
        ó   xN)ÚassertRaisesr   ÚLoginFailedr*   r9   r%   ©r,   r<   r"   r"   r#   Útest_invalidEncoding^   s    üz(BasicAuthTestsMixin.test_invalidEncodingc                 C   s&   t dƒ}|  tj| jj||  ¡ ¡ dS )z•
        L{basic.BasicCredentialFactory.decode} raises L{LoginFailed} when
        passed a response which is not valid base64-encoded text.
        s   123abc+/N)r   rB   r   rC   r*   r9   r%   rD   r"   r"   r#   Útest_invalidCredentialsk   s    üz+BasicAuthTestsMixin.test_invalidCredentials)r.   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r-   r%   r5   r>   r@   rE   rF   r"   r"   r"   r#   r$   )   s   
r$   c                   @   s   e Zd Zddd„ZdS )ÚRequestMixinr.   Nc                 C   s,   |dkrt dddƒ}tdƒ}||_||_|S )zo
        Create a L{DummyRequest} (change me to create a
        L{twisted.web.http.Request} instead).
        NÚTCPÚ	localhostiÒ  ó   /)r
   r   r1   Úclient)r,   r1   r2   r&   r"   r"   r#   r%   z   s    zRequestMixin.makeRequest)r.   N)rG   rH   rI   r%   r"   r"   r"   r#   rK   y   s   rK   c                   @   s   e Zd ZdZdS )ÚBasicAuthTestszK
    Basic authentication tests which use L{twisted.web.http.Request}.
    N)rG   rH   rI   rJ   r"   r"   r"   r#   rP   ‡   s   rP   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚDigestAuthTestszL
    Digest authentication tests which use L{twisted.web.http.Request}.
    c                 C   s,   d| _ d| _t | j| j ¡| _|  ¡ | _dS )z>
        Create a DigestCredentialFactory for testing
        ó
   test realmó   md5N)r'   Ú	algorithmr   ÚDigestCredentialFactoryr*   r%   r&   r+   r"   r"   r#   r-   ’   s     ÿzDigestAuthTests.setUpc                    sn   d‰d‰dg‰ t ƒ ‰‡ ‡‡‡‡fdd„}ˆ ˆjjd|¡ ˆ ˆtdˆdƒ¡}ˆj ˆ|¡ ˆ ˆ d	 ¡ d
S )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.1r.   Fc                    s0   ˆ  ˆ| ¡ ˆ  ˆ|¡ ˆ  ˆ|¡ dˆ d< d S )NTr   )ÚassertEqual)Ú	_responseÚ_methodZ_host©ÚdoneÚhostr1   r<   r,   r"   r#   Úcheck¨   s    z*DigestAuthTests.test_decode.<locals>.checkr9   rL   éQ   r   N)ÚobjectÚpatchr*   r   r%   r
   r9   r4   )r,   r\   Úreqr"   rY   r#   Útest_decode�   s    zDigestAuthTests.test_decodec                 C   s   |   tt| jƒ¡ dS )zN
        L{DigestCredentialFactory} implements L{ICredentialFactory}.
        Nr3   r+   r"   r"   r#   r5   ³   s    zDigestAuthTests.test_interfacec                 C   st   | j  | j¡}|  |d d¡ |  |d d¡ |  |d d¡ |  d|¡ |  d|¡ | ¡ D ]}|  d	|¡ q^d
S )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'   rR   rT   rS   ÚnonceÚopaqueó   
N)r*   ÚgetChallenger&   rV   ÚassertInÚvaluesZassertNotIn)r,   Ú	challengeÚvr"   r"   r#   Útest_getChallenge¹   s    z!DigestAuthTests.test_getChallengec                 C   sd   |   dd¡}| j |¡}|  |d d¡ |  |d d¡ |  |d d¡ |  d	|¡ |  d
|¡ dS )z 
        L{DigestCredentialFactory.getChallenge} can issue a challenge even if
        the L{Request} it is passed returns L{None} from C{getClientIP}.
        r.   Nrb   rc   r'   rR   rT   rS   rd   re   )r%   r*   rg   rV   rh   )r,   r&   rj   r"   r"   r#   Ú test_getChallengeWithoutClientIPÊ   s    z0DigestAuthTests.test_getChallengeWithoutClientIPN)	rG   rH   rI   rJ   r-   ra   r5   rl   rm   r"   r"   r"   r#   rQ   �   s   rQ   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚUnauthorizedResourceTestsz,
    Tests for L{UnauthorizedResource}.
    c                 C   s4   t g ƒ}|  | dd¡|¡ |  | dd¡|¡ dS )zF
        An L{UnauthorizedResource} is every child of itself.
        ZfooNÚbar)r   ZassertIdenticalZgetChildWithDefault)r,   Úresourcer"   r"   r#   Útest_getChildWithDefaultÝ   s    z2UnauthorizedResourceTests.test_getChildWithDefaultc                 C   s@   t tdƒgƒ}| |¡ |  |jd¡ |  |j d¡dg¡ dS )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   ÚrenderrV   ÚresponseCodeÚresponseHeadersÚgetRawHeaders)r,   r&   rp   r"   r"   r#   Ú_unauthorizedRenderTestå   s    

þz1UnauthorizedResourceTests._unauthorizedRenderTestc                 C   s*   |   ¡ }|  |¡ |  dd |j¡¡ dS )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   Unauthorizedr6   N©r%   ry   rV   r8   Úwritten©r,   r&   r"   r"   r#   Útest_renderó   s    
z%UnauthorizedResourceTests.test_renderc                 C   s.   | j dd�}|  |¡ |  dd |j¡¡ dS )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)r1   r6   Nrz   r|   r"   r"   r#   Útest_renderHEADý   s    
z)UnauthorizedResourceTests.test_renderHEADc                 C   s:   t tdƒgƒ}|  ¡ }| |¡ |  |j d¡dg¡ dS )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\"foort   s   basic realm="example\\\"foo"N)r   r   r%   ru   rV   rw   rx   )r,   rp   r&   r"   r"   r#   Útest_renderQuotesRealm  s    

þz0UnauthorizedResourceTests.test_renderQuotesRealmc                 C   sP   t t dd¡gƒ}|  ¡ }| |¡ |j d¡d }|  d|¡ |  d|¡ dS )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.
        rS   s   example\"foort   r   s   realm="example\\\"foo"s   hm="md5N)r   r   rU   r%   ru   rw   rx   rh   )r,   rp   r&   Z
authHeaderr"   r"   r#   Útest_renderQuotesDigest  s    ÿ
z1UnauthorizedResourceTests.test_renderQuotesDigestN)
rG   rH   rI   rJ   rq   ry   r}   r~   r   r€   r"   r"   r"   r#   rn   Ø   s   

rn   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú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                 C   s   d| _ d| _|| _d S )Nr   )Ú	loggedOutÚloggedInÚavatarFactory)r,   r„   r"   r"   r#   Ú__init__5  s    zRealm.__init__c                 G   s2   t |kr(|  jd7  _t |  |¡| jfS tƒ ‚d S ©Né   )r   rƒ   r„   Úlogoutr/   )r,   ZavatarIdZmindZ
interfacesr"   r"   r#   ÚrequestAvatar:  s    zRealm.requestAvatarc                 C   s   |  j d7  _ d S r†   )r‚   r+   r"   r"   r#   rˆ   @  s    zRealm.logoutN)rG   rH   rI   rJ   r…   r‰   rˆ   r"   r"   r"   r#   r�   (  s   r�   c                   @   s¤   e Zd ZdZeZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&S )'ÚHTTPAuthHeaderTestsz.
    Tests for L{HTTPAuthSessionWrapper}.
    c                 C   s¨   d| _ d| _d| _d| _d| _tƒ | _| j | j | j¡ t| jdƒ| _	| j	 
| jt| jdƒ¡ | j | j	i| _t| jjƒ| _t | j| jg¡| _g | _t| j| jƒ| _dS )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   ÚcheckerZaddUserr   ÚavatarÚputChildÚavatarsr�   Úgetr'   r   ZPortalÚcredentialFactoriesr   Úwrapperr+   r"   r"   r#   r-   K  s    zHTTPAuthHeaderTests.setUpc                 C   s2   t | jd | j ƒ}|j dd| ¡ 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}.
        r7   ó   authorizationó   Basic )r   r(   r)   ÚrequestHeadersÚaddRawHeaderr   r•   )r,   r&   Úauthorizationr"   r"   r#   Ú_authorizedBasicLogin^  s    z)HTTPAuthHeaderTests._authorizedBasicLoginc                    sH   ˆ  ˆjg¡‰ tˆjˆ ƒ}ˆ  ¡ }‡ ‡fdd„}| |¡ ˆ  |¡ |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                    s   ˆ  ˆ jd¡ d S ©Nrs   ©rV   rv   ©Úresult©r&   r,   r"   r#   Ú
cbFinishedr  s    z@HTTPAuthHeaderTests.test_getChildWithDefault.<locals>.cbFinished)r%   r�   r   r•   ÚnotifyFinishÚaddCallbackru   ©r,   ÚchildÚdr¡   r"   r    r#   rq   h  s    

z,HTTPAuthHeaderTests.test_getChildWithDefaultc                    sf   ˆj  tdƒ¡ ˆ ˆjg¡‰ ˆ j d|¡ tˆjˆ ƒ}ˆ  	¡ }‡ ‡fdd„}| 
|¡ ˆ  |¡ |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.
        rr   r–   c                    s   ˆ  ˆ jd¡ d S rœ   r�   rž   r    r"   r#   r¡   †  s    zAHTTPAuthHeaderTests._invalidAuthorizationTest.<locals>.cbFinished)r”   Úappendr   r%   r�   r˜   r™   r   r•   r¢   r£   ru   )r,   r<   r¥   r¦   r¡   r"   r    r#   Ú_invalidAuthorizationTesty  s    

z-HTTPAuthHeaderTests._invalidAuthorizationTestc                 C   s   |   dtdƒ ¡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+   r"   r"   r#   Ú(test_getChildWithDefaultUnauthorizedUser�  s    z<HTTPAuthHeaderTests.test_getChildWithDefaultUnauthorizedUserc                 C   s   |   dt| 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 a user which exists and the wrong
        password.
        r—   s   :bar)r¨   r   r(   r+   r"   r"   r#   Ú,test_getChildWithDefaultUnauthorizedPassword•  s    ÿz@HTTPAuthHeaderTests.test_getChildWithDefaultUnauthorizedPasswordc                 C   s
   |   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+   r"   r"   r#   Ú*test_getChildWithDefaultUnrecognizedScheme   s    z>HTTPAuthHeaderTests.test_getChildWithDefaultUnrecognizedSchemec                    sV   ˆj  tdƒ¡ ˆ ˆjg¡‰ ˆ ˆ ¡}ˆ  ¡ }‡ ‡fdd„}| |¡ ˆ  |¡ |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.
        rr   c                    s   ˆ  ˆ jˆjg¡ d S r   )rV   r{   rŽ   ©Zignoredr    r"   r#   r¡   ´  s    zJHTTPAuthHeaderTests.test_getChildWithDefaultAuthorized.<locals>.cbFinished)	r”   r§   r   r%   r�   r›   r¢   r£   ru   r¤   r"   r    r#   Ú"test_getChildWithDefaultAuthorized¨  s    


z6HTTPAuthHeaderTests.test_getChildWithDefaultAuthorizedc                    sR   ˆj  tdƒ¡ ˆ g ¡‰ ˆ ˆ ¡}ˆ  ¡ }‡ ‡fdd„}| |¡ ˆ  |¡ |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.
        rr   c                    s   ˆ  ˆ jˆjg¡ d S r   )rV   r{   rŒ   r¬   r    r"   r#   r¡   È  s    z=HTTPAuthHeaderTests.test_renderAuthorized.<locals>.cbFinished)r”   r§   r   r%   r›   r¢   r£   ru   r¤   r"   r    r#   Útest_renderAuthorized»  s    



z)HTTPAuthHeaderTests.test_renderAuthorizedc                    sr   t tƒG dd„ dƒƒ}|ƒ ‰ ˆj ˆ ¡ ˆ ˆjg¡‰tˆjˆƒ}ˆ ¡ }‡ ‡‡fdd„}| 	|¡ ˆ 
|¡ |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                   @   s    e Zd ZdZdd„ Zdd„ ZdS )zUHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactorys   dumbc                 S   s
   g | _ d S r   )Úrequestsr+   r"   r"   r#   r…   Ú  s    z^HTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactory.__init__c                 S   s   | j  |¡ i S r   )r¯   r§   r|   r"   r"   r#   rg   Ý  s    zbHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactory.getChallengeN)rG   rH   rI   Úschemer…   rg   r"   r"   r"   r#   ÚDumbCredentialFactoryÖ  s   r±   c                    s   ˆ  ˆ jˆg¡ d S r   )rV   r¯   r¬   ©Úfactoryr&   r,   r"   r#   r¡   ç  s    zJHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.cbFinished)r   r   r”   r§   r%   r�   r   r•   r¢   r£   ru   )r,   r±   r¥   r¦   r¡   r"   r²   r#   Ú"test_getChallengeCalledWithRequestÏ  s    


z6HTTPAuthHeaderTests.test_getChallengeCalledWithRequestc                 C   sh   | j  tdƒ¡ G dd„ dtƒ}| j | j|ƒ ¡ |  | jg¡}|  |¡}| 	|¡ |  
| 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.
        rr   c                   @   s   e Zd Zdd„ ZdS )z7HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResourcec                 S   s   t S r   r   r|   r"   r"   r#   ru   ú  s    z>HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResource.renderN)rG   rH   rI   ru   r"   r"   r"   r#   ÚSlowerResourceù  s   rµ   r   )r”   r§   r   r   r�   r‘   r�   r%   r›   ru   rV   r'   r‚   )r,   rµ   r&   r¥   r"   r"   r#   Ú_logoutTestî  s    	

zHTTPAuthHeaderTests._logoutTestc                 C   s$   |   ¡ }| ¡  |  | jjd¡ dS )zX
        The realm's logout callback is invoked after the resource is rendered.
        r‡   N)r¶   ÚfinishrV   r'   r‚   r|   r"   r"   r#   Útest_logout  s    zHTTPAuthHeaderTests.test_logoutc                 C   s.   |   ¡ }| ttdƒƒ¡ |  | jjd¡ dS )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¶   ZprocessingFailedr   r   rV   r'   r‚   r|   r"   r"   r#   Útest_logoutOnError  s    z&HTTPAuthHeaderTests.test_logoutOnErrorc                 C   sH   | j  tdƒ¡ |  | jg¡}|j dd¡ t| j|ƒ}|  	|t
¡ dS )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.
        rr   r–   s   Basic decode should failN)r”   r§   r   r%   r�   r˜   r™   r   r•   ÚassertIsInstancer   )r,   r&   r¥   r"   r"   r#   Útest_decodeRaises  s     ÿz%HTTPAuthHeaderTests.test_decodeRaisesc                 C   sH   d}|   | j |¡d¡ tdƒ}| j |¡ |   | j |¡|df¡ dS )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)NNrr   s   abcdef123456N)rV   r•   Z_selectParseHeaderr   r”   r§   )r,   ZbasicAuthorizationr³   r"   r"   r#   Útest_selectParseResponse$  s    
 ÿ
þz,HTTPAuthHeaderTests.test_selectParseResponsec                    s¼   t  | t¡}G dd„ dtƒ‰ G ‡ fdd„dƒ}| j |ƒ ¡ |  | jg¡}|j 	dd¡ t
| j|ƒ}| |¡ |  |jd¡ |  dt|ƒ¡ |  |d	 d
 jˆ ¡ |  t|  ˆ ¡ƒd¡ dS )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                   @   s   e Zd ZdS )zKHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.UnexpectedExceptionN©rG   rH   rI   r"   r"   r"   r#   ÚUnexpectedException=  s   r¾   c                       s$   e Zd ZdZdd„ Z‡ fdd„ZdS )zBHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactorys   badc                 S   s   i S r   r"   )r,   rO   r"   r"   r#   rg   C  s    zOHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.getChallengec                    s
   ˆ ƒ ‚d S r   r"   )r,   r<   r&   ©r¾   r"   r#   r9   F  s    zIHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.decodeN)rG   rH   rI   r°   rg   r9   r"   r¿   r"   r#   Ú
BadFactory@  s   rÀ   r–   s   Bad abcéô  r‡   r   Úlog_failureN)r   ÚcreateWithCleanupr   Ú	Exceptionr”   r§   r%   r�   r˜   r™   r   r•   ru   rV   rv   ÚassertEqualsÚlenrº   ÚvalueÚflushLoggedErrors)r,   ÚlogObserverrÀ   r&   r¥   r"   r¿   r#   Útest_unexpectedDecodeError5  s    	
z.HTTPAuthHeaderTests.test_unexpectedDecodeErrorc                    s¼   t  | t¡}G dd„ dtƒ‰ G ‡ fdd„dƒ}| j |ƒ ¡ | j tdƒ¡ |  	| j
g¡}|  |¡}| |¡ |  |jd¡ |  dt|ƒ¡ |  |d d	 jˆ ¡ |  t|  ˆ ¡ƒd¡ d
S )z‰
        Any unexpected failure from L{Portal.login} results in a 500 response
        code and causes the failure to be logged.
        c                   @   s   e Zd ZdS )zJHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.UnexpectedExceptionNr½   r"   r"   r"   r#   r¾   Z  s   r¾   c                       s   e Zd ZefZ‡ fdd„ZdS )zDHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.BrokenCheckerc                    s
   ˆ ƒ ‚d S r   r"   )r,   Úcredentialsr¿   r"   r#   ÚrequestAvatarId`  s    zTHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.BrokenChecker.requestAvatarIdN)rG   rH   rI   r	   ZcredentialInterfacesrÌ   r"   r¿   r"   r#   ÚBrokenChecker]  s   rÍ   rr   rÁ   r‡   r   rÂ   N)r   rÃ   r   rÄ   r   ÚregisterCheckerr”   r§   r   r%   r�   r›   ru   rV   rv   rÅ   rÆ   rº   rÇ   rÈ   )r,   rÉ   rÍ   r&   r¥   r"   r¿   r#   Útest_unexpectedLoginErrorS  s    

z-HTTPAuthHeaderTests.test_unexpectedLoginErrorc                    s’   d‰t ƒ ˆjt< ˆjt  ˆjtˆdƒ¡ ˆj tƒ ¡ ˆj	 
tdƒ¡ ˆ ˆjg¡‰ tˆjˆ ƒ}ˆ  ¡ }‡ ‡‡fdd„}| |¡ ˆ  |¡ |S )zl
        Anonymous requests are allowed if a L{Portal} has an anonymous checker
        registered.
        s*   contents of the unprotected child resourcer‹   rr   c                    s   ˆ  ˆ jˆg¡ d S r   )rV   r{   r¬   ©r&   r,   ZunprotectedContentsr"   r#   r¡     s    z<HTTPAuthHeaderTests.test_anonymousAccess.<locals>.cbFinished)r   r’   r   r‘   r�   r   r   rÎ   r   r”   r§   r   r%   r   r•   r¢   r£   ru   r¤   r"   rÐ   r#   Útest_anonymousAccessm  s    
 ÿ

z(HTTPAuthHeaderTests.test_anonymousAccessN)rG   rH   rI   rJ   r   r%   r-   r›   rq   r¨   r©   rª   r«   r­   r®   r´   r¶   r¸   r¹   r»   r¼   rÊ   rÏ   rÑ   r"   r"   r"   r#   rŠ   D  s(   

rŠ   )9rJ   r   Zzope.interfacer   Zzope.interface.verifyr   Ztwisted.credr   r   Ztwisted.cred.checkersr   r   r   Ztwisted.cred.credentialsr	   Ztwisted.internet.addressr
   Ztwisted.internet.errorr   Ztwisted.internet.testingr   Ztwisted.loggerr   Ztwisted.python.failurer   Ztwisted.trialr   Ztwisted.web._authr   r   Ztwisted.web._auth.basicr   Ztwisted.web._auth.wrapperr   r   Ztwisted.web.iwebr   Ztwisted.web.resourcer   r   r   Ztwisted.web.serverr   Ztwisted.web.staticr   Ztwisted.web.test.test_webr   r   r$   rK   ZTestCaserP   rQ   rn   ZIRealmr�   rŠ   r"   r"   r"   r#   Ú<module>   s:   PKM
