3
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
 ejeef Zeje Zejeje ef ZG dd	 d	ZG d
d deZG dd deZeeje dddZG dd dZdS )    N   )_base64_alphabet)base64_decode)base64_encode)
want_bytes)BadSignaturec               @   s6   e Zd ZdZeeedddZeeeedddZdS )	SigningAlgorithmzgSubclasses must implement :meth:`get_signature` to provide
    signature generation functionality.
    )keyvaluereturnc             C   s
   t  dS )z2Returns the signature for the given key and value.N)NotImplementedError)selfr	   r
    r   ;/tmp/pip-build-3irwxpxt/itsdangerous/itsdangerous/signer.pyget_signature   s    zSigningAlgorithm.get_signature)r	   r
   sigr   c             C   s   t j|| j||S )zMVerifies the given signature matches the expected
        signature.
        )hmaccompare_digestr   )r   r	   r
   r   r   r   r   verify_signature   s    z!SigningAlgorithm.verify_signatureN)__name__
__module____qualname____doc__bytesr   boolr   r   r   r   r   r      s   r   c               @   s"   e Zd ZdZeeedddZdS )NoneAlgorithmz`Provides an algorithm that does not perform any signing and
    returns an empty signature.
    )r	   r
   r   c             C   s   dS )N    r   )r   r	   r
   r   r   r   r   %   s    zNoneAlgorithm.get_signatureN)r   r   r   r   r   r   r   r   r   r   r       s   r   c               @   sF   e Zd ZU dZeejZej	d	ej	dddZ
eeedddZdS )
HMACAlgorithmz*Provides signature generation using HMACs.N)digest_methodc             C   s   |d kr| j }|| _d S )N)default_digest_methodr   )r   r   r   r   r   __init__1   s    zHMACAlgorithm.__init__)r	   r
   r   c             C   s   t j||| jd}|j S )N)msg	digestmod)r   newr   digest)r   r	   r
   macr   r   r   r   7   s    zHMACAlgorithm.get_signature)N)r   r   r   r   staticmethodhashlibsha1r   _tAnyr    r   r   r   r   r   r   r   )   s   
r   )
secret_keyr   c             C   s&   t | ttfrt| gS dd | D S )Nc             S   s   g | ]}t |qS r   )r   ).0sr   r   r   
<listcomp>@   s    z#_make_keys_list.<locals>.<listcomp>)
isinstancestrr   r   )r+   r   r   r   _make_keys_list<   s    
r1   c               @   s   e Zd ZU dZeejZej	dZ
e
deeeeje ejej	 eje dddZeed	d
dZdeedddZeedddZeedddZeeedddZeedddZeedddZdS )Signera  A signer securely signs bytes, then unsigns them to verify that
    the value hasn't been changed.

    The secret key should be a random string of ``bytes`` and should not
    be saved to code or version control. Different salts should be used
    to distinguish signing in different contexts. See :doc:`/concepts`
    for information about the security of the secret key and salt.

    :param secret_key: The secret key to sign and verify with. Can be a
        list of keys, oldest to newest, to support key rotation.
    :param salt: Extra key to combine with ``secret_key`` to distinguish
        signatures in different contexts.
    :param sep: Separator between the signature and value.
    :param key_derivation: How to derive the signing key from the secret
        key and salt. Possible values are ``concat``, ``django-concat``,
        or ``hmac``. Defaults to :attr:`default_key_derivation`, which
        defaults to ``django-concat``.
    :param digest_method: Hash function to use when generating the HMAC
        signature. Defaults to :attr:`default_digest_method`, which
        defaults to :func:`hashlib.sha1`. Note that the security of the
        hash alone doesn't apply when used intermediately in HMAC.
    :param algorithm: A :class:`SigningAlgorithm` instance to use
        instead of building a default :class:`HMACAlgorithm` with the
        ``digest_method``.

    .. versionchanged:: 2.0
        Added support for key rotation by passing a list to
        ``secret_key``.

    .. versionchanged:: 0.18
        ``algorithm`` was added as an argument to the class constructor.

    .. versionchanged:: 0.14
        ``key_derivation`` and ``digest_method`` were added as arguments
        to the class constructor.
    zdjango-concat   itsdangerous.Signer   .N)r+   saltsepkey_derivationr   	algorithmc             C   s   t || _t|| _| jtkr&td|d k	r8t|}nd}|| _|d krP| j}|| _|d krd| j	}|| _
|d kr|t| j
}|| _d S )NzThe given separator cannot be used because it may be contained in the signature itself. ASCII letters, digits, and '-_=' must not be used.s   itsdangerous.Signer)r1   secret_keysr   r6   r   
ValueErrorr5   default_key_derivationr7   r   r   r   r8   )r   r+   r5   r6   r7   r   r8   r   r   r   r    x   s$    




zSigner.__init__)r   c             C   s
   | j d S )zThe newest (last) entry in the :attr:`secret_keys` list. This
        is for compatibility from before key rotation support was added.
        r   )r9   )r   r   r   r   r+      s    zSigner.secret_key)r+   r   c             C   s   |dkr| j d
 }nt|}| jdkrBtjt| j| j| j S | jdkrltjt| j| jd | j S | jdkrt	j
|| jd}|j| j |j S | jdkr|S td	dS )a  This method is called to derive the key. The default key
        derivation choices can be overridden here. Key derivation is not
        intended to be used as a security method to make a complex key
        out of a short password. Instead you should use large random
        secret keys.

        :param secret_key: A specific secret key to derive from.
            Defaults to the last item in :attr:`secret_keys`.

        .. versionchanged:: 2.0
            Added the ``secret_key`` parameter.
        Nr   concatzdjango-concats   signerr   )r"   nonezUnknown key derivation methodr<   )r9   r   r7   r)   castr   r   r5   r$   r   r#   update	TypeError)r   r+   r%   r   r   r   
derive_key   s    



zSigner.derive_key)r
   r   c             C   s&   t |}| j }| jj||}t|S )z*Returns the signature for the given value.)r   rB   r8   r   r   )r   r
   r	   r   r   r   r   r      s    zSigner.get_signaturec             C   s   t |}|| j | j| S )zSigns the given string.)r   r6   r   )r   r
   r   r   r   sign   s    zSigner.sign)r
   r   r   c             C   s`   yt |}W n tk
r    dS X t|}x0t| jD ]"}| j|}| jj|||r6dS q6W dS )z+Verifies the signature for the given value.FT)r   	Exceptionr   reversedr9   rB   r8   r   )r   r
   r   r+   r	   r   r   r   r      s    
zSigner.verify_signature)signed_valuer   c             C   s^   t |}| j|kr$td| jd|j| jd\}}| j||rF|S td|d|ddS )zUnsigns the given string.zNo z found in valuer   z
Signature z does not match)payloadN)r   r6   r   rsplitr   )r   rF   r
   r   r   r   r   unsign   s    
zSigner.unsignc             C   s(   y| j | dS  tk
r"   dS X dS )znOnly validates the given signed value. Returns ``True`` if
        the signature exists and is valid.
        TFN)rI   r   )r   rF   r   r   r   validate   s
    
zSigner.validate)r3   r4   NNN)N)r   r   r   r   r&   r'   r(   r   r)   r*   r;   r0   _t_secret_key_t_opt_str_bytes_t_str_bytesOptionalr   r    propertyr   r+   rB   r   rC   r   r   rI   rJ   r   r   r   r   r2   C   s    
$    .'!r2   )r'   r   typingr)   encodingr   r   r   r   excr   Unionr0   r   rM   rN   rL   IterablerK   r   r   r   Listr1   r2   r   r   r   r   <module>   s   
	