U
    b#                     @   s   d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	 ddl
mZmZmZmZ ddlmZmZmZmZ ddlmZmZ G dd	 d	Ze ZejZejZejZejZejZejZdS )
    N)Mapping)AnyDictListOptionalType   )	Algorithmget_default_algorithms
has_cryptorequires_cryptography)DecodeErrorInvalidAlgorithmErrorInvalidSignatureErrorInvalidTokenError)base64url_decodebase64url_encodec                	   @   s   e Zd ZdZd#ddZedd Zdd Zd	d
 Zdd Z	d$e
eee ee eeej  eedddZd%eeeee  ee ee
 eeef dddZd&eeeee  ee edddZdd Zdd Zd'ddZdd  Zd!d" ZdS )(PyJWSZJWTNc                 C   sh   t  | _|d k	rt|nt| j| _t| j D ]}|| jkr2| j|= q2|d krVi }|  || _d S )N)r
   _algorithmsset_valid_algslistkeys_get_default_optionsoptions)self
algorithmsr   key r   //tmp/pip-unpacked-wheel-ivybibab/jwt/api_jws.py__init__   s    

zPyJWS.__init__c                   C   s   ddiS )Nverify_signatureTr   r   r   r   r   r   '   s    zPyJWS._get_default_optionsc                 C   s>   || j krtdt|ts$td|| j |< | j| dS )zW
        Registers a new Algorithm for use when creating and verifying tokens.
        z Algorithm already has a handler.z!Object is not of type `Algorithm`N)r   
ValueError
isinstancer	   	TypeErrorr   add)r   alg_idalg_objr   r   r   register_algorithm+   s    


zPyJWS.register_algorithmc                 C   s*   || j krtd| j |= | j| dS )z
        Unregisters an Algorithm for use when creating and verifying tokens
        Throws KeyError if algorithm is not registered.
        zJThe specified algorithm could not be removed because it is not registered.N)r   KeyErrorr   remove)r   r&   r   r   r   unregister_algorithm8   s    
zPyJWS.unregister_algorithmc                 C   s
   t | jS )zM
        Returns a list of supported values for the 'alg' parameter.
        )r   r   )r   r   r   r   get_algorithmsF   s    zPyJWS.get_algorithmsHS256F)payloadr   	algorithmheadersjson_encoderis_payload_detachedreturnc              
   C   s|  g }|d krd}|r@| d}|r*|d }| d}	|	dkr@d}| j|d}
|rd| | |
| |
d sr|
d= |rd|
d< nd|
kr|
d= tj|
d|d	 }|t| |r|}nt|}|| d
	|}z$| j
| }||}|||}W nP tk
rJ } z0ts0|tkr0td| d|td|W 5 d }~X Y nX |t| |rhd|d< d
	|}|dS )Nnonealgb64FT)typr5   r7   ),:)
separatorscls   .zAlgorithm 'z9' could not be found. Do you have cryptography installed?Algorithm not supported    r   utf-8)get
header_typ_validate_headersupdatejsondumpsencodeappendr   joinr   prepare_keysignr)   r   r   NotImplementedErrordecode)r   r.   r   r/   r0   r1   r2   segmentsZheaders_algZheaders_b64headerZjson_headerZmsg_payloadsigning_inputr'   	signatureeencoded_stringr   r   r   rF   L   s`    	




  






zPyJWS.encode )jwtr   r   r   detached_payloadr3   c                 K   s   |d kri }| j |}|d }|r.|s.td| |\}	}
}}|dddkr~|d kr`td|}	d|
ddd	 |	g}
|r| |
|||| |	||d
S )Nr!   z\It is required that you pass in a value for the "algorithms" argument when calling decode().r6   TFzIt is required that you pass in a value for the "detached_payload" argument to decode a message having the b64 header set to false.r<   r   r   )r.   rN   rP   )r   r   _loadr@   rH   rsplit_verify_signature)r   rT   r   r   r   rU   kwargsZmerged_optionsr!   r.   rO   rN   rP   r   r   r   decode_complete   s,    	
zPyJWS.decode_complete)rT   r   r   r   r3   c                 K   s   | j ||||f|}|d S )Nr.   )rZ   )r   rT   r   r   r   rY   decodedr   r   r   rL      s    zPyJWS.decodec                 C   s   |  |d }| | |S )zReturns back the JWT header parameters as a dict()

        Note: The signature is not verified so the header parameters
        should not be fully trusted until signature verification is complete
           )rV   rB   )r   rT   r0   r   r   r   get_unverified_header   s    
zPyJWS.get_unverified_headerc              
   C   s  t |tr|d}t |ts,tdt z$|dd\}}|dd\}}W n, tk
r| } ztd|W 5 d }~X Y nX zt|}W n2 t	t
jfk
r } ztd|W 5 d }~X Y nX zt|}W n2 tk
r }	 ztd|	 |	W 5 d }	~	X Y nX t |tstdzt|}
W n4 t	t
jfk
rT } ztd	|W 5 d }~X Y nX zt|}W n4 t	t
jfk
r } ztd
|W 5 d }~X Y nX |
|||fS )Nr?   z$Invalid token type. Token must be a r<   r   zNot enough segmentszInvalid header paddingzInvalid header string: z,Invalid header string: must be a json objectzInvalid payload paddingzInvalid crypto padding)r#   strrF   bytesr   rW   splitr"   r   r$   binasciiErrorrD   loadsr   )r   rT   rO   Zcrypto_segmentZheader_segmentZpayload_segmenterrZheader_datarN   rQ   r.   rP   r   r   r   rV      s8    


"zPyJWS._loadc           	   
   C   s   | d}|d k	r"||kr"tdz.| j| }||}||||sNtdW n, tk
r| } ztd|W 5 d }~X Y nX d S )Nr5   z&The specified alg value is not allowedzSignature verification failedr=   )r@   r   r   rI   verifyr   r)   )	r   rO   rN   rP   r   r   r5   r'   rQ   r   r   r   rX      s    	


zPyJWS._verify_signaturec                 C   s   d|kr|  |d  d S )Nkid)_validate_kid)r   r0   r   r   r   rB     s    zPyJWS._validate_headersc                 C   s   t |tstdd S )Nz(Key ID header parameter must be a string)r#   r^   r   )r   rf   r   r   r   rg     s    
zPyJWS._validate_kid)NN)r-   NNF)rS   NNN)rS   NN)rS   N)__name__
__module____qualname__rA   r    staticmethodr   r(   r+   r,   r_   r^   r   r   r   rD   JSONEncoderboolrF   r   r   rZ   rL   r]   rV   rX   rB   rg   r   r   r   r   r      sb   


    O    

)   
+  
r   )ra   rD   collections.abcr   typingr   r   r   r   r   r   r	   r
   r   r   
exceptionsr   r   r   r   utilsr   r   r   Z_jws_global_objrF   rZ   rL   r(   r+   r]   r   r   r   r   <module>   s      