Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Oauth2 draft25 server #61

Closed
wants to merge 4 commits into from

2 participants

@mvantellingen

This makes the unittests pass

@ib-lundgren
Collaborator

Thanks for pushing towards OAuth 2 Server support!

We now have 3 versions spread out with @sontek starting on some (#58), my local one which is close to complete authorization grant code and implicit grant code support and this one. This is my fault since after doing the initial work way back this summer I wanted to reorganize it a bit and broke all the tests, which is the state it has remained in since, and because of this I never pushed it.

I will try and get around to cleaning it up and merging it in here this week and if I can't find time for that I'll just push the slightly messy code I have now and whoever feel like it can tear it apart in search for useful bits.

@mvantellingen

Good to hear. It would be great if you could push your code, we can clean it up afterwards. I currently have a few days to work on getting a good oauth2 provider.

@ib-lundgren
Collaborator
@ib-lundgren
Collaborator

Thanks again for this PR. I'm closing as I've manually merged pieces of this code during the unification of all three oauth 2 branches =)

@ib-lundgren ib-lundgren closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
11 oauthlib/oauth2/draft25/__init__.py
@@ -12,8 +12,7 @@
from .parameters import prepare_grant_uri, prepare_token_request
from .parameters import parse_authorization_code_response
from .parameters import parse_implicit_response, parse_token_response
-from .exceptions import (InvalidClientIdentifier, MissingRedirectURI,
- InvalidRedirectURI)
+from .server import AuthorizationServer
AUTH_HEADER = u'auth_header'
@@ -520,11 +519,3 @@ def parse_request_body_response(self, body, scope=None):
response = parse_token_response(body, scope=scope)
self._populate_attributes(response)
return response
-
-class AuthorizationServer(object):
- def client_redirect_uris(self, client_identifier):
- raise NotImplementedError("Must be implemented by inheriting classes.")
-
- def redirect_uri(client_identifier, redirect_uri=None):
- raise NotImplementedError("TODO")
-
View
28 oauthlib/oauth2/draft25/server.py
@@ -0,0 +1,28 @@
+from .exceptions import MissingRedirectURI, InvalidRedirectURI
+from .utils import valid_redirect_uri, compare_uris
+
+
+class AuthorizationServer(object):
+ def client_redirect_uris(self, client_identifier):
+ raise NotImplementedError("Must be implemented by inheriting classes.")
+
+ def redirect_uri(self, client_identifier, redirect_uri=None):
+ redirect_uris = self.client_redirect_uris(client_identifier)
+
+ # If multiple redirection URIs have been registered, if only part of
+ # the redirection URI has been registered, or if no redirection URI has
+ # been registered, the client MUST include a redirection URI.
+ if not redirect_uri and len(redirect_uris) != 1:
+ raise MissingRedirectURI()
+
+ # If an redirect_uri is given then check that it is valid and is one
+ # of the optionally URI's returned by `client_redirect_uris`.
+ if redirect_uri:
+ if not valid_redirect_uri(redirect_uri):
+ raise InvalidRedirectURI()
+ if redirect_uris:
+ if not compare_uris(redirect_uri, redirect_uris):
+ raise InvalidRedirectURI()
+
+ return redirect_uri
+ return redirect_uris[0]
View
59 oauthlib/oauth2/draft25/utils.py
@@ -55,3 +55,62 @@ def escape(u):
if not isinstance(u, unicode):
raise ValueError('Only unicode objects are escapable.')
return urllib.quote(u.encode('utf-8'), safe='~')
+
+
+def valid_redirect_uri(uri):
+ """Validate that the redirection endpoint URI is well formed.
+
+ The redirection endpoint URI MUST be an absolute URI as defined by
+ [RFC3986] section 4.3. The endpoint URI MAY include an
+ "application/x-www-form-urlencoded" formatted
+ ([W3C.REC-html401-19991224]) query component ([RFC3986] section 3.4),
+ which MUST be retained when adding additional query parameters. The
+ endpoint URI MUST NOT include a fragment component.
+
+ .. `Section 3.1.2`: http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-3.1.2
+
+ """
+ result = urlparse.urlparse(uri)
+ if not result.scheme or result.fragment:
+ return False
+ return True
+
+
+def normalize_uri(uri):
+ """Normalize the URI according to rfc3986
+
+ This currently just returns the same uri since there is no rfc3986
+ compliant module which supports normalization.
+
+ """
+ return uri
+
+
+def compare_uris(src, targets):
+ """Compare the `src` URI to the URI's in the targets
+
+ If multiple redirection URIs have been registered, if only part of
+ the redirection URI has been registered, or if no redirection URI has
+ been registered, the client MUST include a redirection URI with the
+ authorization request using the "redirect_uri" request parameter.
+
+ When a redirection URI is included in an authorization request, the
+ authorization server MUST compare and match the value received
+ against at least one of the registered redirection URIs (or URI
+ components) as defined in [RFC3986] section 6, if any redirection
+ URIs were registered. If the client registration included the full
+ redirection URI, the authorization server MUST compare the two URIs
+ using simple string comparison as defined in [RFC3986] section 6.2.1.
+
+ .. `Section 3.1.2.3`: http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-3.1.2.3
+
+ TODO: Implement completely
+
+ """
+ parts = urlparse.urlsplit(normalize_uri(src))
+ src = urlparse.urlunsplit(parts[:3] + (None,) + parts[4:])
+
+ for uri in targets:
+ if src == normalize_uri(uri):
+ return True
+ return False
View
9 tests/oauth2/draft25/test_server.py
@@ -4,7 +4,7 @@
from ...unittest import TestCase
-from oauthlib.oauth2.draft25 import AuthorizationServer
+from oauthlib.oauth2.draft25.server import AuthorizationServer
from oauthlib.oauth2.draft25.exceptions import (InvalidClientIdentifier,
MissingRedirectURI, InvalidRedirectURI)
@@ -15,7 +15,7 @@ class AuthorizationEndpointTestCase(TestCase):
def test_redirection_uri_invalid_client_identifier(self):
class Server(AuthorizationServer):
def client_redirect_uris(self, client_identifier):
- raise InvalidClientIdentifier(client_identifer)
+ raise InvalidClientIdentifier(client_identifier)
server = Server()
# http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-4.1.2.1
@@ -49,7 +49,8 @@ def client_redirect_uris(self, client_identifier):
# The endpoint URI MAY include an "application/x-www-form-urlencoded"
# formatted query component
request_redirect_uri = 'http://example.com/?foo=bar'
- redirect_uri = server.redirect_uri('client_identifier', redirect_uri)
+ redirect_uri = server.redirect_uri('client_identifier',
+ request_redirect_uri)
self.assertEqual(request_redirect_uri, redirect_uri)
# http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-3.1.2
@@ -99,7 +100,7 @@ class Server(AuthorizationServer):
'http://example.com/another/path/to/redirect/',
)
def client_redirect_uris(self, client_identifier):
- return uris
+ return self.uris
server = Server()
# http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-3.1.2.3
Something went wrong with that request. Please try again.