
¿«‘_É  ã               @   sÔ   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
 Gd	 d
 „  d
 e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z d S)é    Né   )Úconstant_time_compare)Ú_base64_alphabet)Úbase64_decode)Úbase64_encode)Ú
want_bytes)ÚBadSignaturec               @   s.   e  Z d  Z d Z d d „  Z d d „  Z d S)ÚSigningAlgorithmzgSubclasses must implement :meth:`get_signature` to provide
    signature generation functionality.
    c             C   s   t  ƒ  ‚ d S)z2Returns the signature for the given key and value.N)ÚNotImplementedError)ÚselfÚkeyÚvalue© r   ú;/tmp/pip-build-5gj8f0j9/itsdangerous/itsdangerous/signer.pyÚget_signature   s    zSigningAlgorithm.get_signaturec             C   s   t  | |  j | | ƒ ƒ S)zMVerifies the given signature matches the expected
        signature.
        )r   r   )r   r   r   Úsigr   r   r   Úverify_signature   s    z!SigningAlgorithm.verify_signatureN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r	      s   r	   c               @   s"   e  Z d  Z d Z d d „  Z d S)ÚNoneAlgorithmz`Provides an algorithm that does not perform any signing and
    returns an empty signature.
    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      s   r   c               @   s@   e  Z d  Z d Z e e j ƒ Z d d d „ Z d d „  Z	 d S)ÚHMACAlgorithmz*Provides signature generation using HMACs.Nc             C   s"   | d  k r |  j  } | |  _ d  S)N)Údefault_digest_methodÚdigest_method)r   r   r   r   r   Ú__init__-   s    	zHMACAlgorithm.__init__c             C   s(   t  j | d | d |  j ƒ} | j ƒ  S)NÚmsgÚ	digestmod)ÚhmacÚnewr   Údigest)r   r   r   Úmacr   r   r   r   2   s    zHMACAlgorithm.get_signature)
r   r   r   r   ÚstaticmethodÚhashlibÚsha1r   r   r   r   r   r   r   r   %   s   r   c               @   sŽ   e  Z d  Z d Z e e j ƒ Z d Z d d d d d d d „ Z	 d d „  Z
 d	 d
 „  Z d d „  Z d d „  Z d d „  Z d d „  Z d S)ÚSigneraè  This class can sign and unsign bytes, validating the signature
    provided.

    Salt can be used to namespace the hash, so that a signed string is
    only valid for a given namespace. Leaving this at the default value
    or re-using a salt value across different parts of your application
    where the same signed value in one part can mean something different
    in another part is a security risk.

    See :ref:`the-salt` for an example of what the salt is doing and how
    you can utilize it.

    .. versionadded:: 0.14
        ``key_derivation`` and ``digest_method`` were added as arguments
        to the class constructor.

    .. versionadded:: 0.18
        ``algorithm`` was added as an argument to the class constructor.
    zdjango-concatNÚ.c             C   s¸   t  | ƒ |  _ t  | ƒ |  _ |  j t k r9 t d ƒ ‚ | d  k rK d n | |  _ | d  k ri |  j } | |  _ | d  k r‡ |  j } | |  _	 | d  k r« t
 |  j	 ƒ } | |  _ d  S)Nz‹The given separator cannot be used because it may be contained in the signature itself. Alphanumeric characters and `-_=` must not be used.zitsdangerous.Signer)r   Ú
secret_keyÚsepr   Ú
ValueErrorÚsaltÚdefault_key_derivationÚkey_derivationr   r   r   Ú	algorithm)r   r(   r+   r)   r-   r   r.   r   r   r   r   [   s    						zSigner.__init__c             C   sÌ   t  |  j ƒ } |  j d k r8 |  j | |  j ƒ j ƒ  S|  j d k re |  j | d |  j ƒ j ƒ  S|  j d k r¦ t j |  j d |  j ƒ} | j | ƒ | j ƒ  S|  j d k r¼ |  j St	 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.
        Úconcatzdjango-concats   signerr   r   ÚnonezUnknown key derivation methodN)
r   r+   r-   r   r(   r!   r   r    ÚupdateÚ	TypeError)r   r+   r"   r   r   r   Ú
derive_keyw   s    
zSigner.derive_keyc             C   s7   t  | ƒ } |  j ƒ  } |  j j | | ƒ } t | ƒ S)z*Returns the signature for the given value.)r   r3   r.   r   r   )r   r   r   r   r   r   r   r   Œ   s    zSigner.get_signaturec             C   s$   t  | ƒ t  |  j ƒ |  j | ƒ S)zSigns the given string.)r   r)   r   )r   r   r   r   r   Úsign“   s    zSigner.signc             C   sK   |  j  ƒ  } y t | ƒ } Wn t k
 r4 d SYn X|  j j | | | ƒ S)z+Verifies the signature for the given value.F)r3   r   Ú	Exceptionr.   r   )r   r   r   r   r   r   r   r   —   s    	zSigner.verify_signaturec             C   s‚   t  | ƒ } t  |  j ƒ } | | k r: t d |  j ƒ ‚ | j | d ƒ \ } } |  j | | ƒ rh | St d | d | ƒ‚ d S)zUnsigns the given string.zNo %r found in valuer   zSignature %r does not matchÚpayloadN)r   r)   r   Úrsplitr   )r   Úsigned_valuer)   r   r   r   r   r   Úunsign    s    zSigner.unsignc             C   s2   y |  j  | ƒ d SWn t k
 r- d SYn Xd S)znOnly validates the given signed value. Returns ``True`` if
        the signature exists and is valid.
        TFN)r9   r   )r   r8   r   r   r   Úvalidate«   s
    zSigner.validate)r   r   r   r   r#   r$   r%   r   r,   r   r3   r   r4   r   r9   r:   r   r   r   r   r&   7   s   	r&   )r$   r   Ú_compatr   Úencodingr   r   r   r   Úexcr   Úobjectr	   r   r   r&   r   r   r   r   Ú<module>   s   	