Skip to content

Commit

Permalink
Added error_page for the /authorize endpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanHuot committed Jul 26, 2018
1 parent accc1df commit 052eaee
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
16 changes: 12 additions & 4 deletions bottle_oauthlib/oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,10 @@ def set_response(bottle_request, bottle_response, status, headers, body, force_j


class BottleOAuth2(object):
def __init__(self, bottle_server):
def __init__(self, bottle_server, error_uri=None):
self._bottle = bottle_server
self._oauthlib = None
self._error_uri = error_uri

def initialize(self, oauthlib_server):
self._oauthlib = oauthlib_server
Expand Down Expand Up @@ -212,9 +213,16 @@ def wrapper():
uri, http_method, body, headers = extract_params(bottle.request)
scope = bottle.request.params.get('scope', '').split(' ')

resp_headers, resp_body, resp_status = self._oauthlib.create_authorization_response(
uri, http_method=http_method, body=body, headers=headers, scopes=scope
)
try:
resp_headers, resp_body, resp_status = self._oauthlib.create_authorization_response(
uri, http_method=http_method, body=body, headers=headers, scopes=scope
)
except FatalClientError as e:
if self._error_uri:
raise bottle.HTTPResponse(status=302, headers={"Location": add_params_to_uri(
self._error_uri, {'error': e.error, 'error_description': e.description}
)})
raise e
set_response(bottle.request, bottle.response, resp_status, resp_headers, resp_body)

func_response = f()
Expand Down
34 changes: 25 additions & 9 deletions tests/test_oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
from bottle import tob
from tests.bottle_tools import ServerTestBase
from bottle_oauthlib.oauth2 import BottleOAuth2
import oauthlib
from oauthlib.oauth2 import Server
from tests import AttrDict
from unittest import mock
import unittest
from unittest import mock


class test_not_initialized(ServerTestBase):
Expand Down Expand Up @@ -127,6 +128,7 @@ def test(): return "my=custom&body="
mocked.assert_called_once()


@unittest.skip("waitin' for oauthlib release of introspect support")
class test_create_introspect_decorators(ServerTestBase):
def setUp(self):
super().setUp()
Expand All @@ -139,7 +141,6 @@ def setUp(self):
"Content-Type": "application/json"
}, "{'valid': true, 'foo': 'bar'}", "200 FooOK")

@unittest.skip("remove when introspect branch is merged into oauthlib")
def test_valid_response(self):
@bottle.route('/foo')
@self.oauth.create_introspect_response()
Expand All @@ -153,7 +154,6 @@ def test(): return None
self.assertEqual(app_response['header']['Content-Type'], "application/x-www-form-urlencoded")
mocked.assert_called_once()

@unittest.skip("remove when introspect branch is merged into oauthlib")
def test_override_response(self):
@bottle.route('/foo')
@self.oauth.create_introspect_response()
Expand All @@ -166,12 +166,12 @@ def test(): return "{'valid': false}"
self.assertEqual(app_response['body'], tob("{'valid': false}"))
self.assertEqual(app_response['header']['Content-Type'], "application/json")
mocked.assert_called_once()


class test_create_authorization_decorators(ServerTestBase):
def setUp(self):
super().setUp()
self.oauth = BottleOAuth2(self.app)
self.oauth = BottleOAuth2(self.app, error_uri="/errorpage")
self.validator = mock.MagicMock()
self.server = Server(self.validator)
self.oauth.initialize(self.server)
Expand All @@ -185,7 +185,8 @@ def test_valid_response(self):
@self.oauth.create_authorization_response()
def test(): return None

with mock.patch("oauthlib.oauth2.Server.create_authorization_response", return_value=self.fake_response) as mocked:
with mock.patch("oauthlib.oauth2.Server.create_authorization_response",
return_value=self.fake_response) as mocked:
app_response = self.urlopen("/foo", method="GET", query="scope=admin%20view%20write")
self.assertEqual(app_response['code'], 200)
self.assertEqual(app_response['status'], "FooOK")
Expand All @@ -199,14 +200,31 @@ def test_override_response(self):
@self.oauth.create_authorization_response()
def test(): return "my=custom&body="

with mock.patch("oauthlib.oauth2.Server.create_authorization_response", return_value=self.fake_response) as mocked:
with mock.patch("oauthlib.oauth2.Server.create_authorization_response",
return_value=self.fake_response) as mocked:
app_response = self.urlopen("/foo")
self.assertEqual(app_response['code'], 200)
self.assertEqual(app_response['status'], "FooOK")
self.assertEqual(app_response['body'], tob("my=custom&body="))
self.assertEqual(app_response['header']['Content-Type'], "application/x-www-form-urlencoded")
mocked.assert_called_once()

def test_fatal_error(self):
@bottle.route('/foo')
@self.oauth.create_authorization_response()
def test(): return None

with mock.patch("oauthlib.oauth2.Server.create_authorization_response",
side_effect=oauthlib.oauth2.InvalidClientIdError()) as mocked:
app_response = self.urlopen("/foo")
self.assertEqual(app_response['code'], 302)
self.assertEqual(app_response['status'], "Found")
self.assertEqual(
app_response['header']['Location'],
"/errorpage?error=invalid_request&error_description=Invalid+client_id+parameter+value."
)
mocked.assert_called_once()


class test_create_revocation_decorators(ServerTestBase):
def setUp(self):
Expand All @@ -228,5 +246,3 @@ def test(): return None
self.assertEqual(app_response['code'], 200)
self.assertEqual(app_response['status'], "fooOK")
mocked.assert_called_once()


0 comments on commit 052eaee

Please sign in to comment.