
    i[f                         d dl Z d dlmZ d dlmZmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ dd	lmZ dd
lmZ ddlmZ  G d de          Zd Z e	e          ZdS )    N)contextmanager)gjson)request)
LocalProxy)OAuth2ErrorResourceProtector)MissingAuthorizationError   )FlaskJsonRequest)token_authenticated)raise_http_exceptionc                   @    e Zd ZdZd ZddZedd            Zd	dZdS )
r	   ax  A protecting method for resource servers. Creating a ``require_oauth``
    decorator easily with ResourceProtector::

        from authlib.integrations.flask_oauth2 import ResourceProtector

        require_oauth = ResourceProtector()

        # add bearer token validator
        from authlib.oauth2.rfc6750 import BearerTokenValidator
        from project.models import Token

        class MyBearerTokenValidator(BearerTokenValidator):
            def authenticate_token(self, token_string):
                return Token.query.filter_by(access_token=token_string).first()

        require_oauth.register_token_validator(MyBearerTokenValidator())

        # protect resource with require_oauth

        @app.route('/user')
        @require_oauth(['profile'])
        def user_profile():
            user = User.get(current_token.user_id)
            return jsonify(user.to_dict())

    c                     |j         }t          j        t          |                                                    }|                                }t          |||           dS )zRaise HTTPException for OAuth2Error. Developers can re-implement
        this method to customize the error response.

        :param error: OAuth2Error
        :raise: HTTPException
        N)status_coder   dumpsdictget_bodyget_headersr   )selferrorstatusbodyheaderss        h/var/www/piapp/venv/lib/python3.11/site-packages/authlib/integrations/flask_oauth2/resource_protector.pyraise_error_responsez&ResourceProtector.raise_error_response-   sV     "z$u~~//0011##%%VT733333    Nc                     t          t                    }||d<   |D ])}t          ||         t                    r||         g||<   * | j        dd|i|}t          j        | |           |t          _        |S )zA method to acquire current valid token with the given scope.

        :param scopes: a list of scope values
        :return: token object
        scopesr   )token )	r   _req
isinstancestrvalidate_requestr   sendr   authlib_server_oauth2_token)r   r   kwargsr   claimr    s         r   acquire_tokenzResourceProtector.acquire_token9   s     #4((!x 	0 	0E&--- 0!'u%%@@g@@@ U3333(-%r   c              #      K   	 |                      |          V  dS # t          $ r }|                     |           Y d}~dS d}~ww xY w)ae  The with statement of ``require_oauth``. Instead of using a
        decorator, you can use a with statement instead::

            @app.route('/api/user')
            def user_api():
                with require_oauth.acquire('profile') as token:
                    user = User.get(token.user_id)
                    return jsonify(user.to_dict())
        N)r*   r   r   )r   r   r   s      r   acquirezResourceProtector.acquireJ   sp      	-$$V,,,,,,, 	- 	- 	-%%e,,,,,,,,,	-s    
AAAFc                 (     ||d<    fd}|S )Nr   c                 N     t          j                    fd            }|S )Nc                      	  j         di  nb# t          $ r.}r | i |cY d }~S                     |           Y d }~n/d }~wt          $ r}                    |           Y d }~nd }~ww xY w | i |S )Nr!   )r*   r
   r   r   )argsr(   r   claimsfoptionalr   s      r   	decoratedz>ResourceProtector.__call__.<locals>.wrapper.<locals>.decorated_   s    5&D&0000000 5 5 5 2 q$1&11111111--e44444444" 5 5 5--e444444445q$)&)))s*    
A0	AA0AA0A++A0)	functoolswraps)r2   r4   r1   r3   r   s   ` r   wrapperz+ResourceProtector.__call__.<locals>.wrapper^   sI    _Q	* 	* 	* 	* 	* 	* 	*  	* r   r!   )r   r   r3   r(   r7   r1   s   ` `  @r   __call__zResourceProtector.__call__Z   s>    !x	 	 	 	 	 	 	 r   )N)NF)	__name__
__module____qualname____doc__r   r*   r   r,   r8   r!   r   r   r	   r	      su         4
4 
4 
4   " - - - ^-     r   r	   c                  *    t          j        d          S )Nr'   )r   getr!   r   r   _get_current_tokenr?   n   s    5.///r   )r5   
contextlibr   flaskr   r   r   r"   werkzeug.localr   authlib.oauth2r   r	   _ResourceProtectorauthlib.oauth2.rfc6749r
   requestsr   signalsr   errorsr   r?   current_tokenr!   r   r   <module>rJ      s6       % % % % % %         ! ! ! ! ! ! % % % % % %             ' & & & & & ( ( ( ( ( ( ( ( ( ( ( (Y Y Y Y Y* Y Y Yx0 0 0 
-..r   