
    Ld5                         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	   a~  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.query.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        ZF:\djangOuth\env\Lib\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                    }t          |t                    r|g}|                     ||          }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
        )token)	r   _req
isinstancestrvalidate_requestr   sendr   authlib_server_oauth2_token)r   scopesr   r   s       r   acquire_tokenzResourceProtector.acquire_token9   sb     #4((fc"" 	XF%%fg66 U3333(-%r   c              #      K   	 |                      |          V  dS # t          $ r }|                     |           Y d}~dS d}~ww xY w)ak  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.query.get(token.user_id)
                    return jsonify(user.to_dict())
        N)r'   r   r   )r   r&   r   s      r   acquirezResourceProtector.acquireH   sp      	-$$V,,,,,,, 	- 	- 	-%%e,,,,,,,,,	-s    
AAAFc                       fd}|S )Nc                 N     t          j                    fd            }|S )Nc                     	                                 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 N)r'   r
   r   r   )argskwargsr   foptionalr&   r   s      r   	decoratedz>ResourceProtector.__call__.<locals>.wrapper.<locals>.decoratedZ   s    5&&v....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*    
A8	AA8AA8A33A8)	functoolswraps)r0   r2   r1   r&   r   s   ` r   wrapperz+ResourceProtector.__call__.<locals>.wrapperY   sI    _Q	* 	* 	* 	* 	* 	* 	*  	* r    )r   r&   r1   r5   s   ``` r   __call__zResourceProtector.__call__X   s/    	 	 	 	 	 	 	 r   r-   )NF)	__name__
__module____qualname____doc__r   r'   r   r)   r7   r6   r   r   r	   r	      su         4
4 
4 
4    - - - ^-     r   r	   c                  *    t          j        d          S )Nr%   )r   getr6   r   r   _get_current_tokenr>   i   s    5.///r   )r3   
contextlibr   flaskr   r   r   r    werkzeug.localr   authlib.oauth2r   r	   _ResourceProtectorauthlib.oauth2.rfc6749r
   requestsr   signalsr   errorsr   r>   current_tokenr6   r   r   <module>rI      s6       % % % % % %         ! ! ! ! ! ! % % % % % %             ' & & & & & ( ( ( ( ( ( ( ( ( ( ( (T T T T T* T T Tn0 0 0 
-..r   