U
    sÍ@gâA  ã                   @   sL  d 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mZmZmZ ddlmZ dd	lmZ zdd
lmZ W n ek
r    dZdZY nX dZdZdZdZde ZdZde ZG dd„ dejƒZG dd„ de ƒZ!G dd„ de!ejƒZ"G dd„ de!ejƒZ#G dd„ de!ejƒZ$G dd„ dejƒZ%G dd „ d ejƒZ&dS )!z4
Tests for L{twisted.words.protocols.jabber.client}
é    )Úabsolute_importÚdivision)Úsha1)Údefer)Úunicode)Úunittest)ÚclientÚerrorÚjidÚ	xmlstream)ÚSASLInitiatingInitializer)Úutility)ÚsslNzSSL not availablez//iq[@type="get"]/query[@xmlns="jabber:iq:auth"]z//iq[@type="set"]/query[@xmlns="jabber:iq:auth"]z urn:ietf:params:xml:ns:xmpp-bindz"/iq[@type="set"]/bind[@xmlns="%s"]z#urn:ietf:params:xml:ns:xmpp-sessionz%/iq[@type="set"]/session[@xmlns="%s"]c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚCheckVersionInitializerTestsc                 C   s"   t  ¡ }t  |¡}t |¡| _d S ©N)r   ZAuthenticatorZ	XmlStreamr   ZCheckVersionInitializerÚinit)ÚselfÚaÚxs© r   úF/usr/lib/python3/dist-packages/twisted/words/test/test_jabberclient.pyÚsetUp#   s    
z"CheckVersionInitializerTests.setUpc                 C   s   d| j j_| j  ¡  dS )z3
        Test supported version number 1.0
        )é   r   N)r   r   ÚversionÚ
initialize©r   r   r   r   ÚtestSupported)   s    
z*CheckVersionInitializerTests.testSupportedc                 C   s.   d| j j_|  tj| j j¡}|  d|j¡ dS )zK
        Test unsupported version number 0.0, and check exception.
        )r   r   zunsupported-versionN)	r   r   r   ZassertRaisesr	   ZStreamErrorr   ÚassertEqualZ	condition)r   Úexcr   r   r   ÚtestNotSupported1   s    
z-CheckVersionInitializerTests.testNotSupportedN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   "   s   r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚInitiatingInitializerHarnessaè  
    Testing harness for interacting with XML stream initializers.

    This sets up an L{utility.XmlPipe} to create a communication channel between
    the initializer and the stubbed receiving entity. It features a sink and
    source side that both act similarly to a real L{xmlstream.XmlStream}. The
    sink is augmented with an authenticator to which initializers can be added.

    The harness also provides some utility methods to work with event observers
    and deferreds.
    c                 C   s4   g | _ t ¡ | _| jj| _t d¡| _| j| j_d S )Nzexample.org)Úoutputr   ZXmlPipeÚpipeZsinkr   ZConnectAuthenticatorÚauthenticatorr   r   r   r   r   H   s
    

z"InitiatingInitializerHarness.setUpc                 C   s(   t  ¡ }| |¡ | jj ||j¡ |S )aù  
        Observe an output event, returning a deferred.

        The returned deferred will be fired when the given event has been
        observed on the source end of the L{XmlPipe} tied to the protocol
        under test. The handler is added as the first callback.

        @param event: The event to be observed. See
            L{utility.EventDispatcher.addOnetimeObserver}.
        @param handler: The handler to be called with the observed event object.
        @rtype: L{defer.Deferred}.
        )r   ZDeferredÚaddCallbackr%   ÚsourceZaddOnetimeObserverÚcallback)r   ZeventZhandlerÚdr   r   r   ÚwaitForP   s    
z$InitiatingInitializerHarness.waitForN)r    r!   r"   Ú__doc__r   r+   r   r   r   r   r#   ;   s   r#   c                       s@   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡  Z	S )ÚIQAuthInitializerTestsz0
    Tests for L{client.IQAuthInitializer}.
    c                    s6   t t| ƒ ¡  t | j¡| _t d¡| j	_d| j	_
d S )Núuser@example.com/resourceÚsecret)Úsuperr-   r   r   ÚIQAuthInitializerr   r   r
   ÚJIDr&   Úpasswordr   ©Ú	__class__r   r   r   i   s    zIQAuthInitializerTests.setUpc                    s>   ‡ ‡fdd„}‡fdd„‰ ˆ  t|¡}ˆj ¡ }t ||g¡S )zè
        Test plain-text authentication.

        Act as a server supporting plain-text authentication and expect the
        C{password} field to be filled with the password. Then act as if
        authentication succeeds.
        c                    sX   t  | d¡}| d¡ |j d¡ |j d¡ |j d¡ ˆ tˆ ¡}ˆjj |¡ |S ©zÄ
            Called when the initializer sent a query for authentication methods.

            The response informs the client that plain-text authentication
            is supported.
            Úresult©zjabber:iq:authÚqueryÚusernamer3   Úresource©	r   Ú
toResponseÚ
addElementr9   r+   ÚIQ_AUTH_SETr%   r(   Úsend©ÚiqÚresponser*   ©Ú	onAuthSetr   r   r   Ú	onAuthGety   s    	
z7IQAuthInitializerTests.testPlainText.<locals>.onAuthGetc                    sZ   ˆ   dt| jjƒ¡ ˆ   dt| jjƒ¡ ˆ   dt| jjƒ¡ t | d¡}ˆ jj	 
|¡ dS )úÇ
            Called when the initializer sent the authentication request.

            The server checks the credentials and responds with an empty result
            signalling success.
            Úuserr/   r;   r7   N)r   r   r9   r:   r3   r;   r   r=   r%   r(   r@   ©rB   rC   r   r   r   rE      s
    z7IQAuthInitializerTests.testPlainText.<locals>.onAuthSet)r+   ÚIQ_AUTH_GETr   r   r   ÚgatherResults©r   rF   Úd1Úd2r   rD   r   ÚtestPlainTextp   s
    	
z$IQAuthInitializerTests.testPlainTextc                    sF   ‡ ‡fdd„}‡fdd„‰ dˆj _ˆ t|¡}ˆj ¡ }t ||g¡S )a"  
        Test digest authentication.

        Act as a server supporting digest authentication and expect the
        C{digest} field to be filled with a sha1 digest of the concatenated
        stream session identifier and password. Then act as if authentication
        succeeds.
        c                    sX   t  | d¡}| d¡ |j d¡ |j d¡ |j d¡ ˆ tˆ ¡}ˆjj |¡ |S )zÀ
            Called when the initializer sent a query for authentication methods.

            The response informs the client that digest authentication is
            supported.
            r7   r8   r:   Údigestr;   r<   rA   rD   r   r   rF   ±   s    	
z4IQAuthInitializerTests.testDigest.<locals>.onAuthGetc                    sb   ˆ   dt| jjƒ¡ ˆ   tdƒ ¡ t| jjƒ¡ ˆ   dt| jjƒ¡ t 	| d¡}ˆ j
j |¡ dS )rG   rH   s   12345secretr;   r7   N)r   r   r9   r:   r   Z	hexdigestrP   r;   r   r=   r%   r(   r@   rI   r   r   r   rE   È   s    
ÿz4IQAuthInitializerTests.testDigest.<locals>.onAuthSetZ12345)r   Zsidr+   rJ   r   r   r   rK   rL   r   rD   r   Ú
testDigest§   s    

z!IQAuthInitializerTests.testDigestc                    s>   ‡ fdd„}ˆ   t|¡}ˆ j ¡ }ˆ  |tj¡ t ||g¡S )zT
        Test initializer failure of request for fields for authentication.
        c                    s"   t  d¡ | ¡}ˆ jj |¡ dS )z²
            Called when the initializer sent a query for authentication methods.

            The server responds that the client is not authorized to authenticate.
            únot-authorizedN©r	   ÚStanzaErrorr=   r%   r(   r@   rI   r   r   r   rF   è   s    z?IQAuthInitializerTests.testFailRequestFields.<locals>.onAuthGet©	r+   rJ   r   r   ÚassertFailurer	   rT   r   rK   rL   r   r   r   ÚtestFailRequestFieldsä   s
    

z,IQAuthInitializerTests.testFailRequestFieldsc                    sL   ‡ ‡fdd„}‡fdd„‰ ˆ  t|¡}ˆj ¡ }ˆ |tj¡ t ||g¡S )z;
        Test initializer failure to authenticate.
        c                    sX   t  | d¡}| d¡ |j d¡ |j d¡ |j d¡ ˆ tˆ ¡}ˆjj |¡ |S r6   r<   rA   rD   r   r   rF     s    	
z6IQAuthInitializerTests.testFailAuth.<locals>.onAuthGetc                    s"   t  d¡ | ¡}ˆ jj |¡ dS )zÂ
            Called when the initializer sent the authentication request.

            The server checks the credentials and responds with a not-authorized
            stanza error.
            rR   NrS   rI   r   r   r   rE     s    z6IQAuthInitializerTests.testFailAuth.<locals>.onAuthSetrU   rL   r   rD   r   ÚtestFailAuthý   s    
z#IQAuthInitializerTests.testFailAuth)
r    r!   r"   r,   r   rO   rQ   rW   rX   Ú__classcell__r   r   r4   r   r-   d   s   7=r-   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚBindInitializerTestsz.
    Tests for L{client.BindInitializer}.
    c                    s.   t t| ƒ ¡  t | j¡| _t d¡| j	_d S )Nr.   )
r0   rZ   r   r   ÚBindInitializerr   r   r
   r2   r&   r   r4   r   r   r   5  s    zBindInitializerTests.setUpc                    sF   ‡ fdd„}‡ fdd„}ˆ   t|¡}ˆ j ¡ }| |¡ t ||g¡S )zK
        Set up a stream, and act as if resource binding succeeds.
        c                    s<   t  | d¡}| tdf¡ |jjddd ˆ jj |¡ d S )Nr7   Úbindr
   úuser@example.com/other resource)Zcontent)r   r=   r>   ÚNS_BINDr\   r%   r(   r@   rI   r   r   r   ÚonBind?  s    ÿz.BindInitializerTests.testBasic.<locals>.onBindc                    s   ˆ   t d¡ˆ jj¡ d S )Nr]   )r   r
   r2   r&   )r7   r   r   r   ÚcbF  s    ÿz*BindInitializerTests.testBasic.<locals>.cb)r+   ÚIQ_BIND_SETr   Ústartr'   r   rK   )r   r_   r`   rM   rN   r   r   r   Ú	testBasic;  s    

zBindInitializerTests.testBasicc                    s>   ‡ fdd„}ˆ   t|¡}ˆ j ¡ }ˆ  |tj¡ t ||g¡S )zH
        Set up a stream, and act as if resource binding fails.
        c                    s"   t  d¡ | ¡}ˆ jj |¡ d S )NZconflictrS   rI   r   r   r   r_   T  s    z0BindInitializerTests.testFailure.<locals>.onBind)	r+   ra   r   rb   rV   r	   rT   r   rK   )r   r_   rM   rN   r   r   r   ÚtestFailureP  s
    
z BindInitializerTests.testFailure)r    r!   r"   r,   r   rc   rd   rY   r   r   r4   r   rZ   0  s   rZ   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚSessionInitializerTestsz1
    Tests for L{client.SessionInitializer}.
    c                    s    t t| ƒ ¡  t | j¡| _d S r   )r0   re   r   r   ÚSessionInitializerr   r   r   r4   r   r   r   d  s    zSessionInitializerTests.setUpc                    s0   ‡ fdd„}ˆ   t|¡}ˆ j ¡ }t ||g¡S )zP
        Set up a stream, and act as if session establishment succeeds.
        c                    s   t  | d¡}ˆ jj |¡ d S )Nr7   )r   r=   r%   r(   r@   rI   r   r   r   Ú	onSessionn  s    z6SessionInitializerTests.testSuccess.<locals>.onSession)r+   ÚIQ_SESSION_SETr   rb   r   rK   ©r   rg   rM   rN   r   r   r   ÚtestSuccessi  s    
z#SessionInitializerTests.testSuccessc                    s>   ‡ fdd„}ˆ   t|¡}ˆ j ¡ }ˆ  |tj¡ t ||g¡S )zM
        Set up a stream, and act as if session establishment fails.
        c                    s"   t  d¡ | ¡}ˆ jj |¡ d S )NZ	forbiddenrS   rI   r   r   r   rg   {  s    z6SessionInitializerTests.testFailure.<locals>.onSession)	r+   rh   r   rb   rV   r	   rT   r   rK   ri   r   r   r   rd   w  s
    
z#SessionInitializerTests.testFailure)r    r!   r"   r,   r   rj   rd   rY   r   r   r4   r   re   _  s   re   c                   @   s   e Zd ZdZdd„ ZdS )ÚBasicAuthenticatorTestszB
    Test for both BasicAuthenticator and basicClientFactory.
    c                 C   sˆ   t  d¡| _t | jd¡ d¡}|  d|jj¡ |  | j|jj ¡ |  d|jj	¡ |j
\}}|  |tj¡ |  |tj¡ |  |j¡ dS )a  
        Authenticator and stream are properly constructed by the factory.

        The L{xmlstream.XmlStream} protocol created by the factory has the new
        L{client.BasicAuthenticator} instance in its C{authenticator}
        attribute.  It is set up with C{jid} and C{password} as passed to the
        factory, C{otherHost} taken from the client JID. The stream futher has
        two initializers, for TLS and authentication, of which the first has
        its C{required} attribute set to C{True}.
        r.   r/   Núexample.com)r
   r2   Ú
client_jidr   ZbasicClientFactoryÚbuildProtocolr   r&   Ú	otherHostr3   ÚinitializersÚassertIsInstancer   ÚTLSInitiatingInitializerr1   ÚassertFalseÚrequired)r   r   ÚtlsZauthr   r   r   Ú
test_basic‹  s    ÿÿ
z"BasicAuthenticatorTests.test_basicN)r    r!   r"   r,   rv   r   r   r   r   rk   †  s   rk   c                   @   s&   e Zd ZdZdd„ Zdd„ Zee_dS )ÚXMPPAuthenticatorTestsz@
    Test for both XMPPAuthenticator and XMPPClientFactory.
    c                 C   sÌ   t  d¡| _t | jd¡ d¡}|  d|jj¡ |  | j|jj ¡ |  d|jj	¡ |j
\}}}}}|  |tj¡ |  |t¡ |  |tj¡ |  |tj¡ |  |j¡ |  |j¡ |  |j¡ |  |j¡ dS )zú
        Test basic operations.

        Setup an XMPPClientFactory, which sets up an XMPPAuthenticator, and let
        it produce a protocol instance. Then inspect the instance variables of
        the authenticator and XML stream objects.
        r.   r/   Nrl   )r
   r2   rm   r   ÚXMPPClientFactoryrn   r   r&   ro   r3   rp   rq   r   rr   r   r[   rf   Z
assertTruert   rs   )r   r   r   ru   Úsaslr\   Úsessionr   r   r   rv   ²  s$    ÿÿz!XMPPAuthenticatorTests.test_basicc           
         s„   g ‰ d
‡ fdd„	}t  d¡| _t ¡ }tj| jd|d}|  tj	d|¡ | 
d¡}|j\}}}}}	|  |tj	¡ |  |ˆ d	 ¡ dS )zG
        A TLS configuration is passed to the TLS initializer.
        TNc                    s   ˆ   |¡ d S r   )Úappend)r   r   rt   ÚconfigurationForTLS©Zconfigsr   r   r   Û  s    z:XMPPAuthenticatorTests.test_tlsConfiguration.<locals>.initr.   r/   )r|   Ú__init__r   )TN)r
   r2   rm   r   ZCertificateOptionsr   rx   Zpatchr   rr   rn   rp   rq   ZassertIs)
r   r   r|   Úfactoryr   r   ru   ry   r\   rz   r   r}   r   Útest_tlsConfigurationÕ  s     þ
z,XMPPAuthenticatorTests.test_tlsConfigurationN)r    r!   r"   r,   rv   r€   ÚskipWhenNoSSLÚskipr   r   r   r   rw   ­  s   #rw   )'r,   Z
__future__r   r   Zhashlibr   Ztwisted.internetr   Ztwisted.python.compatr   Ztwisted.trialr   Ztwisted.words.protocols.jabberr   r	   r
   r   Z#twisted.words.protocols.jabber.saslr   Ztwisted.words.xishr   r   ÚImportErrorr   rJ   r?   r^   ra   Z
NS_SESSIONrh   ZTestCaser   Úobjectr#   r-   rZ   re   rk   rw   r   r   r   r   Ú<module>   s8   
) M/''