U
    
W[@^  ã                   @   s¶  d Z ddlmZmZ ddl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 ddlmZmZmZ ddl m!Z!m"Z" ddl#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l0m1Z1 dd„ Z2G dd„ dƒZ3G dd„ dƒZ4G dd„ de4e3e
j5ƒZ6G d d!„ d!e4e
j5ƒZ7G d"d#„ d#e4e
j5ƒZ8eej9ƒ G d$d%„ d%e:ƒZ;G d&d'„ d'e
j5ƒZ<dS )(z!
Tests for L{twisted.web._auth}.
é    )ÚdivisionÚabsolute_importN)Úimplementer)ÚverifyObject)Úunittest)ÚFailure)ÚConnectionDone)ÚIPv4Address)ÚerrorÚportal)Ú'InMemoryUsernamePasswordDatabaseDontUse)Ú	ANONYMOUSÚAllowAnonymousAccess)ÚIUsernamePassword)ÚICredentialFactory)Ú	IResourceÚResourceÚgetChildForRequest)ÚbasicÚdigest)ÚHTTPAuthSessionWrapperÚUnauthorizedResource)ÚBasicCredentialFactory©ÚNOT_DONE_YET)ÚData)ÚDummyRequest)ÚEventLoggingObserver)ÚglobalLogPublisherc                 C   s   t  | ¡ ¡ S ©N)Úbase64Ú	b64encodeÚstrip)Ús© r$   ú@/usr/lib/python3/dist-packages/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%   ÚsetUp2   s
    
zBasicAuthTestsMixin.setUpó   GETNc                 C   s   t d| jf ƒ‚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 %r did not implement makeRequestN)ÚNotImplementedErrorÚ	__class__)r.   ÚmethodÚclientAddressr$   r$   r%   r'   :   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_interfaceD   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(   r6   r   Z
providedByÚcheckPasswordZassertFalse©r.   ÚresponseZcredsr$   r$   r%   Útest_usernamePasswordL   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.
        r8   r9   ó   =N)r!   r:   r*   r+   r"   r,   r;   r(   r6   r   r   r<   r=   r$   r$   r%   Útest_incorrectPaddingZ   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,   r;   r'   ©r.   r>   r$   r$   r%   Útest_invalidEncodingg   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!   rC   r
   rD   r,   r;   r'   rE   r$   r$   r%   Útest_invalidCredentialsr   s     ýz+BasicAuthTestsMixin.test_invalidCredentials)r0   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   r'   r7   r?   rA   rF   rG   r$   r$   r$   r%   r&   ,   s   

r&   c                   @   s   e Zd Zddd„ZdS )ÚRequestMixinr0   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ÚTCPZ	localhostiÒ  ó   /)r	   r   r3   Úclient)r.   r3   r4   r(   r$   r$   r%   r'      s    zRequestMixin.makeRequest)r0   N)rH   rI   rJ   r'   r$   r$   r$   r%   rL   ~   s   rL   c                   @   s   e Zd ZdZdS )ÚBasicAuthTestszK
    Basic authentication tests which use L{twisted.web.http.Request}.
    N)rH   rI   rJ   rK   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.1r0   Fc                    s0   ˆ  ˆ| ¡ ˆ  ˆ|¡ ˆ  ˆ|¡ dˆ d< d S )NTr   )ÚassertEqual)Z	_responseÚ_methodZ_host©ZdoneZhostr3   r>   r.   r$   r%   Úcheck®   s    z*DigestAuthTests.test_decode.<locals>.checkr;   rM   éQ   r   N)ÚobjectZpatchr,   r   r'   r	   r;   r6   )r.   rY   Zreqr$   rX   r%   Útest_decode¤   s    zDigestAuthTests.test_decodec                 C   s   |   tt| jƒ¡ dS )zN
        L{DigestCredentialFactory} implements L{ICredentialFactory}.
        Nr5   r-   r$   r$   r%   r7   º   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}.
        r0   Nr]   r^   r)   rR   rT   rS   r_   r`   )r'   r,   rb   rV   rc   )r.   r(   re   r$   r$   r%   Ú test_getChallengeWithoutClientIPÔ   s    z0DigestAuthTests.test_getChallengeWithoutClientIPN)	rH   rI   rJ   rK   r/   r\   r7   rg   rh   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fooNZ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(   rj   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   Unauthorizedr8   N©r'   rs   rV   r:   Ú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)r3   r8   Nrt   rv   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\"foorn   s   basic realm="example\\\"foo"N)r   r   r'   ro   rV   rq   rr   )r.   rj   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\"foorn   r   s   realm="example\\\"foo"s   hm="md5N)r   r   rU   r'   ro   rq   rr   rc   )r.   rj   r(   Z
authHeaderr$   r$   r%   Útest_renderQuotesDigest&  s    
ÿ
ÿþz1UnauthorizedResourceTests.test_renderQuotesDigestN)
rH   rI   rJ   rK   rk   rs   rw   rx   ry   rz   r$   r$   r$   r%   ri   ã   s   ri   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__F  s    zRealm.__init__c                 G   s2   t |kr(|  jd7  _t |  |¡| jfS tƒ ‚d S ©Né   )r   r}   r~   Úlogoutr1   )r.   ZavatarIdZmindZ
interfacesr$   r$   r%   ÚrequestAvatarL  s    zRealm.requestAvatarc                 C   s   |  j d7  _ d S r€   )r|   r-   r$   r$   r%   r‚   S  s    zRealm.logoutN)rH   rI   rJ   rK   r   rƒ   r‚   r$   r$   r$   r%   r{   9  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   ZcheckerZaddUserr   ÚavatarÚputChildÚavatarsr{   Úgetr)   r   ZPortalÚcredentialFactoriesr   Úwrapperr-   r$   r$   r%   r/   ^  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}.
        r9   ó   authorizationó   Basic )r!   r*   r+   ÚrequestHeadersÚaddRawHeaderr   rŽ   )r.   r(   Zauthorizationr$   r$   r%   Ú_authorizedBasicLogint  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 ©Nrm   ©rV   rp   ©Úresult©r(   r.   r$   r%   Ú
cbFinished‰  s    z@HTTPAuthHeaderTests.test_getChildWithDefault.<locals>.cbFinished)r'   r‡   r   rŽ   ÚnotifyFinishÚaddCallbackro   ©r.   ÚchildÚdr™   r$   r˜   r%   rk   €  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.
        rl   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›   ro   )r.   r>   r   rž   r™   r$   r˜   r%   Ú_invalidAuthorizationTest  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.
        rl   c                    s   ˆ  ˆ jˆjg¡ d S r   )rV   ru   rˆ   ©Zignoredr˜   r$   r%   r™   Ì  s    zJHTTPAuthHeaderTests.test_getChildWithDefaultAuthorized.<locals>.cbFinished)	r   rŸ   r   r'   r‡   r“   rš   r›   ro   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.
        rl   c                    s   ˆ  ˆ jˆjg¡ d S r   )rV   ru   r†   r¤   r˜   r$   r%   r™   ß  s    z=HTTPAuthHeaderTests.test_renderAuthorized.<locals>.cbFinished)r   rŸ   r   r'   r“   rš   r›   ro   rœ   r$   r˜   r%   Útest_renderAuthorizedÓ  s    



z)HTTPAuthHeaderTests.test_renderAuthorizedc                    st   t tƒG dd„ dtƒƒ}|ƒ ‰ ˆ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Ÿ   rv   r$   r$   r%   rb   ó  s    zbHTTPAuthHeaderTests.test_getChallengeCalledWithRequest.<locals>.DumbCredentialFactory.getChallengeN)rH   rI   rJ   Úschemer   rb   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š   r›   ro   )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.
        rl   c                   @   s   e Zd Zdd„ ZdS )z7HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResourcec                 S   s   t S r   r   rv   r$   r$   r%   ro     s    z>HTTPAuthHeaderTests._logoutTest.<locals>.SlowerResource.renderN)rH   rI   rJ   ro   r$   r$   r$   r%   ÚSlowerResource  s   r­   r   )r   rŸ   r   r   r‰   rŠ   r‡   r'   r“   ro   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®   ZfinishrV   r)   r|   rv   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|   rv   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.
        rl   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)NNrl   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tƒ}| 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©rH   rI   rJ   r$   r$   r$   r%   ÚUnexpectedExceptionW  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%   rb   ]  s    zOHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.getChallengec                    s
   ˆ ƒ ‚d S r   r$   )r.   r>   r(   ©rµ   r$   r%   r;   `  s    zIHTTPAuthHeaderTests.test_unexpectedDecodeError.<locals>.BadFactory.decodeN)rH   rI   rJ   r¨   rb   r;   r$   r¶   r$   r%   Ú
BadFactoryZ  s   r·   r   s   Bad abcéô  r   r   Úlog_failureN)r   ÚcreateWithCleanupr   Ú	Exceptionr[   r   rŸ   r'   r‡   r‘   r’   r   rŽ   ro   rV   rp   ÚassertEqualsÚlenr±   ÚvalueÚflushLoggedErrors)r.   ÚlogObserverr·   r(   r   r$   r¶   r%   Útest_unexpectedDecodeErrorM  s$    þ	
þz.HTTPAuthHeaderTests.test_unexpectedDecodeErrorc                    s¾   t  | t¡}G dd„ dtƒ‰ G ‡ fdd„dtƒ}| 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.   Zcredentialsr¶   r$   r%   ÚrequestAvatarId€  s    zTHTTPAuthHeaderTests.test_unexpectedLoginError.<locals>.BrokenChecker.requestAvatarIdN)rH   rI   rJ   r   ZcredentialInterfacesrÂ   r$   r¶   r$   r%   ÚBrokenChecker}  s   rÃ   rl   r¸   r   r   r¹   N)r   rº   r   r»   r[   r   ÚregisterCheckerr   rŸ   r   r'   r‡   r“   ro   rV   rp   r¼   r½   r±   r¾   r¿   )r.   rÀ   rÃ   r(   r   r$   r¶   r%   Útest_unexpectedLoginErrorq  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…   rl   c                    s   ˆ  ˆ jˆg¡ d S r   )rV   ru   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›   ro   rœ   r$   rÆ   r%   Útest_anonymousAccess‘  s    
 ÿ

z(HTTPAuthHeaderTests.test_anonymousAccessN)rH   rI   rJ   rK   r   r'   r/   r“   rk   r    r¡   r¢   r£   r¥   r¦   r¬   r®   r¯   r°   r²   r³   rÁ   rÅ   rÇ   r$   r$   r$   r%   r„   X  s(   
		$ r„   )=rK   Z
__future__r   r   r    Zzope.interfacer   Zzope.interface.verifyr   Ztwisted.trialr   Ztwisted.python.failurer   Ztwisted.internet.errorr   Ztwisted.internet.addressr	   Ztwisted.credr
   r   Ztwisted.cred.checkersr   r   r   Ztwisted.cred.credentialsr   Ztwisted.web.iwebr   Ztwisted.web.resourcer   r   r   Ztwisted.web._authr   r   Ztwisted.web._auth.wrapperr   r   Ztwisted.web._auth.basicr   Ztwisted.web.serverr   Ztwisted.web.staticr   Ztwisted.web.test.test_webr   Ztwisted.test.proto_helpersr   Ztwisted.loggerr   r!   r&   rL   ZTestCaserP   rQ   ri   ZIRealmr[   r{   r„   r$   r$   r$   r%   Ú<module>   s>   ROU
