summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIb Lundgren <ib.lundgren@gmail.com>2013-08-03 11:56:17 -0700
committerIb Lundgren <ib.lundgren@gmail.com>2013-08-03 11:56:17 -0700
commit5b8aa2d3762d5f800a1db3d07f15702cb007c7e9 (patch)
treefbde8ceaf25b34611b2b7ebb212b6592cbf58164
parentf794cf31971274766378faf140d60e5ec3807286 (diff)
parent517e01f5db428fe4c3e56119faad1760a8841c9f (diff)
downloadoauthlib-5b8aa2d3762d5f800a1db3d07f15702cb007c7e9.tar.gz
Merge pull request #199 from squirly/master
The authorization endpoint now returns a 200 on "oob" oauth_callbacks.
-rw-r--r--AUTHORS3
-rw-r--r--docs/oauth1/server.rst12
-rw-r--r--oauthlib/oauth1/rfc5849/endpoints/access_token.py19
-rw-r--r--oauthlib/oauth1/rfc5849/endpoints/authorization.py65
-rw-r--r--oauthlib/oauth1/rfc5849/endpoints/request_token.py19
-rw-r--r--oauthlib/oauth1/rfc5849/request_validator.py6
-rw-r--r--tests/oauth1/rfc5849/endpoints/test_access_token.py14
-rw-r--r--tests/oauth1/rfc5849/endpoints/test_authorization.py17
-rw-r--r--tests/oauth1/rfc5849/endpoints/test_base.py14
-rw-r--r--tests/oauth1/rfc5849/endpoints/test_request_token.py16
10 files changed, 110 insertions, 75 deletions
diff --git a/AUTHORS b/AUTHORS
index 4da117c..c2719db 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,4 +17,5 @@ Mackenzie Thompson
Hsiaoming Yang
Devin Sevilla
Clint Ecker
-Kyle Valade \ No newline at end of file
+Kyle Valade
+Tyler Jones (squirly)
diff --git a/docs/oauth1/server.rst b/docs/oauth1/server.rst
index cb00257..8fcfd2d 100644
--- a/docs/oauth1/server.rst
+++ b/docs/oauth1/server.rst
@@ -289,6 +289,7 @@ The example uses Flask but should be transferable to any framework.
from flask import Flask, redirect, Response, request, url_for
from oauthlib.oauth1 import OAuth1Error
+ import urlparse
app = Flask(__name__)
@@ -296,7 +297,7 @@ The example uses Flask but should be transferable to any framework.
@app.route('/request_token', methods=['POST'])
def request_token():
- _, h, b, s = provider.create_request_token_response(request.url,
+ h, b, s = provider.create_request_token_response(request.url,
http_method=request.method,
body=request.data,
headers=request.headers)
@@ -323,19 +324,22 @@ The example uses Flask but should be transferable to any framework.
def post_authorize():
realms = request.form.getlist('realms')
try:
- u, _, _, _ = provider.create_authorization_response(request.url,
+ h, b, s = provider.create_authorization_response(request.url,
http_method=request.method,
body=request.data,
headers=request.headers,
realms=realms)
- return redirect(u)
+ if s == 200:
+ return 'Your verifier is: ' + str(urlparse.parse_qs(b)['oauth_verifier'][0])
+ else:
+ return Response(b, status=s, headers=h)
except OAuth1Error as e:
return redirect(e.in_uri(url_for('/error')))
@app.route('/access_token', methods=['POST'])
def access_token():
- _, h, b, s = provider.create_access_token_response(request.url,
+ h, b, s = provider.create_access_token_response(request.url,
http_method=request.method,
body=request.data,
headers=request.headers)
diff --git a/oauthlib/oauth1/rfc5849/endpoints/access_token.py b/oauthlib/oauth1/rfc5849/endpoints/access_token.py
index 9950d5b..10d4ad0 100644
--- a/oauthlib/oauth1/rfc5849/endpoints/access_token.py
+++ b/oauthlib/oauth1/rfc5849/endpoints/access_token.py
@@ -57,18 +57,17 @@ class AccessTokenEndpoint(BaseEndpoint):
:param body: The request body as a string.
:param headers: The request headers as a dict.
:param credentials: A list of extra credentials to include in the token.
- :returns: A tuple of 4 elements.
- 1. None (uri but n/a for this endpoint, here for consistency.
- 2. A dict of headers to set on the response.
- 3. The response body as a string.
- 4. The response status code as an integer.
+ :returns: A tuple of 3 elements.
+ 1. A dict of headers to set on the response.
+ 2. The response body as a string.
+ 3. The response status code as an integer.
An example of a valid request::
>>> from your_validator import your_validator
>>> from oauthlib.oauth1 import AccessTokenEndpoint
>>> endpoint = AccessTokenEndpoint(your_validator)
- >>> u, h, b, s = endpoint.create_access_token_response(
+ >>> h, b, s = endpoint.create_access_token_response(
... 'https://your.provider/access_token?foo=bar',
... headers={
... 'Authorization': 'OAuth oauth_token=234lsdkf....'
@@ -76,8 +75,6 @@ class AccessTokenEndpoint(BaseEndpoint):
... credentials={
... 'my_specific': 'argument',
... })
- >>> u
- None
>>> h
{'Content-Type': 'application/x-www-form-urlencoded'}
>>> b
@@ -106,11 +103,11 @@ class AccessTokenEndpoint(BaseEndpoint):
request)
if valid:
token = self.create_access_token(request, credentials or {})
- return None, resp_headers, token, 200
+ return resp_headers, token, 200
else:
- return None, {}, None, 401
+ return {}, None, 401
except errors.OAuth1Error as e:
- return None, resp_headers, e.urlencoded, e.status_code
+ return resp_headers, e.urlencoded, e.status_code
def validate_access_token_request(self, request):
"""Validate an access token request.
diff --git a/oauthlib/oauth1/rfc5849/endpoints/authorization.py b/oauthlib/oauth1/rfc5849/endpoints/authorization.py
index 7fe39c4..5b78299 100644
--- a/oauthlib/oauth1/rfc5849/endpoints/authorization.py
+++ b/oauthlib/oauth1/rfc5849/endpoints/authorization.py
@@ -13,7 +13,10 @@ from oauthlib.common import Request, add_params_to_uri
from .base import BaseEndpoint
from .. import errors
-
+try:
+ from urllib import urlencode
+except ImportError:
+ from urllib.parse import urlencode
class AuthorizationEndpoint(BaseEndpoint):
"""An endpoint responsible for letting authenticated users authorize access
@@ -59,33 +62,48 @@ class AuthorizationEndpoint(BaseEndpoint):
:param body: The request body as a string.
:param headers: The request headers as a dict.
:param credentials: A list of credentials to include in the verifier.
- :returns: A tuple of 4 elements.
- 1. The URI to be used to redirect the user back to client.
- 2. A dict of headers to set on the response.
- 3. The response body as a string.
- 4. The response status code as an integer.
+ :returns: A tuple of 3 elements.
+ 1. A dict of headers to set on the response.
+ 2. The response body as a string.
+ 3. The response status code as an integer.
+
+ If the callback URI tied to the current token is "oob", a response with
+ a 200 status code will be returned. In this case, it may be desirable to
+ modify the response to better display the verifier to the client.
- An example of a valid request::
+ An example of an authorization request::
>>> from your_validator import your_validator
- >>> from oauthlib.oauth1 import RequestTokenEndpoint
- >>> endpoint = RequestTokenEndpoint(your_validator)
- >>> u, h, b, s = endpoint.create_request_token_response(
- ... 'https://your.provider/request_token?foo=bar',
- ... headers={
- ... 'Authorization': 'OAuth realm=movies user, oauth_....'
- ... },
+ >>> from oauthlib.oauth1 import AuthorizationEndpoint
+ >>> endpoint = AuthorizationEndpoint(your_validator)
+ >>> h, b, s = endpoint.create_authorization_response(
+ ... 'https://your.provider/authorize?oauth_token=...',
... credentials={
... 'extra': 'argument',
... })
- >>> u
- 'https://the.client/callback?oauth_verifier=...&mextra=argument'
>>> h
- {}
+ {'Location': 'https://the.client/callback?oauth_verifier=...&extra=argument'}
>>> b
- ''
+ None
>>> s
302
+
+ An example of a request with an "oob" callback::
+
+ >>> from your_validator import your_validator
+ >>> from oauthlib.oauth1 import AuthorizationEndpoint
+ >>> endpoint = AuthorizationEndpoint(your_validator)
+ >>> h, b, s = endpoint.create_authorization_response(
+ ... 'https://your.provider/authorize?foo=bar',
+ ... credentials={
+ ... 'extra': 'argument',
+ ... })
+ >>> h
+ {'Content-Type': 'application/x-www-form-urlencoded'}
+ >>> b
+ 'oauth_verifier=...&extra=argument'
+ >>> s
+ 200
"""
request = self._create_request(uri, http_method=http_method, body=body,
headers=headers)
@@ -104,11 +122,16 @@ class AuthorizationEndpoint(BaseEndpoint):
description=('User granted access to realms outside of '
'what the client may request.'))
+ verifier = self.create_verifier(request, credentials or {})
redirect_uri = self.request_validator.get_redirect_uri(
request.resource_owner_key, request)
- verifier = self.create_verifier(request, credentials or {})
- uri = add_params_to_uri(redirect_uri, verifier.items())
- return uri, {}, None, 302
+ if redirect_uri == 'oob':
+ response_headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+ response_body = urlencode(verifier)
+ return response_headers, response_body, 200
+ else:
+ populated_redirect = add_params_to_uri(redirect_uri, verifier.items())
+ return {'Location': populated_redirect}, None, 302
def get_realms_and_credentials(self, uri, http_method='GET', body=None,
headers=None):
diff --git a/oauthlib/oauth1/rfc5849/endpoints/request_token.py b/oauthlib/oauth1/rfc5849/endpoints/request_token.py
index 2956bcc..424e33f 100644
--- a/oauthlib/oauth1/rfc5849/endpoints/request_token.py
+++ b/oauthlib/oauth1/rfc5849/endpoints/request_token.py
@@ -51,18 +51,17 @@ class RequestTokenEndpoint(BaseEndpoint):
:param body: The request body as a string.
:param headers: The request headers as a dict.
:param credentials: A list of extra credentials to include in the token.
- :returns: A tuple of 4 elements.
- 1. None (uri but n/a for this endpoint, here for consistency.
- 2. A dict of headers to set on the response.
- 3. The response body as a string.
- 4. The response status code as an integer.
+ :returns: A tuple of 3 elements.
+ 1. A dict of headers to set on the response.
+ 2. The response body as a string.
+ 3. The response status code as an integer.
An example of a valid request::
>>> from your_validator import your_validator
>>> from oauthlib.oauth1 import RequestTokenEndpoint
>>> endpoint = RequestTokenEndpoint(your_validator)
- >>> u, h, b, s = endpoint.create_request_token_response(
+ >>> h, b, s = endpoint.create_request_token_response(
... 'https://your.provider/request_token?foo=bar',
... headers={
... 'Authorization': 'OAuth realm=movies user, oauth_....'
@@ -70,8 +69,6 @@ class RequestTokenEndpoint(BaseEndpoint):
... credentials={
... 'my_specific': 'argument',
... })
- >>> u
- None
>>> h
{'Content-Type': 'application/x-www-form-urlencoded'}
>>> b
@@ -100,11 +97,11 @@ class RequestTokenEndpoint(BaseEndpoint):
request)
if valid:
token = self.create_request_token(request, credentials or {})
- return None, resp_headers, token, 200
+ return resp_headers, token, 200
else:
- return None, {}, None, 401
+ return {}, None, 401
except errors.OAuth1Error as e:
- return None, resp_headers, e.urlencoded, e.status_code
+ return resp_headers, e.urlencoded, e.status_code
def validate_request_token_request(self, request):
"""Validate a request token request.
diff --git a/oauthlib/oauth1/rfc5849/request_validator.py b/oauthlib/oauth1/rfc5849/request_validator.py
index 70ce6d9..933a65a 100644
--- a/oauthlib/oauth1/rfc5849/request_validator.py
+++ b/oauthlib/oauth1/rfc5849/request_validator.py
@@ -360,12 +360,16 @@ class RequestValidator(object):
raise NotImplementedError("Subclasses must implement this function.")
def get_redirect_uri(self, token, request):
- """Get the redirect uri associated with a request token.
+ """Get the redirect URI associated with a request token.
:param token: The request token string.
:param request: An oauthlib.common.Request object.
:returns: The redirect URI associated with the request token.
+ It may be desirable to return a custom URI if the redirect is set to "oob".
+ In this case, the user will be redirected to the returned URI and at that
+ endpoint the verifier can be displayed.
+
This method is used by
* AuthorizationEndpoint
diff --git a/tests/oauth1/rfc5849/endpoints/test_access_token.py b/tests/oauth1/rfc5849/endpoints/test_access_token.py
index 0596eba..8245f61 100644
--- a/tests/oauth1/rfc5849/endpoints/test_access_token.py
+++ b/tests/oauth1/rfc5849/endpoints/test_access_token.py
@@ -39,33 +39,33 @@ class AccessTokenEndpointTest(TestCase):
def test_check_request_token(self):
self.validator.check_request_token.return_value = False
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_check_verifier(self):
self.validator.check_verifier.return_value = False
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_validate_client_key(self):
self.validator.validate_client_key.return_value = False
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
def test_validate_request_token(self):
self.validator.validate_request_token.return_value = False
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
def test_validate_verifier(self):
self.validator.validate_verifier.return_value = False
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
@@ -75,12 +75,12 @@ class AccessTokenEndpointTest(TestCase):
resource_owner_secret='secret',
verifier='verfier')
_, headers, _ = client.sign(self.uri + '/extra')
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=headers)
self.assertEqual(s, 401)
def test_valid_request(self):
- u, h, b, s = self.endpoint.create_access_token_response(
+ h, b, s = self.endpoint.create_access_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 200)
self.assertIn('oauth_token', b)
diff --git a/tests/oauth1/rfc5849/endpoints/test_authorization.py b/tests/oauth1/rfc5849/endpoints/test_authorization.py
index c3876e1..d6b1a05 100644
--- a/tests/oauth1/rfc5849/endpoints/test_authorization.py
+++ b/tests/oauth1/rfc5849/endpoints/test_authorization.py
@@ -15,7 +15,6 @@ class ResourceEndpointTest(TestCase):
self.validator.verify_request_token.return_value = True
self.validator.verify_realms.return_value = True
self.validator.get_realms.return_value = ['test']
- self.validator.get_redirect_uri.return_value = 'https://c.b/cb'
self.validator.save_verifier = MagicMock()
self.endpoint = AuthorizationEndpoint(self.validator)
self.uri = 'https://i.b/authorize?oauth_token=foo'
@@ -39,7 +38,17 @@ class ResourceEndpointTest(TestCase):
realms=['bar'])
def test_create_authorization_response(self):
- u, h, b, s = self.endpoint.create_authorization_response(self.uri)
+ self.validator.get_redirect_uri.return_value = 'https://c.b/cb'
+ h, b, s = self.endpoint.create_authorization_response(self.uri)
self.assertEqual(s, 302)
- self.assertTrue(u.startswith('https://c.b/cb'))
- self.assertIn('oauth_verifier', u)
+ self.assertIn('Location', h)
+ self.assertTrue(location.startswith('https://c.b/cb'))
+ self.assertIn('oauth_verifier', location)
+
+ def test_create_authorization_response(self):
+ self.validator.get_redirect_uri.return_value = 'oob'
+ h, b, s = self.endpoint.create_authorization_response(self.uri)
+ self.assertEqual(s, 200)
+ self.assertNotIn('Location', h)
+ self.assertIn('oauth_verifier', b)
+ self.assertIn('oauth_token', b)
diff --git a/tests/oauth1/rfc5849/endpoints/test_base.py b/tests/oauth1/rfc5849/endpoints/test_base.py
index f175e6d..1c6bd33 100644
--- a/tests/oauth1/rfc5849/endpoints/test_base.py
+++ b/tests/oauth1/rfc5849/endpoints/test_base.py
@@ -27,13 +27,13 @@ class BaseEndpointTest(TestCase):
def test_ssl_enforcement(self):
uri, headers, _ = self.client.sign('http://i.b/request_token')
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
uri, headers=headers)
self.assertEqual(s, 400)
self.assertIn('insecure_transport_protocol', b)
def test_missing_parameters(self):
- u, h, b, s = self.endpoint.create_request_token_response(self.uri)
+ h, b, s = self.endpoint.create_request_token_response(self.uri)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
@@ -41,7 +41,7 @@ class BaseEndpointTest(TestCase):
headers = {}
headers['Authorization'] = self.headers['Authorization'].replace(
'HMAC', 'RSA')
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=headers)
self.assertEqual(s, 400)
self.assertIn('invalid_signature_method', b)
@@ -50,7 +50,7 @@ class BaseEndpointTest(TestCase):
headers = {}
headers['Authorization'] = self.headers['Authorization'].replace(
'1.0', '2.0')
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
@@ -61,21 +61,21 @@ class BaseEndpointTest(TestCase):
headers['Authorization'] = sub('timestamp="\d*k?"',
'timestamp="%s"' % pattern,
self.headers['Authorization'])
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_client_key_check(self):
self.validator.check_client_key.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_noncecheck(self):
self.validator.check_nonce.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
diff --git a/tests/oauth1/rfc5849/endpoints/test_request_token.py b/tests/oauth1/rfc5849/endpoints/test_request_token.py
index 47e2c10..773dedf 100644
--- a/tests/oauth1/rfc5849/endpoints/test_request_token.py
+++ b/tests/oauth1/rfc5849/endpoints/test_request_token.py
@@ -34,45 +34,45 @@ class RequestTokenEndpointTest(TestCase):
def test_check_redirect_uri(self):
client = Client('foo')
uri, headers, _ = client.sign(self.uri)
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
uri, headers=headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_check_realms(self):
self.validator.check_realms.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 400)
self.assertIn('invalid_request', b)
def test_validate_client_key(self):
self.validator.validate_client_key.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
def test_validate_realms(self):
self.validator.validate_requested_realms.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
def test_validate_redirect_uri(self):
self.validator.validate_redirect_uri.return_value = False
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 401)
def test_validate_signature(self):
client = Client('foo', callback_uri='https://c.b/cb')
_, headers, _ = client.sign(self.uri + '/extra')
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=headers)
self.assertEqual(s, 401)
def test_valid_request(self):
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
self.uri, headers=self.headers)
self.assertEqual(s, 200)
self.assertIn('oauth_token', b)
@@ -85,7 +85,7 @@ class RequestTokenEndpointTest(TestCase):
client_secret='bar')
uri = self.uri + '?realm=foo'
_, headers, _ = client.sign(uri)
- u, h, b, s = self.endpoint.create_request_token_response(
+ h, b, s = self.endpoint.create_request_token_response(
uri, headers=headers)
self.assertEqual(s, 200)
self.assertIn('oauth_token', b)