U
    ~fh                     @  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 ddlmZ e	rhddlmZmZ d	d
dddZd	d
dddZG dd dZdS )z%Utilities for caching OCSP responses.    )annotations)
namedtuple)datetime)timezone)TYPE_CHECKINGAnyOptional)_create_lock)OCSPRequestOCSPResponser   zOptional[_datetime])valuereturnc                 C  s   t | dr| jS | jS )z7Compat helper to return the response's next_update_utc.next_update_utc)hasattrr   next_updater    r   6/tmp/pip-unpacked-wheel-36gvocj8/pymongo/ocsp_cache.py_next_update   s    
r   c                 C  s   t | dr| jS | jS )z7Compat helper to return the response's this_update_utc.this_update_utc)r   r   this_updater   r   r   r   _this_update&   s    
r   c                   @  sb   e Zd ZdZedddddgZddd	d
ZdddddZddddddZdddddZ	dS )
_OCSPCachezA cache for OCSP responses.ZOcspResponseCacheKeyhash_algorithmissuer_name_hashissuer_key_hashserial_numberNone)r   c                 C  s   i | _ t | _d S )N)_datar	   _lock)selfr   r   r   __init__6   s    z_OCSPCache.__init__r
   CACHE_KEY_TYPE)ocsp_requestr   c                 C  s    | j |jj |j|j|jdS )N)r   r   r   r   )r"   r   namelowerr   r   r   )r    r#   r   r   r   _get_cache_key;   s    
z_OCSPCache._get_cache_keyr   )keyr   r   c           	   	   C  s  | j  | |}t|}|dkr>| j|d W 5 Q R  dS t|}|dkr\W 5 Q R  dS tjtj	d}|j
dkr|jdd}||  kr|k sn W 5 Q R  dS | j|d}|dkr|| j|< W 5 Q R  dS t|}|dk	r||k r|| j|< W 5 Q R X dS )zAdd/update a cache entry.

        'key' is of type cryptography.x509.ocsp.OCSPRequest
        'value' is of type cryptography.x509.ocsp.OCSPResponse

        Validity of the OCSP response must be checked by caller.
        Ntztzinfo)r   r&   r   r   popr   	_datetimenowr   utcr+   replaceget)	r    r'   r   	cache_keyr   r   r.   Zcached_valueZcached_next_updater   r   r   __setitem__C   s*    


z_OCSPCache.__setitem__)itemr   c              
   C  s   | j  | |}| j| }t|}t|}|dk	s8t|dk	sDttjtj	d}|j
dkrh|jdd}||  kr||k rn n|W  5 Q R  S | j|d t|W 5 Q R X dS )zGet a cache entry if it exists.

        'item' is of type cryptography.x509.ocsp.OCSPRequest

        Raises KeyError if the item is not in the cache.
        Nr(   r*   )r   r&   r   r   r   AssertionErrorr-   r.   r   r/   r+   r0   r,   KeyError)r    r4   r2   r   r   r   r.   r   r   r   __getitem__k   s    


z_OCSPCache.__getitem__N)
__name__
__module____qualname____doc__r   r"   r!   r&   r3   r7   r   r   r   r   r   .   s   
(r   N)r;   
__future__r   collectionsr   r   r-   r   typingr   r   r   Zpymongo.lockr	   Zcryptography.x509.ocspr
   r   r   r   r   r   r   r   r   <module>   s   