Use original test files
This commit is contained in:
parent
e04d42fedf
commit
e822252b6e
|
@ -2,6 +2,10 @@ try:
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
|
try:
|
||||||
|
from urllib.parse import parse_qs, urlsplit
|
||||||
|
except ImportError:
|
||||||
|
from urlparse import parse_qs, urlsplit
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
|
@ -9,6 +13,7 @@ from django.core.management import call_command
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.test import RequestFactory
|
from django.test import RequestFactory
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from jwkest.jwt import JWT
|
||||||
|
|
||||||
from oidc_provider import settings
|
from oidc_provider import settings
|
||||||
from oidc_provider.models import *
|
from oidc_provider.models import *
|
||||||
|
@ -18,7 +23,7 @@ from oidc_provider.views import *
|
||||||
|
|
||||||
class AuthorizationCodeFlowTestCase(TestCase):
|
class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
Test cases for Authorize Endpoint using Authorization Code Flow.
|
Test cases for Authorize Endpoint using Code Flow.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -291,3 +296,168 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
|
|
||||||
# An error is returned if the Client does not have pre-configured consent for the requested Claims.
|
# An error is returned if the Client does not have pre-configured consent for the requested Claims.
|
||||||
self.assertEqual('interaction_required' in response['Location'], True)
|
self.assertEqual('interaction_required' in response['Location'], True)
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorizationImplicitFlowTestCase(TestCase):
|
||||||
|
"""
|
||||||
|
Test cases for Authorization Endpoint using Implicit Flow.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
call_command('creatersakey')
|
||||||
|
self.factory = RequestFactory()
|
||||||
|
self.user = create_fake_user()
|
||||||
|
self.client = create_fake_client(response_type='id_token token')
|
||||||
|
self.client_public = create_fake_client(response_type='id_token token', is_public=True)
|
||||||
|
self.client_no_access = create_fake_client(response_type='id_token')
|
||||||
|
self.client_public_no_access = create_fake_client(response_type='id_token', is_public=True)
|
||||||
|
self.state = uuid.uuid4().hex
|
||||||
|
self.nonce = uuid.uuid4().hex
|
||||||
|
|
||||||
|
def _auth_request(self, method, data={}, is_user_authenticated=False):
|
||||||
|
url = reverse('oidc_provider:authorize')
|
||||||
|
|
||||||
|
if method.lower() == 'get':
|
||||||
|
query_str = urlencode(data).replace('+', '%20')
|
||||||
|
if query_str:
|
||||||
|
url += '?' + query_str
|
||||||
|
request = self.factory.get(url)
|
||||||
|
elif method.lower() == 'post':
|
||||||
|
request = self.factory.post(url, data=data)
|
||||||
|
else:
|
||||||
|
raise Exception('Method unsupported for an Authorization Request.')
|
||||||
|
|
||||||
|
# Simulate that the user is logged.
|
||||||
|
request.user = self.user if is_user_authenticated else AnonymousUser()
|
||||||
|
|
||||||
|
response = AuthorizeView.as_view()(request)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
def test_missing_nonce(self):
|
||||||
|
"""
|
||||||
|
The `nonce` parameter is REQUIRED if you use the Implicit Flow.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'response_type': self.client.response_type,
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self._auth_request('get', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertEqual('#error=invalid_request' in response['Location'], True)
|
||||||
|
|
||||||
|
def test_id_token_token_response(self):
|
||||||
|
"""
|
||||||
|
Implicit client requesting `id_token token` receives both id token
|
||||||
|
and access token as the result of the authorization request.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'response_type': self.client.response_type,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
'nonce': self.nonce,
|
||||||
|
'allow': 'Accept',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertIn('access_token', response['Location'])
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
# same for public client
|
||||||
|
data['client_id'] = self.client_public.client_id,
|
||||||
|
data['redirect_uri'] = self.client_public.default_redirect_uri,
|
||||||
|
data['response_type'] = self.client_public.response_type,
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertIn('access_token', response['Location'])
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
def test_id_token_response(self):
|
||||||
|
"""
|
||||||
|
Implicit client requesting `id_token` receives
|
||||||
|
only an id token as the result of the authorization request.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'client_id': self.client_no_access.client_id,
|
||||||
|
'redirect_uri': self.client_no_access.default_redirect_uri,
|
||||||
|
'response_type': self.client_no_access.response_type,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
'nonce': self.nonce,
|
||||||
|
'allow': 'Accept',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertNotIn('access_token', response['Location'])
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
# same for public client
|
||||||
|
data['client_id'] = self.client_public_no_access.client_id,
|
||||||
|
data['redirect_uri'] = self.client_public_no_access.default_redirect_uri,
|
||||||
|
data['response_type'] = self.client_public_no_access.response_type,
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertNotIn('access_token', response['Location'])
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
def test_id_token_token_at_hash(self):
|
||||||
|
"""
|
||||||
|
Implicit client requesting `id_token token` receives
|
||||||
|
`at_hash` in `id_token`.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'response_type': self.client.response_type,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
'nonce': self.nonce,
|
||||||
|
'allow': 'Accept',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
# obtain `id_token` portion of Location
|
||||||
|
components = urlsplit(response['Location'])
|
||||||
|
fragment = parse_qs(components[4])
|
||||||
|
id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
|
||||||
|
|
||||||
|
self.assertIn('at_hash', id_token)
|
||||||
|
|
||||||
|
def test_id_token_at_hash(self):
|
||||||
|
"""
|
||||||
|
Implicit client requesting `id_token` should not receive
|
||||||
|
`at_hash` in `id_token`.
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
'client_id': self.client_no_access.client_id,
|
||||||
|
'redirect_uri': self.client_no_access.default_redirect_uri,
|
||||||
|
'response_type': self.client_no_access.response_type,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
'nonce': self.nonce,
|
||||||
|
'allow': 'Accept',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self._auth_request('post', data, is_user_authenticated=True)
|
||||||
|
|
||||||
|
self.assertIn('id_token', response['Location'])
|
||||||
|
|
||||||
|
# obtain `id_token` portion of Location
|
||||||
|
components = urlsplit(response['Location'])
|
||||||
|
fragment = parse_qs(components[4])
|
||||||
|
id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
|
||||||
|
|
||||||
|
self.assertNotIn('at_hash', id_token)
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
try:
|
|
||||||
from urllib.parse import urlencode
|
|
||||||
except ImportError:
|
|
||||||
from urllib import urlencode
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.contrib.auth.models import AnonymousUser
|
|
||||||
from django.core.management import call_command
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
from django.test import RequestFactory
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
from oidc_provider.models import *
|
|
||||||
from oidc_provider.tests.app.utils import *
|
|
||||||
from oidc_provider.views import *
|
|
||||||
|
|
||||||
|
|
||||||
class CodeFlowTestCase(TestCase):
|
|
||||||
"""
|
|
||||||
Test cases for Authorization Code Flow.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
call_command('creatersakey')
|
|
||||||
self.factory = RequestFactory()
|
|
||||||
self.user = create_fake_user()
|
|
||||||
self.client = create_fake_client(response_type='code')
|
|
||||||
self.client_public = create_fake_client(response_type='code', is_public=True)
|
|
||||||
self.state = uuid.uuid4().hex
|
|
||||||
self.nonce = uuid.uuid4().hex
|
|
||||||
|
|
||||||
def _auth_request(self, method, data={}, is_user_authenticated=False):
|
|
||||||
url = reverse('oidc_provider:authorize')
|
|
||||||
|
|
||||||
if method.lower() == 'get':
|
|
||||||
query_str = urlencode(data).replace('+', '%20')
|
|
||||||
if query_str:
|
|
||||||
url += '?' + query_str
|
|
||||||
request = self.factory.get(url)
|
|
||||||
elif method.lower() == 'post':
|
|
||||||
request = self.factory.post(url, data=data)
|
|
||||||
else:
|
|
||||||
raise Exception('Method unsupported for an Authorization Request.')
|
|
||||||
|
|
||||||
# Simulate that the user is logged.
|
|
||||||
request.user = self.user if is_user_authenticated else AnonymousUser()
|
|
||||||
|
|
||||||
response = AuthorizeView.as_view()(request)
|
|
||||||
|
|
||||||
return response
|
|
|
@ -1,185 +0,0 @@
|
||||||
try:
|
|
||||||
from urllib.parse import urlencode
|
|
||||||
except ImportError:
|
|
||||||
from urllib import urlencode
|
|
||||||
try:
|
|
||||||
from urllib.parse import parse_qs, urlsplit
|
|
||||||
except ImportError:
|
|
||||||
from urlparse import parse_qs, urlsplit
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.contrib.auth.models import AnonymousUser
|
|
||||||
from django.core.management import call_command
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
from django.test import RequestFactory
|
|
||||||
from django.test import TestCase
|
|
||||||
from jwkest.jwt import JWT
|
|
||||||
|
|
||||||
from oidc_provider.models import *
|
|
||||||
from oidc_provider.tests.app.utils import *
|
|
||||||
from oidc_provider.views import *
|
|
||||||
|
|
||||||
|
|
||||||
class ImplicitFlowTestCase(TestCase):
|
|
||||||
"""
|
|
||||||
Test cases for Authorization Implicit Flow.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
call_command('creatersakey')
|
|
||||||
self.factory = RequestFactory()
|
|
||||||
self.user = create_fake_user()
|
|
||||||
self.client = create_fake_client(response_type='id_token token')
|
|
||||||
self.client_public = create_fake_client(response_type='id_token token', is_public=True)
|
|
||||||
self.client_no_access = create_fake_client(response_type='id_token')
|
|
||||||
self.client_public_no_access = create_fake_client(response_type='id_token', is_public=True)
|
|
||||||
self.state = uuid.uuid4().hex
|
|
||||||
self.nonce = uuid.uuid4().hex
|
|
||||||
|
|
||||||
def _auth_request(self, method, data={}, is_user_authenticated=False):
|
|
||||||
url = reverse('oidc_provider:authorize')
|
|
||||||
|
|
||||||
if method.lower() == 'get':
|
|
||||||
query_str = urlencode(data).replace('+', '%20')
|
|
||||||
if query_str:
|
|
||||||
url += '?' + query_str
|
|
||||||
request = self.factory.get(url)
|
|
||||||
elif method.lower() == 'post':
|
|
||||||
request = self.factory.post(url, data=data)
|
|
||||||
else:
|
|
||||||
raise Exception('Method unsupported for an Authorization Request.')
|
|
||||||
|
|
||||||
# Simulate that the user is logged.
|
|
||||||
request.user = self.user if is_user_authenticated else AnonymousUser()
|
|
||||||
|
|
||||||
response = AuthorizeView.as_view()(request)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def test_missing_nonce(self):
|
|
||||||
"""
|
|
||||||
The `nonce` parameter is REQUIRED if you use the Implicit Flow.
|
|
||||||
"""
|
|
||||||
data = {
|
|
||||||
'client_id': self.client.client_id,
|
|
||||||
'response_type': self.client.response_type,
|
|
||||||
'redirect_uri': self.client.default_redirect_uri,
|
|
||||||
'scope': 'openid email',
|
|
||||||
'state': self.state,
|
|
||||||
}
|
|
||||||
|
|
||||||
response = self._auth_request('get', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertEqual('#error=invalid_request' in response['Location'], True)
|
|
||||||
|
|
||||||
def test_id_token_token_response(self):
|
|
||||||
"""
|
|
||||||
Implicit client requesting `id_token token` receives both id token
|
|
||||||
and access token as the result of the authorization request.
|
|
||||||
"""
|
|
||||||
data = {
|
|
||||||
'client_id': self.client.client_id,
|
|
||||||
'redirect_uri': self.client.default_redirect_uri,
|
|
||||||
'response_type': self.client.response_type,
|
|
||||||
'scope': 'openid email',
|
|
||||||
'state': self.state,
|
|
||||||
'nonce': self.nonce,
|
|
||||||
'allow': 'Accept',
|
|
||||||
}
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertIn('access_token', response['Location'])
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
# same for public client
|
|
||||||
data['client_id'] = self.client_public.client_id,
|
|
||||||
data['redirect_uri'] = self.client_public.default_redirect_uri,
|
|
||||||
data['response_type'] = self.client_public.response_type,
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertIn('access_token', response['Location'])
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
def test_id_token_response(self):
|
|
||||||
"""
|
|
||||||
Implicit client requesting `id_token` receives
|
|
||||||
only an id token as the result of the authorization request.
|
|
||||||
"""
|
|
||||||
data = {
|
|
||||||
'client_id': self.client_no_access.client_id,
|
|
||||||
'redirect_uri': self.client_no_access.default_redirect_uri,
|
|
||||||
'response_type': self.client_no_access.response_type,
|
|
||||||
'scope': 'openid email',
|
|
||||||
'state': self.state,
|
|
||||||
'nonce': self.nonce,
|
|
||||||
'allow': 'Accept',
|
|
||||||
}
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertNotIn('access_token', response['Location'])
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
# same for public client
|
|
||||||
data['client_id'] = self.client_public_no_access.client_id,
|
|
||||||
data['redirect_uri'] = self.client_public_no_access.default_redirect_uri,
|
|
||||||
data['response_type'] = self.client_public_no_access.response_type,
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertNotIn('access_token', response['Location'])
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
def test_id_token_token_at_hash(self):
|
|
||||||
"""
|
|
||||||
Implicit client requesting `id_token token` receives
|
|
||||||
`at_hash` in `id_token`.
|
|
||||||
"""
|
|
||||||
data = {
|
|
||||||
'client_id': self.client.client_id,
|
|
||||||
'redirect_uri': self.client.default_redirect_uri,
|
|
||||||
'response_type': self.client.response_type,
|
|
||||||
'scope': 'openid email',
|
|
||||||
'state': self.state,
|
|
||||||
'nonce': self.nonce,
|
|
||||||
'allow': 'Accept',
|
|
||||||
}
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
# obtain `id_token` portion of Location
|
|
||||||
components = urlsplit(response['Location'])
|
|
||||||
fragment = parse_qs(components[4])
|
|
||||||
id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
|
|
||||||
|
|
||||||
self.assertIn('at_hash', id_token)
|
|
||||||
|
|
||||||
def test_id_token_at_hash(self):
|
|
||||||
"""
|
|
||||||
Implicit client requesting `id_token` should not receive
|
|
||||||
`at_hash` in `id_token`.
|
|
||||||
"""
|
|
||||||
data = {
|
|
||||||
'client_id': self.client_no_access.client_id,
|
|
||||||
'redirect_uri': self.client_no_access.default_redirect_uri,
|
|
||||||
'response_type': self.client_no_access.response_type,
|
|
||||||
'scope': 'openid email',
|
|
||||||
'state': self.state,
|
|
||||||
'nonce': self.nonce,
|
|
||||||
'allow': 'Accept',
|
|
||||||
}
|
|
||||||
|
|
||||||
response = self._auth_request('post', data, is_user_authenticated=True)
|
|
||||||
|
|
||||||
self.assertIn('id_token', response['Location'])
|
|
||||||
|
|
||||||
# obtain `id_token` portion of Location
|
|
||||||
components = urlsplit(response['Location'])
|
|
||||||
fragment = parse_qs(components[4])
|
|
||||||
id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
|
|
||||||
|
|
||||||
self.assertNotIn('at_hash', id_token)
|
|
|
@ -304,6 +304,21 @@ class TokenTestCase(TestCase):
|
||||||
|
|
||||||
self.assertEqual(id_token.get('nonce'), None)
|
self.assertEqual(id_token.get('nonce'), None)
|
||||||
|
|
||||||
|
def test_id_token_contains_at_hash(self):
|
||||||
|
"""
|
||||||
|
If access_token is included, the id_token SHOULD contain an at_hash.
|
||||||
|
"""
|
||||||
|
code = self._create_code()
|
||||||
|
|
||||||
|
post_data = self._auth_code_post_data(code=code.code)
|
||||||
|
|
||||||
|
response = self._post_request(post_data)
|
||||||
|
|
||||||
|
response_dic = json.loads(response.content.decode('utf-8'))
|
||||||
|
id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
|
||||||
|
|
||||||
|
self.assertTrue(id_token.get('at_hash'))
|
||||||
|
|
||||||
def test_idtoken_sign_validation(self):
|
def test_idtoken_sign_validation(self):
|
||||||
"""
|
"""
|
||||||
We MUST validate the signature of the ID Token according to JWS
|
We MUST validate the signature of the ID Token according to JWS
|
||||||
|
|
Loading…
Reference in a new issue