U
    d)                     @  s   d dl mZ d dlZd dlZd dlZd dl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 ddl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ejZdS )    )annotationsN)AnyType   )	Algorithmget_default_algorithms
has_cryptorequires_cryptography)DecodeErrorInvalidAlgorithmErrorInvalidSignatureErrorInvalidTokenError)base64url_decodebase64url_encode)RemovedInPyjwt3Warningc                	   @  s  e Zd ZdZd<ddddZedddd	Zd
dddddZd
ddddZddddZ	d
ddddZ
d=dd
ddddd
dd d!Zd>d
d
d#dd$d%d&d'd(Zd?d
d
d#dd$d
d&d)d*Zd+d,d-d.d/Zd+d0d-d1d2Zd@dd,dd
d#dd3d4d5Zd%dd6d7d8Zd
dd9d:d;ZdS )APyJWSZJWTNNone)returnc                 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-cf9_iply/jwt/api_jws.py__init__   s    

zPyJWS.__init__zdict[str, bool]c                   C  s   ddiS )Nverify_signatureTr   r   r   r   r   r   *   s    zPyJWS._get_default_optionsstrr   )alg_idalg_objr   c                 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   r#   r$   r   r   r   register_algorithm.   s    


zPyJWS.register_algorithm)r#   r   c                 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_algorithm;   s    
zPyJWS.unregister_algorithmz	list[str]c                 C  s
   t | jS )zM
        Returns a list of supported values for the 'alg' parameter.
        )r   r   )r   r   r   r   get_algorithmsI   s    zPyJWS.get_algorithms)alg_namer   c              
   C  s\   z| j | W S  tk
rV } z,ts<|tkr<td| d|td|W 5 d}~X Y nX dS )z
        For a given string name, return the matching Algorithm object.

        Example usage:

        >>> jws_obj.get_algorithm_by_name("RS256")
        zAlgorithm 'z9' could not be found. Do you have cryptography installed?Algorithm not supportedN)r   r*   r   r	   NotImplementedError)r   r.   er   r   r   get_algorithm_by_nameO   s    
zPyJWS.get_algorithm_by_nameHS256Fbytesz
str | Nonezdict[str, Any] | NonezType[json.JSONEncoder] | Nonebool)payloadr   	algorithmheadersjson_encoderis_payload_detachedr   c                 C  s,  g }|d k	r|nd}|rD| d}	|	r.|d }| d}
|
dkrDd}| j|d}|rh| | || |d sv|d= |rd|d< nd|kr|d= tj|d|dd	 }|t| |r|}nt|}|| d
	|}| 
|}||}|||}|t| |rd|d< d
	|}|dS )Nnonealgb64FT)typr<   r>   ),:)
separatorscls	sort_keys   .    r   utf-8)get
header_typ_validate_headersupdatejsondumpsencodeappendr   joinr2   prepare_keysigndecode)r   r6   r   r7   r8   r9   r:   segmentsZ
algorithm_Zheaders_algZheaders_b64headerZjson_headerZmsg_payloadsigning_inputr$   	signatureencoded_stringr   r   r   rM   `   sN    	




   





zPyJWS.encode zlist[str] | Nonezbytes | Nonezdict[str, Any])jwtr   r   r   detached_payloadr   c                 K  s   |rt dt|  t |d kr*i }| j|}|d }|rL|sLtd| |\}	}
}}|dddkr|d kr~td|}	d	|

dd	d
 |	g}
|r| |
|||| |	||dS )Nzypassing additional kwargs to decode_complete() is deprecated and will be removed in pyjwt version 3. Unsupported kwargs: r!   z\It is required that you pass in a value for the "algorithms" argument when calling decode().r=   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.rD   r   r   )r6   rT   rV   )warningswarntupler   r   r   r
   _loadrG   rO   rsplit_verify_signature)r   rY   r   r   r   rZ   kwargsZmerged_optionsr!   r6   rU   rT   rV   r   r   r   decode_complete   s6    	
zPyJWS.decode_completec                 K  s:   |rt dt|  t | j|||||d}|d S )Nzppassing additional kwargs to decode() is deprecated and will be removed in pyjwt version 3. Unsupported kwargs: )rZ   r6   )r[   r\   r]   r   r   rb   )r   rY   r   r   r   rZ   ra   decodedr   r   r   rR      s    	    zPyJWS.decodezstr | bytesdict)rY   r   c                 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
           )r^   rI   )r   rY   r8   r   r   r   get_unverified_header   s    
zPyJWS.get_unverified_headerz tuple[bytes, bytes, dict, bytes]c              
   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 )NrF   z$Invalid token type. Token must be a rD   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&   r"   rM   r4   r
   r_   splitr%   r   r'   binasciiErrorrK   loadsrd   )r   rY   rU   Zcrypto_segmentZheader_segmentZpayload_segmenterrZheader_datarT   r1   r6   rV   r   r   r   r^      s8    


"zPyJWS._load)rU   rT   rV   r   r   r   c           	   
   C  s   | d}|r|d k	r&||kr&tdz| |}W n, tk
r` } ztd|W 5 d }~X Y nX ||}||||stdd S )Nr<   z&The specified alg value is not allowedr/   zSignature verification failed)rG   r   r2   r0   rP   verifyr   )	r   rU   rT   rV   r   r   r<   r$   r1   r   r   r   r`     s    	

zPyJWS._verify_signature)r8   r   c                 C  s   d|kr|  |d  d S )Nkid)_validate_kid)r   r8   r   r   r   rI   /  s    zPyJWS._validate_headers)rm   r   c                 C  s   t |tstdd S )Nz(Key ID header parameter must be a string)r&   r"   r   )r   rm   r   r   r   rn   3  s    
zPyJWS._validate_kid)NN)r3   NNF)rX   NNN)rX   NNN)rX   N)__name__
__module____qualname__rH   r    staticmethodr   r)   r,   r-   r2   rM   rb   rR   rf   r^   r`   rI   rn   r   r   r   r   r      s<       H    0    +  r   )
__future__r   rh   rK   r[   typingr   r   r   r   r   r   r	   
exceptionsr
   r   r   r   utilsr   r   r   r   Z_jws_global_objrM   rb   rR   r)   r,   r2   rf   r   r   r   r   <module>   s&     "