1""" 
    2oauthlib.oauth2.rfc6749 
    3~~~~~~~~~~~~~~~~~~~~~~~ 
    4 
    5This module is an implementation of various logic needed 
    6for consuming and providing OAuth 2.0 RFC6749. 
    7""" 
    8import functools 
    9import logging 
    10 
    11from ..errors import ( 
    12    FatalClientError, InvalidClientError, InvalidRequestError, OAuth2Error, 
    13    ServerError, TemporarilyUnavailableError, UnsupportedTokenTypeError, 
    14) 
    15 
    16log = logging.getLogger(__name__) 
    17 
    18 
    19class BaseEndpoint: 
    20 
    21    def __init__(self): 
    22        self._available = True 
    23        self._catch_errors = False 
    24        self._valid_request_methods = None 
    25 
    26    @property 
    27    def valid_request_methods(self): 
    28        return self._valid_request_methods 
    29 
    30    @valid_request_methods.setter 
    31    def valid_request_methods(self, valid_request_methods): 
    32        if valid_request_methods is not None: 
    33            valid_request_methods = [x.upper() for x in valid_request_methods] 
    34        self._valid_request_methods = valid_request_methods 
    35 
    36 
    37    @property 
    38    def available(self): 
    39        return self._available 
    40 
    41    @available.setter 
    42    def available(self, available): 
    43        self._available = available 
    44 
    45    @property 
    46    def catch_errors(self): 
    47        return self._catch_errors 
    48 
    49    @catch_errors.setter 
    50    def catch_errors(self, catch_errors): 
    51        self._catch_errors = catch_errors 
    52 
    53    def _raise_on_missing_token(self, request): 
    54        """Raise error on missing token.""" 
    55        if not request.token: 
    56            raise InvalidRequestError(request=request, 
    57                                      description='Missing token parameter.') 
    58    def _raise_on_invalid_client(self, request): 
    59        """Raise on failed client authentication.""" 
    60        if self.request_validator.client_authentication_required(request): 
    61            if not self.request_validator.authenticate_client(request): 
    62                log.debug('Client authentication failed, %r.', request) 
    63                raise InvalidClientError(request=request) 
    64        elif not self.request_validator.authenticate_client_id(request.client_id, request): 
    65            log.debug('Client authentication failed, %r.', request) 
    66            raise InvalidClientError(request=request) 
    67 
    68    def _raise_on_unsupported_token(self, request): 
    69        """Raise on unsupported tokens.""" 
    70        if (request.token_type_hint and 
    71            request.token_type_hint in self.valid_token_types and 
    72            request.token_type_hint not in self.supported_token_types): 
    73            raise UnsupportedTokenTypeError(request=request) 
    74 
    75    def _raise_on_bad_method(self, request): 
    76        if self.valid_request_methods is None: 
    77            raise ValueError('Configure "valid_request_methods" property first') 
    78        if request.http_method.upper() not in self.valid_request_methods: 
    79            raise InvalidRequestError(request=request, 
    80                                      description=('Unsupported request method %s' % request.http_method.upper())) 
    81 
    82    def _raise_on_bad_post_request(self, request): 
    83        """Raise if invalid POST request received 
    84        """ 
    85        if request.http_method.upper() == 'POST': 
    86            query_params = request.uri_query or "" 
    87            if query_params: 
    88                raise InvalidRequestError(request=request, 
    89                                          description=('URL query parameters are not allowed')) 
    90 
    91def catch_errors_and_unavailability(f): 
    92    @functools.wraps(f) 
    93    def wrapper(endpoint, uri, *args, **kwargs): 
    94        if not endpoint.available: 
    95            e = TemporarilyUnavailableError() 
    96            log.info('Endpoint unavailable, ignoring request %s.' % uri) 
    97            return {}, e.json, 503 
    98 
    99        if endpoint.catch_errors: 
    100            try: 
    101                return f(endpoint, uri, *args, **kwargs) 
    102            except OAuth2Error: 
    103                raise 
    104            except FatalClientError: 
    105                raise 
    106            except Exception as e: 
    107                error = ServerError() 
    108                log.warning( 
    109                    'Exception caught while processing request, %s.' % e) 
    110                return {}, error.json, 500 
    111        else: 
    112            return f(endpoint, uri, *args, **kwargs) 
    113    return wrapper