Merge pull request #3 from guyrt/master
[twitter-api-cdsw] / oauthlib / oauth2 / rfc6749 / endpoints / resource.py
diff --git a/oauthlib/oauth2/rfc6749/endpoints/resource.py b/oauthlib/oauth2/rfc6749/endpoints/resource.py
new file mode 100644 (file)
index 0000000..d03ed21
--- /dev/null
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+"""
+oauthlib.oauth2.rfc6749
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This module is an implementation of various logic needed
+for consuming and providing OAuth 2.0 RFC6749.
+"""
+from __future__ import absolute_import, unicode_literals
+
+import logging
+
+from oauthlib.common import Request
+
+from .base import BaseEndpoint, catch_errors_and_unavailability
+
+log = logging.getLogger(__name__)
+
+
+class ResourceEndpoint(BaseEndpoint):
+
+    """Authorizes access to protected resources.
+
+    The client accesses protected resources by presenting the access
+    token to the resource server.  The resource server MUST validate the
+    access token and ensure that it has not expired and that its scope
+    covers the requested resource.  The methods used by the resource
+    server to validate the access token (as well as any error responses)
+    are beyond the scope of this specification but generally involve an
+    interaction or coordination between the resource server and the
+    authorization server::
+
+        # For most cases, returning a 403 should suffice.
+
+    The method in which the client utilizes the access token to
+    authenticate with the resource server depends on the type of access
+    token issued by the authorization server.  Typically, it involves
+    using the HTTP "Authorization" request header field [RFC2617] with an
+    authentication scheme defined by the specification of the access
+    token type used, such as [RFC6750]::
+
+        # Access tokens may also be provided in query and body
+        https://example.com/protected?access_token=kjfch2345sdf   # Query
+        access_token=sdf23409df   # Body
+    """
+
+    def __init__(self, default_token, token_types):
+        BaseEndpoint.__init__(self)
+        self._tokens = token_types
+        self._default_token = default_token
+
+    @property
+    def default_token(self):
+        return self._default_token
+
+    @property
+    def default_token_type_handler(self):
+        return self.tokens.get(self.default_token)
+
+    @property
+    def tokens(self):
+        return self._tokens
+
+    @catch_errors_and_unavailability
+    def verify_request(self, uri, http_method='GET', body=None, headers=None,
+                       scopes=None):
+        """Validate client, code etc, return body + headers"""
+        request = Request(uri, http_method, body, headers)
+        request.token_type = self.find_token_type(request)
+        request.scopes = scopes
+        token_type_handler = self.tokens.get(request.token_type,
+                                             self.default_token_type_handler)
+        log.debug('Dispatching token_type %s request to %r.',
+                  request.token_type, token_type_handler)
+        return token_type_handler.validate_request(request), request
+
+    def find_token_type(self, request):
+        """Token type identification.
+
+        RFC 6749 does not provide a method for easily differentiating between
+        different token types during protected resource access. We estimate
+        the most likely token type (if any) by asking each known token type
+        to give an estimation based on the request.
+        """
+        estimates = sorted(((t.estimate_type(request), n)
+                            for n, t in self.tokens.items()))
+        return estimates[0][1] if len(estimates) else None

Benjamin Mako Hill || Want to submit a patch?