U
    ڲg,                     @  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 ddlmZmZmZmZ ddlmZmZ dd	lmZ erd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!ej"Z"dS )    )annotationsN)TYPE_CHECKINGAny   )	Algorithmget_default_algorithms
has_cryptorequires_cryptography)PyJWK)DecodeErrorInvalidAlgorithmErrorInvalidSignatureErrorInvalidTokenError)base64url_decodebase64url_encode)RemovedInPyjwt3Warning)AllowedPrivateKeysAllowedPublicKeysc                
   @  s"  e Zd ZdZd@d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
dAddd dd!d"d"dd#d$d%ZdBd'd(ddd)d*d+d,d-ZdCd'd(ddd)d.d+d/d0Zd'd*d1d2d3Zd'd4d1d5d6ZdDdd*dd(ddd7d8d9Zd*dd:d;d<Zd.dd=d>d?ZdS )EPyJWSZJWTNzlist[str] | Nonezdict[str, Any] | NoneNone)
algorithmsoptions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_optionsr   )selfr   r   key r!   //tmp/pip-unpacked-wheel-ecrjo5d0/jwt/api_jws.py__init__   s    

zPyJWS.__init__zdict[str, bool])r   c                   C  s   ddiS )Nverify_signatureTr!   r!   r!   r!   r"   r   2   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_algorithm6   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_algorithmC   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_algorithmsQ   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   r1   er!   r!   r"   get_algorithm_by_nameW   s    
zPyJWS.get_algorithm_by_nameHS256FTbytesz AllowedPrivateKeys | str | bytesz
str | Noneztype[json.JSONEncoder] | Nonebool)payloadr    	algorithmheadersjson_encoderis_payload_detachedsort_headersr   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	 }|t| |r|}nt|}|| d
	|}| 
|	}||}|||}|t| |rd|d< d
	|}|dS )Nnonealgb64FT)typr@   rB   ),:)
separatorscls	sort_keys   .    r   utf-8)get
header_typ_validate_headersupdatejsondumpsencodeappendr   joinr5   prepare_keysigndecode)r   r9   r    r:   r;   r<   r=   r>   segmentsZ
algorithm_Zheaders_algZheaders_b64headerZjson_headerZmsg_payloadsigning_inputr'   	signatureencoded_stringr!   r!   r"   rQ   h   sN    





   





zPyJWS.encode zstr | bytesz'AllowedPublicKeys | PyJWK | str | byteszbytes | Nonezdict[str, Any])jwtr    r   r   detached_payloadr   c                 K  s   |rt dt|  t |d kr*i }| j|}|d }|rV|sVt|tsVtd| 	|\}	}
}}|
dddkr|d krt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().rA   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.rH   r   r   )r9   rX   rZ   )warningswarntupler   r   r   r)   r
   r   _loadrK   rS   rsplit_verify_signature)r   r]   r    r   r   r^   kwargsZmerged_optionsr$   r9   rY   rX   rZ   r!   r!   r"   decode_complete   s6    	
zPyJWS.decode_completer   c                 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: )r^   r9   )r_   r`   ra   r   r   rf   )r   r]   r    r   r   r^   re   decodedr!   r!   r"   rV      s    	    zPyJWS.decode)r]   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
           )rb   rM   )r   r]   r;   r!   r!   r"   get_unverified_header   s    
zPyJWS.get_unverified_headerz*tuple[bytes, bytes, dict[str, Any], 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 )NrJ   z$Invalid token type. Token must be a rH   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%   rQ   r7   r   rc   splitr(   r   r*   binasciiErrorrO   loadsdict)r   r]   rY   Zcrypto_segmentZheader_segmentZpayload_segmenterrZheader_datarX   r4   r9   rZ   r!   r!   r"   rb      s8    


"zPyJWS._load)rY   rX   rZ   r    r   r   c           
   
   C  s   |d krt |tr|jg}z|d }W n tk
rB   tdY nX |rX|d k	r`||kr`tdt |trx|j}|j}nFz| |}W n, tk
r }	 ztd|	W 5 d }	~	X Y nX |	|}|
|||stdd S )Nr@   zAlgorithm not specifiedz&The specified alg value is not allowedr2   zSignature verification failed)r)   r
   Zalgorithm_namer-   r   r   r    r5   r3   rT   verifyr   )
r   rY   rX   rZ   r    r   r@   r'   Zprepared_keyr4   r!   r!   r"   rd      s$    

zPyJWS._verify_signature)r;   r   c                 C  s   d|kr|  |d  d S )Nkid)_validate_kid)r   r;   r!   r!   r"   rM   ?  s    zPyJWS._validate_headers)rq   r   c                 C  s   t |tstdd S )Nz(Key ID header parameter must be a string)r)   r%   r   )r   rq   r!   r!   r"   rr   C  s    
zPyJWS._validate_kid)NN)r6   NNFT)r\   NNN)r\   NNN)r\   N)__name__
__module____qualname__rL   r#   staticmethodr   r,   r/   r0   r5   rQ   rf   rV   ri   rb   rd   rM   rr   r!   r!   r!   r"   r      sB          H    0    +  r   )#
__future__r   rk   rO   r_   typingr   r   r   r   r   r   r	   Zapi_jwkr
   
exceptionsr   r   r   r   utilsr   r   r   r   r   r   Z_jws_global_objrQ   rf   rV   r,   r/   r5   ri   r!   r!   r!   r"   <module>   s,     .