o
    ^[2h                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ ddlmZ ddlmZ ddlm	Z	 e
d	Ze
d	Zd
d Zdd Zdd ZG dd dZdS )    N)to_bytes)
to_unicode)urlsafe_b64encode   )InvalidGrantError)InvalidRequestError)OAuth2Requestz^[a-zA-Z0-9\-._~]{43,128}$c                 C   s    t t| d }tt|S )z8Create S256 code_challenge with the given code_verifier.ascii)hashlibsha256r   digestr   r   )code_verifierdata r   q/home/skpark/git/infrasmart_work/infrasmart/venv/lib/python3.10/site-packages/authlib/oauth2/rfc7636/challenge.pycreate_s256_code_challenge   s   r   c                 C   s   | |kS Nr   r   code_challenger   r   r   compare_plain_code_challenge   s   r   c                 C   s   t | |kS r   )r   r   r   r   r   compare_s256_code_challenge   s   r   c                   @   sX   e Zd ZdZdZddgZeedZdddZ	dd	 Z
d
d Zdd Zdd Zdd ZdS )CodeChallengea  CodeChallenge extension to Authorization Code Grant. It is used to
    improve the security of Authorization Code flow for public clients by
    sending extra "code_challenge" and "code_verifier" to the authorization
    server.

    The AuthorizationCodeGrant SHOULD save the ``code_challenge`` and
    ``code_challenge_method`` into database when ``save_authorization_code``.
    Then register this extension via::

        server.register_grant(AuthorizationCodeGrant, [CodeChallenge(required=True)])
    plainS256)r   r   Tc                 C   s
   || _ d S r   )required)selfr   r   r   r   __init__8   s   
zCodeChallenge.__init__c                 C   s    | d| j | d| j d S )N,after_validate_authorization_request_payloadafter_validate_token_request)register_hookvalidate_code_challengevalidate_code_verifier)r   grantr   r   r   __call__;   s   zCodeChallenge.__call__c                 C   s   |j }|jjd}|jjd}|s|sd S |stdt|jjdg dkr-tdt|s6td|rA|| j	vrAtdt|jjdg dkrQtdd S )	Nr   code_challenge_methodzMissing 'code_challenge'   z%Multiple 'code_challenge' in request.zInvalid 'code_challenge'z#Unsupported 'code_challenge_method'z,Multiple 'code_challenge_method' in request.)
requestpayloadr   getr   lendatalistCODE_CHALLENGE_PATTERNmatchSUPPORTED_CODE_CHALLENGE_METHOD)r   r"   redirect_urir&   	challengemethodr   r   r   r    E   s    
z%CodeChallenge.validate_code_challengec           	      C   s   |j }|jd}| jr|jdkr|std|j}| |}|s%|s%d S |s+tdt	|s4td| 
|}|d u r@| j}| j|}|sPtd| d|||sZtddd S )	Nr   nonezMissing 'code_verifier'zInvalid 'code_verifier'zNo verify method for ''zCode challenge failed.)description)r&   formr(   r   auth_methodr   authorization_code get_authorization_code_challengeCODE_VERIFIER_PATTERNr,   'get_authorization_code_challenge_methodDEFAULT_CODE_CHALLENGE_METHODCODE_CHALLENGE_METHODSRuntimeErrorr   )	r   r"   resultr&   verifierr6   r/   r0   funcr   r   r   r!   [   s*   




z$CodeChallenge.validate_code_verifierc                 C      |j S )a[  Get "code_challenge" associated with this authorization code.
        Developers MAY re-implement it in subclass, the default logic::

            def get_authorization_code_challenge(self, authorization_code):
                return authorization_code.code_challenge

        :param authorization_code: the instance of authorization_code
        )r   r   r6   r   r   r   r7         	z.CodeChallenge.get_authorization_code_challengec                 C   r@   )ap  Get "code_challenge_method" associated with this authorization code.
        Developers MAY re-implement it in subclass, the default logic::

            def get_authorization_code_challenge_method(self, authorization_code):
                return authorization_code.code_challenge_method

        :param authorization_code: the instance of authorization_code
        )r$   rA   r   r   r   r9      rB   z5CodeChallenge.get_authorization_code_challenge_methodN)T)__name__
__module____qualname____doc__r:   r-   r   r   r;   r   r#   r    r!   r7   r9   r   r   r   r   r   !   s    

$r   )r
   reauthlib.common.encodingr   r   r   rfc6749r   r   r   compiler8   r+   r   r   r   r   r   r   r   r   <module>   s    

