o
    ˷e$                     @   s   d dl Z d dl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 eeZi Zd	d
 ZG dd deZdd Zdd Zdd Zdd ZdS )    N)bytes)RemovedInDjangoSES20Warning)urlparse)urlopen)URLError)ImproperlyConfigured)settingsc                   C   s   t   dS )zClear the certificate cache.

    This one-liner exists to discourage imports and direct usage of
    _CERT_CACHE.

    :returns None
    N)_CERT_CACHEclear r   r   G/var/www/ideatree/venv/lib/python3.10/site-packages/django_ses/utils.pyclear_cert_cache   s   r   c                   @   s@   e Zd ZdZdZdd Zdd Zedd Zd	d
 Z	dd Z
dS )EventMessageVerifierz
    A utility class for validating event messages

    See: http://docs.amazonwebservices.com/sns/latest/gsg/SendMessageToHttp.verify.signature.html
    z%s is required for event message verification. Please install `django-ses` with the `event` extra - e.g. `pip install django-ses[events]`.c                 C   s   || _ d| _dS )zB
        Creates a new event message from the given dict.
        N)_data	_verified)selfnotificationr   r   r   __init__,   s   
zEventMessageVerifier.__init__c              	   C   s  | j dur| j S | jd}|sd| _ | j S tt|}|  }|s)d| _ | j S | js2d| _ | j S zddlm	} ddl
m} ddlm} W n tyT   t| jd w | j }z|||| |  W n |y   td	| jd
 d| _ Y | j S w d| _ | j S )z
        Verifies an SES event message.

        Sign the bytes from the notification and compare it to the signature in
        the notification. If same, return True; else False.
        N	SignatureFr   )InvalidSignature)hashes)padding`cryptography`z(Invalid signature on message with ID: %s	MessageIdT)r   r   getr   base64	b64decode_get_bytes_to_signcertificatecryptography.exceptionsr   cryptography.hazmat.primitivesr   )cryptography.hazmat.primitives.asymmetricr   ImportErrorr   _REQ_DEP_TMPL
public_keyverifyPKCS1v15SHA1loggerwarning)r   	signature
sign_bytesr   r   r   pkeyr   r   r   is_verified3   sN   


z EventMessageVerifier.is_verifiedc              
   C   s>  |   }|sdS |tv rt| S zddl}ddlm} W n ty*   t| jd w zddlm} W n tyA   t| jd w z|j	|dd}|
  W n! |yp } ztd	|| dt|< t| W  Y d}~S d}~ww z||jt|< W t| S  ty } ztd
|| dt|< W Y d}~t| S d}~ww )z
        Retrieves the certificate used to sign the event message.

        :returns: None if the cert cannot be retrieved. Else, gets the cert
        caches it, and returns it, or simply returns it if already cached.
        Nr   )RequestExceptionz
`requests`)x509r   
   )timeoutz1Network error downloading certificate from %s: %sz(Could not load certificate from %s: "%s")_get_cert_urlr	   requestsr.   r"   r   r#   cryptographyr/   r   raise_for_statusr(   r)   load_pem_x509_certificatecontent
ValueError)r   cert_urlr3   r.   r/   responseexcer   r   r   r   n   sL   z EventMessageVerifier.certificatec                 C   s   | j d}|std| dS |dstd| dS t|}tjD ]}|d}|j	dt
| d |kr>|  S q$dS )a'  
        Get the signing certificate URL.
        Only accept urls that match the domains set in the
        AWS_SNS_EVENT_CERT_TRUSTED_DOMAINS setting. Sub-domains
        are allowed. i.e. if amazonaws.com is in the trusted domains
        then sns.us-east-1.amazonaws.com will match.
        SigningCertURLz No signing certificate URL: "%s"Nzhttps://zUntrusted certificate URL: "%s".)r   r   r(   r)   
startswithr   r   EVENT_CERT_DOMAINSsplitnetloclen)r   r9   url_objtrusted_domainpartsr   r   r   r2      s   


z"EventMessageVerifier._get_cert_urlc                 C   s   | j d}|dkrg d}n|dks|dkrg d}ntd| dS g }|D ]}| j |}|s3q(|| d	| d	 q(d
| S )z
        Creates the message used for signing SNS notifications.
        This is used to verify the bounce message when it is received.
        TypeNotification)Messager   Subject	TimestampTopicArnrG   SubscriptionConfirmationUnsubscribeConfirmation)rI   r   SubscribeURLrK   TokenrL   rG   z#Unrecognized SNS message Type: "%s"N
 )r   r   r(   r)   appendjoinencode)r   msg_typefields_to_signbytes_to_signfieldfield_valuer   r   r   r      s   

z'EventMessageVerifier._get_bytes_to_signN)__name__
__module____qualname____doc__r#   r   r-   propertyr   r2   r   r   r   r   r   r      s    ;
7r   c                  O   s4   t dt d|v r|d |d< |d= t| i |S )NzQutils.BounceMessageVerifier is deprecated. It is renamed to EventMessageVerifier.bounce_dictr   )warningswarnr   r   )argskwargsr   r   r   BounceMessageVerifier   s   re   c                 C   s   t | }| S )z7
    Verify an SES/SNS event notification message.
    )r   r-   )r   verifierr   r   r   verify_event_message   s   rg   c                 C   s   t dt t| S )z?
    Verify an SES/SNS bounce(event) notification message.
    zQutils.verify_bounce_message is deprecated. It is renamed to verify_event_message.)ra   rb   r   rg   )msgr   r   r   verify_bounce_message  s
   ri   c              
   C   st   t jd| dd| id | d}z	t|  W d S  ty9 } zt jd|d| idd W Y d }~d S d }~ww )	Nz0Received subscription confirmation: TopicArn: %srL   r   )extrarO   z$Could not confirm subscription: "%s"T)rj   exc_info)r(   infor   r   readr   error)r   subscribe_urlr<   r   r   r   confirm_sns_subscription  s$   
	rp   )r   loggingra   builtinsr   django_ses.deprecationr   urllib.parser   urllib.requestr   urllib.errorr   django.core.exceptionsr   
django_sesr   	getLoggerr[   r(   r	   r   objectr   re   rg   ri   rp   r   r   r   r   <module>   s&    
 P