diff --git a/tests/views/test_oauth2.py b/tests/views/test_oauth2.py index 6d26baf6b5f1f910df17cbe9a04a3011eae1a169..01ec329228231c1b0cc8c518869f99d536d55a00 100644 --- a/tests/views/test_oauth2.py +++ b/tests/views/test_oauth2.py @@ -84,11 +84,23 @@ class TestViews(UffdTestCase): r = self.client.get(path=url_for('oauth2.authorize', response_type='code', client_id='test', state='teststate', scope='', redirect_uri='http://localhost:5009/callback'), follow_redirects=False) self.assert_authorization(r) + def test_authorization_access_denied(self): + self.login_as('user') + r = self.client.get(path=url_for('oauth2.authorize', response_type='code', client_id='test1', state='teststate', redirect_uri='http://localhost:5008/callback', scope='profile'), follow_redirects=False) + self.assertEqual(r.status_code, 302) + self.assertTrue(r.location.startswith('http://localhost:5008/callback')) + args = parse_qs(urlparse(r.location).query) + self.assertEqual(args['state'], ['teststate']) + self.assertEqual(args['error'], ['access_denied']) + def test_authorization_invalid_scope(self): self.login_as('user') r = self.client.get(path=url_for('oauth2.authorize', response_type='code', client_id='test', state='teststate', redirect_uri='http://localhost:5009/callback', scope='invalid'), follow_redirects=False) - self.assertEqual(r.status_code, 400) - dump('oauth2_authorization_invalid_scope', r) + self.assertEqual(r.status_code, 302) + self.assertTrue(r.location.startswith('http://localhost:5009/callback')) + args = parse_qs(urlparse(r.location).query) + self.assertEqual(args['state'], ['teststate']) + self.assertEqual(args['error'], ['invalid_scope']) def test_authorization_missing_client_id(self): self.login_as('user') @@ -105,14 +117,18 @@ class TestViews(UffdTestCase): def test_authorization_missing_response_type(self): self.login_as('user') r = self.client.get(path=url_for('oauth2.authorize', client_id='test', state='teststate', redirect_uri='http://localhost:5009/callback', scope='profile'), follow_redirects=False) - self.assertEqual(r.status_code, 400) - dump('oauth2_authorization_missing_response_type', r) + self.assertTrue(r.location.startswith('http://localhost:5009/callback')) + args = parse_qs(urlparse(r.location).query) + self.assertEqual(args['state'], ['teststate']) + self.assertEqual(args['error'], ['invalid_request']) def test_authorization_invalid_response_type(self): self.login_as('user') r = self.client.get(path=url_for('oauth2.authorize', response_type='token', client_id='test', state='teststate', redirect_uri='http://localhost:5009/callback', scope='profile'), follow_redirects=False) - self.assertEqual(r.status_code, 400) - dump('oauth2_authorization_invalid_response_type', r) + self.assertTrue(r.location.startswith('http://localhost:5009/callback')) + args = parse_qs(urlparse(r.location).query) + self.assertEqual(args['state'], ['teststate']) + self.assertEqual(args['error'], ['unsupported_response_type']) def test_authorization_devicelogin_start(self): ref = url_for('oauth2.authorize', response_type='code', client_id='test', state='teststate', redirect_uri='http://localhost:5009/callback') diff --git a/uffd/views/oauth2.py b/uffd/views/oauth2.py index 43d65fa61e5b6b1dd8d253b3a6e53c1bda065c11..94f50eb4e1ddcd62086cb967fe85e2b9a1d1c9bb 100644 --- a/uffd/views/oauth2.py +++ b/uffd/views/oauth2.py @@ -155,7 +155,11 @@ server = oauthlib.oauth2.WebApplicationServer(validator) bp = Blueprint('oauth2', __name__, url_prefix='/oauth2/', template_folder='templates') @bp.errorhandler(oauthlib.oauth2.rfc6749.errors.OAuth2Error) -def handle_oauth2error(error): +def handle_oauth2_error(error): + return redirect(error.in_uri(error.redirect_uri)) + +@bp.errorhandler(oauthlib.oauth2.rfc6749.errors.FatalClientError) +def handle_fatal_oauth2_error(error): return render_template('oauth2/error.html', error=type(error).__name__, error_description=error.description), 400 @bp.route('/authorize', methods=['GET', 'POST']) @@ -203,7 +207,7 @@ def authorize(): # service access to his data. Since we only have trusted services (the # clients defined in the server config), we don't ask for consent. if not client.access_allowed(credentials['user']): - abort(403, description=_("You don't have the permission to access the service <b>%(service_name)s</b>.", service_name=client.service.name)) + raise oauthlib.oauth2.rfc6749.errors.AccessDeniedError(request=credentials['request']) session['oauth2-clients'] = session.get('oauth2-clients', []) if client.client_id not in session['oauth2-clients']: session['oauth2-clients'].append(client.client_id)