U _@sddlZddlZddlmZddlmZmZmZmZm Z ddl m Z m Z m Z mZddlmZmZmZmZddlmZmZGdd d ZeZejZejZejZejZejZejZdS) N)Mapping)AnyDictListOptionalType) Algorithmget_default_algorithms has_cryptorequires_cryptography) DecodeErrorInvalidAlgorithmErrorInvalidSignatureErrorInvalidTokenError)base64url_decodebase64url_encodec@seZdZdZd!ddZeddZddZd d Zd d Z d"e e e e e e eeje dddZd#e e ee e e e efdddZd$e e ee e e dddZddZddZd%ddZddZdd ZdS)&PyJWSZJWTNcCsht|_|dk rt|nt|j|_t|jD]}||jkr2|j|=q2|dkrVi}|||_dS)N)r _algorithmsset _valid_algslistkeys_get_default_optionsoptions)self algorithmsrkeyr||jkrtdt|ts$td||j|<|j|dS)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 TypeErrorradd)ralg_idalg_objrrrregister_algorithm+s    zPyJWS.register_algorithmcCs*||jkrtd|j|=|j|dS)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)rKeyErrorrremove)rr&rrrunregister_algorithm8s  zPyJWS.unregister_algorithmcCs t|jS)zM Returns a list of supported values for the 'alg' parameter. )rr)rrrrget_algorithmsFszPyJWS.get_algorithmsHS256)payloadr algorithmheaders json_encoderreturnc Csg}|dkrd}||jkr|j|d}|r>||||tj|d|d}|t||t|d |} z$|j |} | |}| | |} Wn6t k rts|tkrtd|ntdYnX|t| d |} | dS) NZnone)typalg),:)Z separatorscls.zFAlgorithm '%s' could not be found. Do you have cryptography installed?Algorithm not supportedutf-8)r header_typ_validate_headersupdatejsondumpsencodeappendrjoinr prepare_keyZsignr)r r NotImplementedErrordecode) rr.rr/r0r1ZsegmentsheaderZ json_header signing_inputr' signatureZencoded_stringrrrr@Ls>          z PyJWS.encode)jwtrrrr2c Ksb|dkr i}|j|}|d}|r.|s.td||\}} } } |rV|| | | |||| | dS)Nr!z\It is required that you pass in a value for the "algorithms" argument when calling decode().)r.rFrH)rr _load_verify_signature) rrJrrrkwargsZmerged_optionsr!r.rGrFrHrrrdecode_completes zPyJWS.decode_completecKs|j||||f|}|dS)Nr.)rN)rrJrrrrMZdecodedrrrrEsz PyJWS.decodecCs||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 )rKr<)rrJr0rrrget_unverified_headers zPyJWS.get_unverified_headerc Cst|tr|d}t|ts,tdtz$|dd\}}|dd\}}Wn,tk r|}ztd|W5d}~XYnXz t|}Wn2t t j fk r}ztd|W5d}~XYnXzt |}Wn0tk r} ztd| | W5d} ~ XYnXt|tstdz t|} Wn4t t j fk rR}ztd |W5d}~XYnXz t|} Wn4t t j fk r}ztd |W5d}~XYnX| ||| fS) Nr:z$Invalid token type. Token must be a r8rzNot enough segmentszInvalid header paddingzInvalid header string: %sz,Invalid header string: must be a json objectzInvalid payload paddingzInvalid crypto padding)r#strr@bytesr rsplitsplitr"rr$binasciiErrorr>loadsr) rrJrGZcrypto_segmentZheader_segmentZpayload_segmenterrZ header_datarFer.rHrrrrKs8        z PyJWS._loadcCsr|d}|dk r"||kr"tdz.|j|}||}||||sNtdWntk rltdYnXdS)Nr4z&The specified alg value is not allowedzSignature verification failedr9)getrrrCZverifyrr))rrGrFrHrrr4r'rrrrLs    zPyJWS._verify_signaturecCsd|kr||ddS)Nkid) _validate_kid)rr0rrrr<szPyJWS._validate_headerscCst|tstddS)Nz(Key ID header parameter must be a string)r#rQr)rr[rrrr\s zPyJWS._validate_kid)NN)r-NN)rINN)rINN)rIN)__name__ __module__ __qualname__r;r staticmethodrr(r+r,rRrQrrrr>Z JSONEncoderr@rrrNrErPrKrLr<r\rrrrrsZ      7   + r)rUr>Zcollections.abcrtypingrrrrrrr r r r exceptionsr rrrZutilsrrrZ_jws_global_objr@rNrEr(r+rPrrrrs f