
    ([f5                         d dl Z d dlZd dlmZmZmZ ddlmZmZm	Z	  e j
        d          Zd Zd Zd Z G d	 d
          ZdS )    N)to_bytes
to_unicodeurlsafe_b64encode   )InvalidRequestErrorInvalidGrantErrorOAuth2Requestz^[a-zA-Z0-9\-._~]{43,128}$c                     t          j        t          | d                                                    }t	          t          |                    S )z8Create S256 code_challenge with the given code_verifier.ascii)hashlibsha256r   digestr   r   )code_verifierdatas     T/var/www/piapp/venv/lib/python3.11/site-packages/authlib/oauth2/rfc7636/challenge.pycreate_s256_code_challenger      s>    >(='::;;BBDDD'--...    c                     | |k    S N r   code_challenges     r   compare_plain_code_challenger      s     N**r   c                 (    t          |           |k    S r   )r   r   s     r   compare_s256_code_challenger      s    %m44FFr   c                   N    e Zd ZdZdZddgZeedZddZ	d Z
d Zd	 Zd
 Z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                     || _         d S r   )required)selfr!   s     r   __init__zCodeChallenge.__init__8   s     r   c                 r    |                     d| j                   |                     d| j                   d S )N$after_validate_authorization_requestafter_validate_token_request)register_hookvalidate_code_challengevalidate_code_verifier)r"   grants     r   __call__zCodeChallenge.__call__;   sP    2(	
 	
 	
 	*'	
 	
 	
 	
 	
r   c                     |j         }|j                            d          }|j                            d          }|s|sd S |st          d          |r|| j        vrt          d          d S d S )Nr   code_challenge_methodzMissing "code_challenge"z#Unsupported "code_challenge_method")requestr   getr   SUPPORTED_CODE_CHALLENGE_METHOD)r"   r*   r.   	challengemethods        r   r(   z%CodeChallenge.validate_code_challengeE   s    !&L$$%566	!!"9:: 	 	F 	B%&@AAA 	MfD$HHH%&KLLL	M 	MHHr   c                    |j         }|j                            d          }| j        r|j        dk    r|st          d          |j        }|                     |          }|s|sd S |st          d          t          	                    |          st          d          | 
                    |          }|| j        }| j                            |          }|st          d| d           |||          st          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_PATTERNmatch'get_authorization_code_challenge_methodDEFAULT_CODE_CHALLENGE_METHODCODE_CHALLENGE_METHODSRuntimeErrorr   )r"   r*   r.   verifierr9   r1   r2   funcs           r   r)   z$CodeChallenge.validate_code_verifierR   sP   !&<##O44 = 	AW0F::8:%&?@@@$799:LMM	  	 	F  	A%&?@@@$**844 	A%&?@@@ ==>PQQ>7F*..v66 	CAAAABBB tHi(( 	J#0HIIII	J 	Jr   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"   r9   s     r   r:   z.CodeChallenge.get_authorization_code_challengev   s     "00r   c                     |j         S )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-   rD   s     r   r=   z5CodeChallenge.get_authorization_code_challenge_method   s     "77r   N)T)__name__
__module____qualname____doc__r>   r0   r   r   r?   r#   r+   r(   r)   r:   r=   r   r   r   r   r      s          %,!'.&7# .+ 
! ! ! !
 
 
M M M"J "J "JH	1 	1 	1	8 	8 	8 	8 	8r   r   )rer   authlib.common.encodingr   r   r   rfc6749r   r   r	   compiler;   r   r   r   r   r   r   r   <module>rN      s    				  K K K K K K K K K K          #
#@AA / / /+ + +G G G
k8 k8 k8 k8 k8 k8 k8 k8 k8 k8r   