B _@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)&PyJWSZJWTNcCslt|_|dk rt|nt|j|_x(t|jD]}||jkr4|j|=q4W|dkrZi}|||_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 |} y$|j |} | |}| | |} Wn6t k rts|tkrtd|ntdYnX|t| d |} | dS) NZnone)typalg),:) separatorscls.zFAlgorithm '%s' could not be found. Do you have cryptography installed?zAlgorithm not supportedzutf-8)r header_typ_validate_headersupdatejsondumpsencodeappendrjoinr prepare_keysignr)r r NotImplementedErrordecode) rr.rr/r0r1segmentsheaderZ json_header signing_inputr' signatureencoded_stringrrrr?Ls4          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.rGrI)rr _load_verify_signature) rrLrrrkwargsZmerged_optionsr!r.rHrGrIrrrdecode_completes zPyJWS.decode_completecKs|j||||f|}|dS)Nr.)rP)rrLrrrrOdecodedrrrrEsz 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 )rMr;)rrLr0rrrget_unverified_headers zPyJWS.get_unverified_headerc Cst|tr|d}t|ts,tdty$|dd\}}|dd\}}Wn,tk r|}ztd|Wdd}~XYnXy t|}Wn2t t j fk r}ztd|Wdd}~XYnXyt |}Wn0tk r} ztd| | Wdd} ~ XYnXt|tstdy t|} Wn4t t j fk rR}ztd |Wdd}~XYnXy t|} Wn4t t j fk r}ztd |Wdd}~XYnX| ||| fS) Nzutf-8z$Invalid token type. Token must be a r9rzNot 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) rrLrHZcrypto_segmentZheader_segmentZpayload_segmenterrZ header_datarGer.rIrrrrMs8        z PyJWS._loadcCsr|d}|dk r"||kr"tdy.|j|}||}||||sNtdWntk rltdYnXdS)Nr4z&The specified alg value is not allowedzSignature verification failedzAlgorithm not supported)getrrrBZverifyrr))rrHrGrIrrr4r'rrrrNs    zPyJWS._verify_signaturecCsd|kr||ddS)Nkid) _validate_kid)rr0rrrr;szPyJWS._validate_headerscCst|tstddS)Nz(Key ID header parameter must be a string)r#rTr)rr^rrrr_s zPyJWS._validate_kid)NN)r-NN)rKNN)rKNN)rKN)__name__ __module__ __qualname__r:r staticmethodrr(r+r,rUrTrrrr= JSONEncoderr?rrrPrErSrMrNr;r_rrrrrs0    0 + r)rXr=collections.abcrtypingrrrrrrr r r r exceptionsr rrrutilsrrrZ_jws_global_objr?rPrEr(r+rSrrrrs f