U
    n5{i£@  ã                   @   s:  d 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ƒ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}
é    )Úsha1)ÚskipIf)Údefer)Úunittest)ÚclientÚerrorÚjidÚ	xmlstream)ÚSASLInitiatingInitializer)Úutility)ÚsslN)TzSSL not available)FÚ z//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   úH/tmp/pip-unpacked-wheel-mnhg7r0q/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   ÚassertRaisesr   ÚStreamErrorr   ÚassertEqualÚ	condition)r   Úexcr   r   r   ÚtestNotSupported/   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   E   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   ÚeventÚhandlerÚdr   r   r   ÚwaitForL   s    
z$InitiatingInitializerHarness.waitForN)r"   r#   r$   Ú__doc__r   r/   r   r   r   r   r%   8   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                    s2   t ƒ  ¡  t | j¡| _t d¡| j_d| j_	d S )Núuser@example.com/resourceÚsecret)
Úsuperr   r   ÚIQAuthInitializerr	   r   r   ÚJIDr(   Úpasswordr   ©Ú	__class__r   r   r   d   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Úusernamer7   Úresource©	r	   Ú
toResponseÚ
addElementr=   r/   ÚIQ_AUTH_SETr'   r*   Úsend©ÚiqÚresponser.   ©Ú	onAuthSetr   r   r   Ú	onAuthGets   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.
            Úuserr3   r?   r;   N)r   Ústrr=   r>   r7   r?   r	   rA   r'   r*   rD   ©rF   rG   r   r   r   rI   Š   s
    z7IQAuthInitializerTests.testPlainText.<locals>.onAuthSet)r/   ÚIQ_AUTH_GETr   r   r   ÚgatherResults©r   rJ   Úd1Úd2r   rH   r   ÚtestPlainTextj   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.
            r;   r<   r>   Údigestr?   r@   rE   rH   r   r   rJ   ª   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 )rK   rL   s   12345secretr?   r;   N)r   rM   r=   r>   r   Ú	hexdigestrU   r?   r	   rA   r'   r*   rD   rN   r   r   r   rI   Á   s
    z4IQAuthInitializerTests.testDigest.<locals>.onAuthSetZ12345)r	   Zsidr/   rO   r   r   r   rP   rQ   r   rH   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   ÚStanzaErrorrA   r'   r*   rD   rN   r   r   r   rJ   à   s    z?IQAuthInitializerTests.testFailRequestFields.<locals>.onAuthGet©	r/   rO   r   r   ÚassertFailurer   rZ   r   rP   rQ   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 r:   r@   rE   rH   r   r   rJ   ù   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.
            rX   NrY   rN   r   r   r   rI     s    z6IQAuthInitializerTests.testFailAuth.<locals>.onAuthSetr[   rQ   r   rH   r   ÚtestFailAuthô   s    
z#IQAuthInitializerTests.testFailAuth)
r"   r#   r$   r0   r   rT   rW   r]   r^   Ú__classcell__r   r   r8   r   r1   _   s   6;r1   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 | j¡| _t d¡| j_d S )Nr2   )	r4   r   r   ÚBindInitializerr	   r   r   r6   r(   r   r8   r   r   r   +  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 )Nr;   Úbindr   úuser@example.com/other resource)Úcontent)r	   rA   rB   ÚNS_BINDrb   r'   r*   rD   rN   r   r   r   ÚonBind5  s    z.BindInitializerTests.testBasic.<locals>.onBindc                    s   ˆ   t d¡ˆ jj¡ d S )Nrc   )r   r   r6   r(   )r;   r   r   r   Úcb;  s     ÿz*BindInitializerTests.testBasic.<locals>.cb)r/   ÚIQ_BIND_SETr   Ústartr)   r   rP   )r   rf   rg   rR   rS   r   r   r   Ú	testBasic0  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 )NÚconflictrY   rN   r   r   r   rf   J  s    z0BindInitializerTests.testFailure.<locals>.onBind)	r/   rh   r   ri   r\   r   rZ   r   rP   )r   rf   rR   rS   r   r   r   ÚtestFailureE  s
    
z BindInitializerTests.testFailure)r"   r#   r$   r0   r   rj   rl   r_   r   r   r8   r   r`   &  s   r`   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 | j¡| _d S r   )r4   r   r   ÚSessionInitializerr	   r   r   r8   r   r   r   Y  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 )Nr;   )r	   rA   r'   r*   rD   rN   r   r   r   Ú	onSessionb  s    z6SessionInitializerTests.testSuccess.<locals>.onSession)r/   ÚIQ_SESSION_SETr   ri   r   rP   ©r   ro   rR   rS   r   r   r   ÚtestSuccess]  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 )NÚ	forbiddenrY   rN   r   r   r   ro   o  s    z6SessionInitializerTests.testFailure.<locals>.onSession)	r/   rp   r   ri   r\   r   rZ   r   rP   rq   r   r   r   rl   j  s
    
z#SessionInitializerTests.testFailure)r"   r#   r$   r0   r   rr   rl   r_   r   r   r8   r   rm   T  s   rm   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}.
        r2   r3   Núexample.com)r   r6   Ú
client_jidr   ZbasicClientFactoryÚbuildProtocolr   r(   Ú	otherHostr7   ÚinitializersÚassertIsInstancer	   ÚTLSInitiatingInitializerr5   ÚassertFalseÚrequired)r   r   ÚtlsÚauthr   r   r   Ú
test_basic~  s    
z"BasicAuthenticatorTests.test_basicN)r"   r#   r$   r0   r€   r   r   r   r   rt   y  s   rt   c                   @   s(   e Zd ZdZdd„ ZeeŽ dd„ ƒZ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.
        r2   r3   Nru   )r   r6   rv   r   ÚXMPPClientFactoryrw   r   r(   rx   r7   ry   rz   r	   r{   r
   ra   rn   Ú
assertTruer}   r|   )r   r   r   r~   Úsaslrb   Úsessionr   r   r   r€   £  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   r}   ÚconfigurationForTLS©Zconfigsr   r   r   Ë  s    z:XMPPAuthenticatorTests.test_tlsConfiguration.<locals>.initr2   r3   )r‡   Ú__init__r   )TN)r   r6   rv   r   ZCertificateOptionsr   r‚   Úpatchr	   r{   rw   ry   rz   ZassertIs)
r   r   r‡   Úfactoryr   r   r~   r„   rb   r…   r   rˆ   r   Útest_tlsConfigurationÄ  s      ÿ
z,XMPPAuthenticatorTests.test_tlsConfigurationN)r"   r#   r$   r0   r€   r   ÚskipWhenNoSSLrŒ   r   r   r   r   r�   ž  s   !r�   )"r0   Úhashlibr   r   r   Ztwisted.internetr   Ztwisted.trialZtwisted.words.protocols.jabberr   r   r   r	   Z#twisted.words.protocols.jabber.saslr
   Ztwisted.words.xishr   r   ÚImportErrorr�   rO   rC   re   rh   Z
NS_SESSIONrp   ZTestCaser   r%   r1   r`   rm   rt   r�   r   r   r   r   Ú<module>   s6   
' H.%%