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 logging 
    9 
    10from oauthlib.common import Request 
    11 
    12from .base import BaseEndpoint, catch_errors_and_unavailability 
    13 
    14log = logging.getLogger(__name__) 
    15 
    16 
    17class ResourceEndpoint(BaseEndpoint): 
    18 
    19    """Authorizes access to protected resources. 
    20 
    21    The client accesses protected resources by presenting the access 
    22    token to the resource server.  The resource server MUST validate the 
    23    access token and ensure that it has not expired and that its scope 
    24    covers the requested resource.  The methods used by the resource 
    25    server to validate the access token (as well as any error responses) 
    26    are beyond the scope of this specification but generally involve an 
    27    interaction or coordination between the resource server and the 
    28    authorization server:: 
    29 
    30        # For most cases, returning a 403 should suffice. 
    31 
    32    The method in which the client utilizes the access token to 
    33    authenticate with the resource server depends on the type of access 
    34    token issued by the authorization server.  Typically, it involves 
    35    using the HTTP "Authorization" request header field [RFC2617] with an 
    36    authentication scheme defined by the specification of the access 
    37    token type used, such as [RFC6750]:: 
    38 
    39        # Access tokens may also be provided in query and body 
    40        https://example.com/protected?access_token=kjfch2345sdf   # Query 
    41        access_token=sdf23409df   # Body 
    42    """ 
    43 
    44    def __init__(self, default_token, token_types): 
    45        BaseEndpoint.__init__(self) 
    46        self._tokens = token_types 
    47        self._default_token = default_token 
    48 
    49    @property 
    50    def default_token(self): 
    51        return self._default_token 
    52 
    53    @property 
    54    def default_token_type_handler(self): 
    55        return self.tokens.get(self.default_token) 
    56 
    57    @property 
    58    def tokens(self): 
    59        return self._tokens 
    60 
    61    @catch_errors_and_unavailability 
    62    def verify_request(self, uri, http_method='GET', body=None, headers=None, 
    63                       scopes=None): 
    64        """Validate client, code etc, return body + headers""" 
    65        request = Request(uri, http_method, body, headers) 
    66        request.token_type = self.find_token_type(request) 
    67        request.scopes = scopes 
    68        token_type_handler = self.tokens.get(request.token_type, 
    69                                             self.default_token_type_handler) 
    70        log.debug('Dispatching token_type %s request to %r.', 
    71                  request.token_type, token_type_handler) 
    72        return token_type_handler.validate_request(request), request 
    73 
    74    def find_token_type(self, request): 
    75        """Token type identification. 
    76 
    77        RFC 6749 does not provide a method for easily differentiating between 
    78        different token types during protected resource access. We estimate 
    79        the most likely token type (if any) by asking each known token type 
    80        to give an estimation based on the request. 
    81        """ 
    82        estimates = sorted(((t.estimate_type(request), n) 
    83                            for n, t in self.tokens.items()), reverse=True) 
    84        return estimates[0][1] if estimates else None