summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Huot <JonathanHuot@users.noreply.github.com>2018-09-17 21:12:47 +0200
committerGitHub <noreply@github.com>2018-09-17 21:12:47 +0200
commitf00935f9f5d1305119f278406dbd1174a2c85868 (patch)
treed616b3d9b4d5bef516b9bc4c2d140ca22fd61fdf
parente7bd936434f7268b0453fd25c637034f7efd8168 (diff)
parent7ed3c53f8d04634ee8f470a4d621cd26505e977e (diff)
downloadoauthlib-f00935f9f5d1305119f278406dbd1174a2c85868.tar.gz
Merge branch 'master' into fix-585_client_id
-rw-r--r--README.rst2
-rw-r--r--docs/index.rst6
-rw-r--r--docs/installation.rst2
-rw-r--r--docs/oauth2/endpoints/endpoints.rst2
-rw-r--r--oauthlib/common.py14
-rw-r--r--oauthlib/oauth1/rfc5849/__init__.py5
-rw-r--r--oauthlib/oauth1/rfc5849/signature.py4
-rw-r--r--oauthlib/oauth1/rfc5849/utils.py2
-rw-r--r--oauthlib/oauth2/rfc6749/errors.py12
-rw-r--r--requirements-test.txt1
-rwxr-xr-xsetup.py8
-rw-r--r--tests/oauth1/rfc5849/test_client.py12
-rw-r--r--tests/oauth2/rfc6749/test_parameters.py4
-rw-r--r--tests/openid/connect/core/grant_types/test_dispatchers.py14
-rw-r--r--tests/test_common.py13
-rw-r--r--tests/unittest/__init__.py21
-rw-r--r--tox.ini9
17 files changed, 57 insertions, 74 deletions
diff --git a/README.rst b/README.rst
index a84307f..7c41a80 100644
--- a/README.rst
+++ b/README.rst
@@ -12,7 +12,7 @@ logic for Python 2.7 and 3.4+.*
:alt: Coveralls
.. image:: https://img.shields.io/pypi/pyversions/oauthlib.svg
:target: https://pypi.org/project/oauthlib/
- :alt: Download from PyPi
+ :alt: Download from PyPI
.. image:: https://img.shields.io/pypi/l/oauthlib.svg
:target: https://pypi.org/project/oauthlib/
:alt: License
diff --git a/docs/index.rst b/docs/index.rst
index 1da2ca5..b6ce191 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,14 +7,14 @@ Welcome to OAuthLib's documentation!
====================================
If you can't find what you need or have suggestions for improvement, don't
-hesitate to open a `new issue on GitHub`_!
+hesitate to open a `new issue on GitHub`_!
Check out :doc:`error_reporting` for details on how to be an awesome bug reporter.
-For news and discussions please head over to our `G+ OAuthLib community`_.
+For news and discussions please head over to our `Gitter OAuthLib community`_.
.. _`new issue on GitHub`: https://github.com/oauthlib/oauthlib/issues/new
-.. _`G+ OAuthLib community`: https://plus.google.com/communities/101889017375384052571
+.. _`Gitter OAuthLib community`: https://gitter.im/oauthlib/Lobby
.. toctree::
:maxdepth: 1
diff --git a/docs/installation.rst b/docs/installation.rst
index 48e4288..72d7b08 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -9,7 +9,7 @@ For various reasons you may wish to install using your OS packaging system and
install instructions for a few are shown below. Please send a PR to add a
missing one.
-Latest release on PYPI
+Latest release on PyPI
----------------------
diff --git a/docs/oauth2/endpoints/endpoints.rst b/docs/oauth2/endpoints/endpoints.rst
index 80d5fbe..98599e8 100644
--- a/docs/oauth2/endpoints/endpoints.rst
+++ b/docs/oauth2/endpoints/endpoints.rst
@@ -24,7 +24,7 @@ handles user authorization, the token endpoint which provides tokens and the
resource endpoint which provides access to protected resources. It is to the
endpoints you will feed requests and get back an almost complete response. This
process is simplified for you using a decorator such as the django one described
-later (but it's applicable to all other web frameworks librairies).
+later (but it's applicable to all other web frameworks libraries).
The main purpose of the endpoint in OAuthLib is to figure out which grant type
or token to dispatch the request to.
diff --git a/oauthlib/common.py b/oauthlib/common.py
index 6364761..bd6ec56 100644
--- a/oauthlib/common.py
+++ b/oauthlib/common.py
@@ -54,10 +54,8 @@ PY3 = sys.version_info[0] == 3
if PY3:
unicode_type = str
- bytes_type = bytes
else:
unicode_type = unicode
- bytes_type = str
# 'safe' must be bytes (Python 2.6 requires bytes, other versions allow either)
@@ -66,7 +64,7 @@ def quote(s, safe=b'/'):
s = _quote(s, safe)
# PY3 always returns unicode. PY2 may return either, depending on whether
# it had to modify the string.
- if isinstance(s, bytes_type):
+ if isinstance(s, bytes):
s = s.decode('utf-8')
return s
@@ -76,7 +74,7 @@ def unquote(s):
# PY3 always returns unicode. PY2 seems to always return what you give it,
# which differs from quote's behavior. Just to be safe, make sure it is
# unicode before we return.
- if isinstance(s, bytes_type):
+ if isinstance(s, bytes):
s = s.decode('utf-8')
return s
@@ -109,8 +107,8 @@ def decode_params_utf8(params):
decoded = []
for k, v in params:
decoded.append((
- k.decode('utf-8') if isinstance(k, bytes_type) else k,
- v.decode('utf-8') if isinstance(v, bytes_type) else v))
+ k.decode('utf-8') if isinstance(k, bytes) else k,
+ v.decode('utf-8') if isinstance(v, bytes) else v))
return decoded
@@ -174,7 +172,7 @@ def extract_params(raw):
empty list of parameters. Any other input will result in a return
value of None.
"""
- if isinstance(raw, bytes_type) or isinstance(raw, unicode_type):
+ if isinstance(raw, bytes) or isinstance(raw, unicode_type):
try:
params = urldecode(raw)
except ValueError:
@@ -309,7 +307,7 @@ def to_unicode(data, encoding='UTF-8'):
if isinstance(data, unicode_type):
return data
- if isinstance(data, bytes_type):
+ if isinstance(data, bytes):
return unicode_type(data, encoding=encoding)
if hasattr(data, '__iter__'):
diff --git a/oauthlib/oauth1/rfc5849/__init__.py b/oauthlib/oauth1/rfc5849/__init__.py
index 87a8e6b..887ab69 100644
--- a/oauthlib/oauth1/rfc5849/__init__.py
+++ b/oauthlib/oauth1/rfc5849/__init__.py
@@ -18,11 +18,6 @@ try:
except ImportError:
import urllib.parse as urlparse
-if sys.version_info[0] == 3:
- bytes_type = bytes
-else:
- bytes_type = str
-
from oauthlib.common import Request, urlencode, generate_nonce
from oauthlib.common import generate_timestamp, to_unicode
from . import parameters, signature
diff --git a/oauthlib/oauth1/rfc5849/signature.py b/oauthlib/oauth1/rfc5849/signature.py
index 4e672ba..e90d6f3 100644
--- a/oauthlib/oauth1/rfc5849/signature.py
+++ b/oauthlib/oauth1/rfc5849/signature.py
@@ -28,7 +28,7 @@ import hashlib
import hmac
import logging
-from oauthlib.common import (bytes_type, extract_params, safe_string_equals,
+from oauthlib.common import (extract_params, safe_string_equals,
unicode_type, urldecode)
from . import utils
@@ -635,7 +635,7 @@ def verify_hmac_sha1(request, client_secret=None,
def _prepare_key_plus(alg, keystr):
- if isinstance(keystr, bytes_type):
+ if isinstance(keystr, bytes):
keystr = keystr.decode('utf-8')
return alg.prepare_key(keystr)
diff --git a/oauthlib/oauth1/rfc5849/utils.py b/oauthlib/oauth1/rfc5849/utils.py
index 3762e3b..735f21d 100644
--- a/oauthlib/oauth1/rfc5849/utils.py
+++ b/oauthlib/oauth1/rfc5849/utils.py
@@ -8,7 +8,7 @@ spec.
"""
from __future__ import absolute_import, unicode_literals
-from oauthlib.common import bytes_type, quote, unicode_type, unquote
+from oauthlib.common import quote, unicode_type, unquote
try:
import urllib2
diff --git a/oauthlib/oauth2/rfc6749/errors.py b/oauthlib/oauth2/rfc6749/errors.py
index 3f0bfc0..d17e08e 100644
--- a/oauthlib/oauth2/rfc6749/errors.py
+++ b/oauthlib/oauth2/rfc6749/errors.py
@@ -316,6 +316,7 @@ class ConsentRequired(OAuth2Error):
error = 'consent_required'
status_code = 401
+
class LoginRequired(OAuth2Error):
"""
The Authorization Server requires End-User authentication.
@@ -328,6 +329,16 @@ class LoginRequired(OAuth2Error):
status_code = 401
+class CustomOAuth2Error(OAuth2Error):
+ """
+ This error is a placeholder for all custom errors not described by the RFC.
+ Some of the popular OAuth2 providers are using custom errors.
+ """
+ def __init__(self, error, *args, **kwargs):
+ self.error = error
+ super(CustomOAuth2Error, self).__init__(*args, **kwargs)
+
+
def raise_from_error(error, params=None):
import inspect
import sys
@@ -339,3 +350,4 @@ def raise_from_error(error, params=None):
for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
if cls.error == error:
raise cls(**kwargs)
+ raise CustomOAuth2Error(error=error, **kwargs)
diff --git a/requirements-test.txt b/requirements-test.txt
index 5bf6e06..c3e0a7b 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -1,4 +1,3 @@
-r requirements.txt
coverage>=3.7.1
-nose==1.3.7
mock>=2.0
diff --git a/setup.py b/setup.py
index 1d69e0d..640bbe1 100755
--- a/setup.py
+++ b/setup.py
@@ -18,10 +18,9 @@ def fread(fn):
with open(join(dirname(__file__), fn), 'r') as f:
return f.read()
-if sys.version_info[0] == 3:
- tests_require = ['nose', 'cryptography', 'pyjwt>=1.0.0', 'blinker']
-else:
- tests_require = ['nose', 'unittest2', 'cryptography', 'mock>=2.0', 'pyjwt>=1.0.0', 'blinker']
+tests_require = ['cryptography', 'pyjwt>=1.0.0', 'blinker']
+if sys.version_info[0] == 2:
+ tests_require.append('mock>=2.0')
rsa_require = ['cryptography']
signedtoken_require = ['cryptography', 'pyjwt>=1.0.0']
signals_require = ['blinker']
@@ -41,7 +40,6 @@ setup(
platforms='any',
license='BSD',
packages=find_packages(exclude=('docs', 'tests', 'tests.*')),
- test_suite='nose.collector',
tests_require=tests_require,
extras_require={
'test': tests_require,
diff --git a/tests/oauth1/rfc5849/test_client.py b/tests/oauth1/rfc5849/test_client.py
index 777efc2..e1f83de 100644
--- a/tests/oauth1/rfc5849/test_client.py
+++ b/tests/oauth1/rfc5849/test_client.py
@@ -5,7 +5,7 @@ from oauthlib.common import Request
from oauthlib.oauth1 import (SIGNATURE_PLAINTEXT, SIGNATURE_HMAC_SHA1,
SIGNATURE_HMAC_SHA256, SIGNATURE_RSA,
SIGNATURE_TYPE_BODY, SIGNATURE_TYPE_QUERY)
-from oauthlib.oauth1.rfc5849 import Client, bytes_type
+from oauthlib.oauth1.rfc5849 import Client
from ...unittest import TestCase
@@ -39,7 +39,7 @@ class ClientConstructorTests(TestCase):
def test_convert_to_unicode_resource_owner(self):
client = Client('client-key',
resource_owner_key=b'owner key')
- self.assertFalse(isinstance(client.resource_owner_key, bytes_type))
+ self.assertNotIsInstance(client.resource_owner_key, bytes)
self.assertEqual(client.resource_owner_key, 'owner key')
def test_give_explicit_timestamp(self):
@@ -57,11 +57,11 @@ class ClientConstructorTests(TestCase):
uri, headers, body = client.sign('http://a.b/path?query',
http_method='POST', body='a=b',
headers={'Content-Type': 'application/x-www-form-urlencoded'})
- self.assertIsInstance(uri, bytes_type)
- self.assertIsInstance(body, bytes_type)
+ self.assertIsInstance(uri, bytes)
+ self.assertIsInstance(body, bytes)
for k, v in headers.items():
- self.assertIsInstance(k, bytes_type)
- self.assertIsInstance(v, bytes_type)
+ self.assertIsInstance(k, bytes)
+ self.assertIsInstance(v, bytes)
def test_hmac_sha1(self):
client = Client('client_key')
diff --git a/tests/oauth2/rfc6749/test_parameters.py b/tests/oauth2/rfc6749/test_parameters.py
index b211d1e..c42f516 100644
--- a/tests/oauth2/rfc6749/test_parameters.py
+++ b/tests/oauth2/rfc6749/test_parameters.py
@@ -103,6 +103,7 @@ class ParameterTests(TestCase):
' "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",'
' "example_parameter": "example_value" }')
+ json_custom_error = '{ "error": "incorrect_client_credentials" }'
json_error = '{ "error": "access_denied" }'
json_notoken = ('{ "token_type": "example",'
@@ -197,6 +198,9 @@ class ParameterTests(TestCase):
self.assertRaises(ValueError, parse_implicit_response,
self.implicit_wrongstate, state=self.state)
+ def test_custom_json_error(self):
+ self.assertRaises(CustomOAuth2Error, parse_token_response, self.json_custom_error)
+
def test_json_token_response(self):
"""Verify correct parameter parsing and validation for token responses. """
self.assertEqual(parse_token_response(self.json_response), self.json_dict)
diff --git a/tests/openid/connect/core/grant_types/test_dispatchers.py b/tests/openid/connect/core/grant_types/test_dispatchers.py
index f90ec46..84f2688 100644
--- a/tests/openid/connect/core/grant_types/test_dispatchers.py
+++ b/tests/openid/connect/core/grant_types/test_dispatchers.py
@@ -36,23 +36,23 @@ class ImplicitTokenGrantDispatcherTest(TestCase):
self.request.scopes = ('hello', 'openid')
self.request.response_type = 'id_token'
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, ImplicitGrant))
+ self.assertIsInstance(handler, ImplicitGrant)
def test_validate_authorization_request_openid(self):
self.request.scopes = ('hello', 'openid')
self.request.response_type = 'id_token'
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, ImplicitGrant))
+ self.assertIsInstance(handler, ImplicitGrant)
def test_create_authorization_response_oauth(self):
self.request.scopes = ('hello', 'world')
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, ImplicitGrant))
+ self.assertIsInstance(handler, ImplicitGrant)
def test_validate_authorization_request_oauth(self):
self.request.scopes = ('hello', 'world')
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, ImplicitGrant))
+ self.assertIsInstance(handler, ImplicitGrant)
class DispatcherTest(TestCase):
@@ -82,7 +82,7 @@ class AuthTokenGrantDispatcherOpenIdTest(DispatcherTest):
def test_create_token_response_openid(self):
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, AuthorizationCodeGrant))
+ self.assertIsInstance(handler, AuthorizationCodeGrant)
self.assertTrue(self.dispatcher.request_validator.get_authorization_code_scopes.called)
@@ -104,7 +104,7 @@ class AuthTokenGrantDispatcherOpenIdWithoutCodeTest(DispatcherTest):
def test_create_token_response_openid_without_code(self):
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, OAuth2AuthorizationCodeGrant))
+ self.assertIsInstance(handler, OAuth2AuthorizationCodeGrant)
self.assertFalse(self.dispatcher.request_validator.get_authorization_code_scopes.called)
@@ -121,5 +121,5 @@ class AuthTokenGrantDispatcherOAuthTest(DispatcherTest):
def test_create_token_response_oauth(self):
handler = self.dispatcher._handler_for_request(self.request)
- self.assertTrue(isinstance(handler, OAuth2AuthorizationCodeGrant))
+ self.assertIsInstance(handler, OAuth2AuthorizationCodeGrant)
self.assertTrue(self.dispatcher.request_validator.get_authorization_code_scopes.called)
diff --git a/tests/test_common.py b/tests/test_common.py
index f239368..20d9f5b 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -10,11 +10,6 @@ from oauthlib.common import (CaseInsensitiveDict, Request, add_params_to_uri,
from .unittest import TestCase
-if sys.version_info[0] == 3:
- bytes_type = bytes
-else:
- bytes_type = lambda s, e: str(s)
-
PARAMS_DICT = {'foo': 'bar', 'baz': '123', }
PARAMS_TWOTUPLE = [('foo', 'bar'), ('baz', '123')]
PARAMS_FORMENCODED = 'foo=bar&baz=123'
@@ -122,11 +117,11 @@ class RequestTest(TestCase):
def test_non_unicode_params(self):
r = Request(
- bytes_type('http://a.b/path?query', 'utf-8'),
- http_method=bytes_type('GET', 'utf-8'),
- body=bytes_type('you=shall+pass', 'utf-8'),
+ b'http://a.b/path?query',
+ http_method=b'GET',
+ body=b'you=shall+pass',
headers={
- bytes_type('a', 'utf-8'): bytes_type('b', 'utf-8')
+ b'a': b'b',
}
)
self.assertEqual(r.uri, 'http://a.b/path?query')
diff --git a/tests/unittest/__init__.py b/tests/unittest/__init__.py
index 35b239a..6cb79a6 100644
--- a/tests/unittest/__init__.py
+++ b/tests/unittest/__init__.py
@@ -1,32 +1,15 @@
import collections
import sys
+from unittest import TestCase
try:
import urlparse
except ImportError:
import urllib.parse as urlparse
-try:
- # check the system path first
- from unittest2 import *
-except ImportError:
- if sys.version_info >= (2, 7):
- # unittest2 features are native in Python 2.7
- from unittest import *
- else:
- raise
-
-# Python 3.1 does not provide assertIsInstance
-if sys.version_info[1] == 1:
- TestCase.assertIsInstance = lambda self, obj, cls: self.assertTrue(isinstance(obj, cls))
# Somewhat consistent itemsequal between all python versions
-if sys.version_info[1] == 3:
+if sys.version_info[0] == 3:
TestCase.assertItemsEqual = TestCase.assertCountEqual
-elif sys.version_info[0] == 2 and sys.version_info[1] == 6:
- pass
-else:
- TestCase.assertItemsEqual = lambda self, a, b: self.assertEqual(
- collections.Counter(list(a)), collections.Counter(list(b)))
# URL comparison where query param order is insignifcant
diff --git a/tox.ini b/tox.ini
index eac7a1e..c45f657 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,11 +4,10 @@ envlist = py27,py34,py35,py36,pypy,docs,readme
[testenv]
deps=
-rrequirements-test.txt
-commands=nosetests -s --with-coverage --cover-html --cover-html-dir={toxinidir}/htmlcov-{envname} --cover-erase --cover-package=oauthlib -w tests
+commands=
+ coverage run --source oauthlib -m unittest discover
+ coverage report
-[testenv:py27]
-deps=unittest2
- {[testenv]deps}
# tox -e docs to mimick readthedocs build.
# as of today, RTD is using python2.7 and doesn't run "setup.py install"
@@ -20,7 +19,7 @@ changedir=docs
whitelist_externals=make
commands=make clean html
-# tox -e readme to mimick pypi long_description check
+# tox -e readme to mimick PyPI long_description check
[testenv:readme]
skipsdist=True
deps=readme