U
    ˆj@1  ã                   @  s  d 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 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 er”ddlmZ eejƒG dd„ dƒƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZG dd„ deƒZG dd„ dej ƒZ!G dd„ dej"ƒZ#dS )z
Mail protocol support.
é    )Úannotations)ÚTYPE_CHECKINGÚCallable)Úimplementer)Úlongversion)ÚCramMD5CredentialsÚUsernamePassword)ÚUnauthorizedLogin)ÚdeferÚprotocol)Úpop3ÚrelayÚsmtp)Úlog)ÚMailServicec                   @  sH   e Zd ZU dZdZdZded< ejfdd„Z	dd	„ Z
d
d„ Zdd„ ZdS )ÚDomainDeliveryBaseaN  
    A base class for message delivery using the domains of a mail service.

    @ivar service: See L{__init__}
    @ivar user: See L{__init__}
    @ivar host: See L{__init__}

    @type protocolName: L{bytes}
    @ivar protocolName: The protocol being used to deliver the mail.
        Sub-classes should set this appropriately.
    Ns   not-implemented-protocolÚbytesÚprotocolNamec                 C  s   || _ || _|| _dS )zó
        @type service: L{MailService}
        @param service: A mail service.

        @type user: L{bytes} or L{None}
        @param user: The authenticated SMTP user.

        @type host: L{bytes}
        @param host: The hostname.
        N)ÚserviceÚuserÚhost)Úselfr   r   r   © r   ú:/tmp/pip-unpacked-wheel-j5h_c8_q/twisted/mail/protocols.pyÚ__init__*   s    zDomainDeliveryBase.__init__c           	      C  s´   d }}| j rd| j  d¡ }|d r2d|d  }d|d  d |d  d	 | | }d
| j d | j d t d¡ d }dd tt|ƒ¡ d t 	¡  }d| d | d | S )aû  
        Generate a received header string for a message.

        @type helo: 2-L{tuple} of (L{bytes}, L{bytes})
        @param helo: The client's identity as sent in the HELO command and its
            IP address.

        @type origin: L{Address}
        @param origin: The origination address of the message.

        @type recipients: L{list} of L{User}
        @param recipients: The destination addresses for the message.

        @rtype: L{bytes}
        @return: A received header string.
        ó    s    auth=Zxtextr   s    helo=s   from s    ([é   ó   ]s   by s    with s    (Úasciió   )s   for <ó    s   > s
   Received: s   
	)
r   Úencoder   r   r   ÚjoinÚmapr   r   Z
rfc822date)	r   ÚheloÚoriginZ
recipientsZauthStrZheloStrZfromUserZbyZforUserr   r   r   ÚreceivedHeader9   s.    $ÿþýüûúÿ
ÿz!DomainDeliveryBase.receivedHeaderc                 C  sX   | j r:| jjr:| jj |jjd¡}|dkrJt | jd¡}n| jj|jj }t	 
|j|¡S )a9  
        Validate the address for which a message is destined.

        @type user: L{User}
        @param user: The destination address.

        @rtype: L{Deferred <defer.Deferred>} which successfully fires with
            no-argument callable which returns L{IMessage <smtp.IMessage>}
            provider.
        @return: A deferred which successfully fires with a no-argument
            callable which returns a message receiver for the destination.

        @raise SMTPBadRcpt: When messages cannot be accepted for the
            destination address.
        NT)r   r   ÚqueueÚdomainsÚgetÚdestÚdomainr   ZDomainQueuerr
   ZmaybeDeferredÚexists)r   r   Údr   r   r   Ú
validateTo^   s    zDomainDeliveryBase.validateToc                 C  s8   |st  |dd¡‚|jdkr4|jdkr4t  |dd¡‚|S )a÷  
        Validate the address from which a message originates.

        @type helo: 2-L{tuple} of (L{bytes}, L{bytes})
        @param helo: The client's identity as sent in the HELO command and its
            IP address.

        @type origin: L{Address}
        @param origin: The origination address of the message.

        @rtype: L{Address}
        @return: The origination address.

        @raise SMTPBadSender: When messages cannot be accepted from the
            origination address.
        i÷  zWho are you?  Say HELO first.r   iõ  z#Sender address must contain domain.)r   ZSMTPBadSenderÚlocalr+   )r   r$   r%   r   r   r   ÚvalidateFromw   s
    zDomainDeliveryBase.validateFrom)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú__annotations__r   ZDNSNAMEr   r&   r.   r0   r   r   r   r   r      s   
%r   c                   @  s   e Zd ZdZdZdS )ÚSMTPDomainDeliveryzA
    A domain delivery base class for use in an SMTP server.
    s   smtpN©r1   r2   r3   r4   r   r   r   r   r   r6   �   s   r6   c                   @  s   e Zd ZdZdZdS )ÚESMTPDomainDeliveryzB
    A domain delivery base class for use in an ESMTP server.
    s   esmtpNr7   r   r   r   r   r8   —   s   r8   c                   @  s,   e Zd ZdZejZdZddd„Zdd„ Z	dS )ÚSMTPFactorya;  
    An SMTP server protocol factory.

    @ivar service: See L{__init__}
    @ivar portal: See L{__init__}

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{SMTP}.
    Nc                 C  s   t j | ¡ || _|| _dS )zé
        @type service: L{MailService}
        @param service: An email service.

        @type portal: L{Portal <twisted.cred.portal.Portal>} or
            L{None}
        @param portal: A portal to use for authentication.
        N)r   r9   r   r   Úportal)r   r   r:   r   r   r   r   ¯   s    	zSMTPFactory.__init__c                 C  s2   t  d|› �¡ tj | |¡}| j|_| j|_|S )a  
        Create an instance of an SMTP server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the SMTP client.

        @rtype: L{SMTP}
        @return: An SMTP protocol.
        zConnection from )r   Úmsgr   r9   ÚbuildProtocolr   r:   ©r   ÚaddrÚpr   r   r   r<   ¼   s
    
zSMTPFactory.buildProtocol)N)
r1   r2   r3   r4   r   ÚSMTPr   r:   r   r<   r   r   r   r   r9   Ÿ   s
   
r9   c                   @  s*   e Zd ZdZejZdZdd„ Zdd„ Z	dS )ÚESMTPFactorya  
    An ESMTP server protocol factory.

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{ESMTP}.

    @type context: L{IOpenSSLContextFactory
        <twisted.internet.interfaces.IOpenSSLContextFactory>} or L{None}
    @ivar context: A factory to generate contexts to be used in negotiating
        encrypted communication.

    @type challengers: L{dict} mapping L{bytes} to no-argument callable which
        returns L{ICredentials <twisted.cred.credentials.ICredentials>}
        subclass provider.
    @ivar challengers: A mapping of acceptable authorization mechanism to
        callable which creates credentials to use for authentication.
    Nc                 G  s   t j| f|žŽ  dti| _dS )zk
        @param args: Arguments for L{SMTPFactory.__init__}

        @see: L{SMTPFactory.__init__}
        s   CRAM-MD5N)r9   r   r   Úchallengers)r   Úargsr   r   r   r   å   s    zESMTPFactory.__init__c                 C  s    t  | |¡}| j|_| j|_|S )a  
        Create an instance of an ESMTP server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the ESMTP client.

        @rtype: L{ESMTP}
        @return: An ESMTP protocol.
        )r9   r<   rB   ÚcontextÚctxr=   r   r   r   r<   î   s    
zESMTPFactory.buildProtocol)
r1   r2   r3   r4   r   ZESMTPr   rD   r   r<   r   r   r   r   rA   Í   s
   	rA   c                   @  sT   e Zd ZU dZdZded< dZded< dd	„ Zddd
dœdd„Zdddœdd„Z	dS )ÚVirtualPOP3a  
    A virtual hosting POP3 server.

    @ivar service: The email service that created this server.  This must be
        set by the service.

    @ivar domainSpecifier: The character to use to split an email address into
        local-part and domain. The default is '@'.
    NzMailService | Noner   ó   @r   ÚdomainSpecifierc                 C  s`   |   |¡\}}z| j |¡}W n  tk
r>   t tƒ ¡ Y S X | t 	| j
||¡dtj¡S dS )a1  
        Perform APOP authentication.

        Override the default lookup scheme to allow virtual domains.

        @type user: L{bytes}
        @param user: The name of the user attempting to log in.

        @type digest: L{bytes}
        @param digest: The challenge response.

        @rtype: L{Deferred} which successfully results in 3-L{tuple} of
            (L{IMailbox <pop3.IMailbox>}, L{IMailbox <pop3.IMailbox>}
            provider, no-argument callable)
        @return: A deferred which fires when authentication is complete.
            If successful, it returns an L{IMailbox <pop3.IMailbox>} interface,
            a mailbox and a logout function. If authentication fails, the
            deferred fails with an L{UnauthorizedLogin
            <twisted.cred.error.UnauthorizedLogin>} error.
        N)ÚlookupDomainr   ÚlookupPortalÚKeyErrorr
   Úfailr	   Úloginr   ZAPOPCredentialsÚmagicÚIMailbox)r   r   Údigestr+   r:   r   r   r   ÚauthenticateUserAPOP  s      ÿz VirtualPOP3.authenticateUserAPOPzMdefer.Deferred[tuple[type[pop3.IMailbox], pop3.IMailbox, Callable[[], None]]])r   ÚpasswordÚreturnc                 C  sp   |   |¡\}}| jdk	s tdƒ‚z| j |¡}W n  tk
rP   t tƒ ¡ Y S X | t	||ƒdt
j¡}|S dS )aa  
        Perform authentication for a username/password login.

        Override the default lookup scheme to allow virtual domains.

        @param user: The name of the user attempting to log in.

        @param password: The password to authenticate with.

        @return: A deferred which fires when authentication is complete.
            If successful, it returns an L{IMailbox <pop3.IMailbox>} interface,
            a mailbox and a logout function. If authentication fails, the
            deferred fails with an L{UnauthorizedLogin
            <twisted.cred.error.UnauthorizedLogin>} error.
        Nz.must have a service to be able to authenticate)rI   r   ÚAssertionErrorrJ   rK   r
   rL   r	   rM   r   r   rO   )r   r   rR   r+   r:   Úresultr   r   r   ÚauthenticateUserPASS.  s    ÿþþz VirtualPOP3.authenticateUserPASSztuple[bytes, bytes])r   rS   c                 C  sl   z|  | jd¡\}}W n tk
r.   d}Y nX | jdk	sBtdƒ‚|| jjkrdt d | 	d¡¡¡‚||fS )a{  
        Check whether a domain part of the given email address is among the
        virtual domains supported by the mail service.

        @param user: An email address.

        @return: a 2-tuple of (local part, domain part) of the email address if
            the domain is supported.

        @raise POP3Error: When the domain is not supported by the mail service.
        r   r   Nz(cannot look up domain if service not setzno such domain {}zutf-8)
ÚsplitrH   Ú
ValueErrorr   rT   r(   r   Z	POP3ErrorÚformatÚdecode)r   r   r+   r   r   r   rI   N  s    
zVirtualPOP3.lookupDomain)
r1   r2   r3   r4   r   r5   rH   rQ   rV   rI   r   r   r   r   rF   þ   s   

 rF   c                   @  s(   e Zd ZdZeZdZdd„ Zdd„ ZdS )ÚPOP3Factorya  
    A POP3 server protocol factory.

    @ivar service: See L{__init__}

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{VirtualPOP3}.
    Nc                 C  s
   || _ dS )zY
        @type service: L{MailService}
        @param service: An email service.
        N)r   )r   r   r   r   r   r   s  s    zPOP3Factory.__init__c                 C  s   t j | |¡}| j|_|S )a   
        Create an instance of a POP3 server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the POP3 client.

        @rtype: L{POP3}
        @return: A POP3 protocol.
        )r   ÚServerFactoryr<   r   r=   r   r   r   r<   z  s    
zPOP3Factory.buildProtocol)	r1   r2   r3   r4   rF   r   r   r   r<   r   r   r   r   r[   d  s
   r[   N)$r4   Ú
__future__r   Útypingr   r   Zzope.interfacer   Ztwisted.copyrightr   Ztwisted.cred.credentialsr   r   Ztwisted.cred.errorr	   Ztwisted.internetr
   r   Ztwisted.mailr   r   r   Ztwisted.pythonr   Ztwisted.mail.mailr   ZIMessageDeliveryr   r6   r8   r9   rA   ZPOP3rF   r\   r[   r   r   r   r   Ú<module>   s&   u.1f