o
    b                     @   s   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mZ d dlmZmZ d	d
lmZ d	dlmZ G dd deZdd Ze	eZdS )    N)contextmanager)json)request)_app_ctx_stack)
LocalProxy)OAuth2ErrorResourceProtector)MissingAuthorizationErrorHttpRequest   )token_authenticated)raise_http_exceptionc                   @   s:   e Zd ZdZdd ZdddZeddd	Zd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()

            def request_invalid(self, request):
                return False

            def token_revoked(self, token):
                return False

        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                 C   s0   |j }t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_bodyZget_headersr   )selferrorstatusbodyheaders r   s/var/www/secure340b-portal/env/lib/python3.10/site-packages/authlib/integrations/flask_oauth2/resource_protector.pyraise_error_response4   s   z&ResourceProtector.raise_error_responseNANDc                 C   sR   t tjtjtjtj}t|s| }| |||}t	j
| |d tj}||_|S )zA method to acquire current valid token with the given scope.

        :param scope: string or list of scope values
        :param operator: value of "AND" or "OR"
        :return: token object
        )token)r
   _reqmethod	full_pathdatar   callableupperZvalidate_requestr   sendr   topauthlib_server_oauth2_token)r   scopeoperatorr   r   ctxr   r   r   acquire_token@   s   zResourceProtector.acquire_tokenc              
   c   sH    z
|  ||V  W dS  ty# } z| | W Y d}~dS d}~w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&   r   r   r   r   acquireU   s   zResourceProtector.acquireFc                    s    fdd}|S )Nc                    s"   t   fdd}|S )Nc               
      s   z  W n< ty. } zr | i |W  Y d }~S | W Y d }~nd }~w tyD } z| W Y d }~nd }~ww  | i |S )N)r(   r	   r   r   )argskwargsr   )fr&   optionalr%   r   r   r   	decoratedg   s   z>ResourceProtector.__call__.<locals>.wrapper.<locals>.decorated)	functoolswraps)r,   r.   r&   r-   r%   r   )r,   r   wrapperf   s   
z+ResourceProtector.__call__.<locals>.wrapperr   )r   r%   r&   r-   r2   r   r1   r   __call__e   s   zResourceProtector.__call__)Nr   )Nr   F)	__name__
__module____qualname____doc__r   r(   r   r)   r3   r   r   r   r   r      s     
r   c                  C   s   t j} t| dd S )Nr$   )r   r#   getattr)r'   r   r   r   _get_current_tokenv   s   r9   )r/   
contextlibr   Zflaskr   r   r   r   Zwerkzeug.localr   Zauthlib.oauth2r   r   Z_ResourceProtectorZauthlib.oauth2.rfc6749r	   r
   Zsignalsr   errorsr   r9   current_tokenr   r   r   r   <module>   s    c