Complete some tests. Also change a few things on them.
This commit is contained in:
parent
d1c1e2adb3
commit
07c92e8182
|
@ -1,12 +1,15 @@
|
||||||
|
import urllib
|
||||||
|
|
||||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
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 oidc_provider import settings
|
from oidc_provider import settings
|
||||||
|
from oidc_provider.models import *
|
||||||
from oidc_provider.tests.utils import *
|
from oidc_provider.tests.utils import *
|
||||||
from oidc_provider.views import *
|
from oidc_provider.views import *
|
||||||
import urllib
|
|
||||||
|
|
||||||
|
|
||||||
class AuthorizationCodeFlowTestCase(TestCase):
|
class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
|
@ -15,26 +18,9 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
self.factory = RequestFactory()
|
self.factory = RequestFactory()
|
||||||
self.user = create_fake_user()
|
self.user = create_fake_user()
|
||||||
self.client = create_fake_client(response_type='code')
|
self.client = create_fake_client(response_type='code')
|
||||||
|
self.state = uuid.uuid4().hex
|
||||||
|
|
||||||
def _create_authorize_url(self, response_type, scope=['openid', 'email']):
|
def test_missing_parameters(self):
|
||||||
"""
|
|
||||||
Generate an OpenID Authentication Request using the fake client data.
|
|
||||||
"""
|
|
||||||
path = reverse('oidc_provider:authorize')
|
|
||||||
|
|
||||||
query_str = urllib.urlencode({
|
|
||||||
'client_id': self.client.client_id,
|
|
||||||
'response_type': response_type,
|
|
||||||
'redirect_uri': self.client.default_redirect_uri,
|
|
||||||
'scope': ' '.join(scope),
|
|
||||||
'state': 'abcdefg',
|
|
||||||
}).replace('+', '%20')
|
|
||||||
|
|
||||||
url = path + '?' + query_str
|
|
||||||
|
|
||||||
return url
|
|
||||||
|
|
||||||
def test_authorize_invalid_parameters(self):
|
|
||||||
"""
|
"""
|
||||||
If the request fails due to a missing, invalid, or mismatching
|
If the request fails due to a missing, invalid, or mismatching
|
||||||
redirection URI, or if the client identifier is missing or invalid,
|
redirection URI, or if the client identifier is missing or invalid,
|
||||||
|
@ -43,6 +29,7 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
See: https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
See: https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||||
"""
|
"""
|
||||||
url = reverse('oidc_provider:authorize')
|
url = reverse('oidc_provider:authorize')
|
||||||
|
|
||||||
request = self.factory.get(url)
|
request = self.factory.get(url)
|
||||||
|
|
||||||
response = AuthorizeView.as_view()(request)
|
response = AuthorizeView.as_view()(request)
|
||||||
|
@ -50,7 +37,7 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(bool(response.content), True)
|
self.assertEqual(bool(response.content), True)
|
||||||
|
|
||||||
def test_authorize_invalid_response_type(self):
|
def test_invalid_response_type(self):
|
||||||
"""
|
"""
|
||||||
The OP informs the RP by using the Error Response parameters defined
|
The OP informs the RP by using the Error Response parameters defined
|
||||||
in Section 4.1.2.1 of OAuth 2.0.
|
in Section 4.1.2.1 of OAuth 2.0.
|
||||||
|
@ -58,7 +45,15 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
||||||
"""
|
"""
|
||||||
# Create an authorize request with an unsupported response_type.
|
# Create an authorize request with an unsupported response_type.
|
||||||
url = self._create_authorize_url(response_type='code id_token')
|
query_str = urllib.urlencode({
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'response_type': 'something_wrong',
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
}).replace('+', '%20')
|
||||||
|
|
||||||
|
url = reverse('oidc_provider:authorize') + '?' + query_str
|
||||||
|
|
||||||
request = self.factory.get(url)
|
request = self.factory.get(url)
|
||||||
|
|
||||||
|
@ -71,14 +66,22 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
query_exists = 'error=' in response['Location']
|
query_exists = 'error=' in response['Location']
|
||||||
self.assertEqual(query_exists, True)
|
self.assertEqual(query_exists, True)
|
||||||
|
|
||||||
def test_authorize_user_not_logged(self):
|
def test_codeflow_user_not_logged(self):
|
||||||
"""
|
"""
|
||||||
The Authorization Server attempts to Authenticate the End-User by
|
The Authorization Server attempts to Authenticate the End-User by
|
||||||
redirecting to the login view.
|
redirecting to the login view.
|
||||||
|
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#Authenticates
|
See: http://openid.net/specs/openid-connect-core-1_0.html#Authenticates
|
||||||
"""
|
"""
|
||||||
url = self._create_authorize_url(response_type='code')
|
query_str = urllib.urlencode({
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'response_type': 'code',
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'scope': 'openid email',
|
||||||
|
'state': self.state,
|
||||||
|
}).replace('+', '%20')
|
||||||
|
|
||||||
|
url = reverse('oidc_provider:authorize') + '?' + query_str
|
||||||
|
|
||||||
request = self.factory.get(url)
|
request = self.factory.get(url)
|
||||||
request.user = AnonymousUser()
|
request.user = AnonymousUser()
|
||||||
|
@ -98,7 +101,7 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
is_next_ok = False
|
is_next_ok = False
|
||||||
self.assertEqual(is_next_ok, True)
|
self.assertEqual(is_next_ok, True)
|
||||||
|
|
||||||
def test_authorize_user_consent(self):
|
def test_codeflow_user_consent_inputs(self):
|
||||||
"""
|
"""
|
||||||
Once the End-User is authenticated, the Authorization Server MUST
|
Once the End-User is authenticated, the Authorization Server MUST
|
||||||
obtain an authorization decision before releasing information to
|
obtain an authorization decision before releasing information to
|
||||||
|
@ -107,8 +110,17 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#Consent
|
See: http://openid.net/specs/openid-connect-core-1_0.html#Consent
|
||||||
"""
|
"""
|
||||||
response_type = 'code'
|
response_type = 'code'
|
||||||
|
state = 'openid email'
|
||||||
|
|
||||||
url = self._create_authorize_url(response_type=response_type)
|
query_str = urllib.urlencode({
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'response_type': response_type,
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'scope': state,
|
||||||
|
'state': self.state,
|
||||||
|
}).replace('+', '%20')
|
||||||
|
|
||||||
|
url = reverse('oidc_provider:authorize') + '?' + query_str
|
||||||
|
|
||||||
request = self.factory.get(url)
|
request = self.factory.get(url)
|
||||||
# Simulate that the user is logged.
|
# Simulate that the user is logged.
|
||||||
|
@ -116,9 +128,8 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
|
|
||||||
response = AuthorizeView.as_view()(request)
|
response = AuthorizeView.as_view()(request)
|
||||||
|
|
||||||
# Check if hidden inputs exists in the form, also
|
# Check if hidden inputs exists in the form,
|
||||||
# check if their values are valid.
|
# also if their values are valid.
|
||||||
|
|
||||||
input_html = '<input name="{0}" type="hidden" value="{1}" />'
|
input_html = '<input name="{0}" type="hidden" value="{1}" />'
|
||||||
|
|
||||||
to_check = {
|
to_check = {
|
||||||
|
@ -131,3 +142,64 @@ class AuthorizationCodeFlowTestCase(TestCase):
|
||||||
is_input_ok = input_html.format(key, value) in response.content
|
is_input_ok = input_html.format(key, value) in response.content
|
||||||
self.assertEqual(is_input_ok, True,
|
self.assertEqual(is_input_ok, True,
|
||||||
msg='Hidden input for "'+key+'" fails.')
|
msg='Hidden input for "'+key+'" fails.')
|
||||||
|
|
||||||
|
def test_codeflow_user_consent_response(self):
|
||||||
|
"""
|
||||||
|
First,
|
||||||
|
if the user denied the consent we must ensure that
|
||||||
|
the error response parameters are added to the query component
|
||||||
|
of the Redirection URI.
|
||||||
|
|
||||||
|
Second,
|
||||||
|
if the user allow the RP then the server MUST return
|
||||||
|
the parameters defined in Section 4.1.2 of OAuth 2.0 [RFC6749]
|
||||||
|
by adding them as query parameters to the redirect_uri.
|
||||||
|
"""
|
||||||
|
response_type = 'code'
|
||||||
|
scope = 'openid email'
|
||||||
|
|
||||||
|
url = reverse('oidc_provider:authorize')
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
'client_id': self.client.client_id,
|
||||||
|
'redirect_uri': self.client.default_redirect_uri,
|
||||||
|
'response_type': response_type,
|
||||||
|
'scope': scope,
|
||||||
|
'state': self.state,
|
||||||
|
}
|
||||||
|
|
||||||
|
request = self.factory.post(url, data=post_data)
|
||||||
|
# Simulate that the user is logged.
|
||||||
|
request.user = self.user
|
||||||
|
|
||||||
|
response = AuthorizeView.as_view()(request)
|
||||||
|
|
||||||
|
# Because user doesn't allow app, SHOULD exists an error parameter
|
||||||
|
# in the query.
|
||||||
|
self.assertEqual('error=' in response['Location'], True)
|
||||||
|
self.assertEqual('access_denied' in response['Location'], True)
|
||||||
|
|
||||||
|
# Simulate user authorization.
|
||||||
|
post_data['allow'] = 'Accept' # Should be the value of the button.
|
||||||
|
|
||||||
|
request = self.factory.post(url, data=post_data)
|
||||||
|
# Simulate that the user is logged.
|
||||||
|
request.user = self.user
|
||||||
|
|
||||||
|
response = AuthorizeView.as_view()(request)
|
||||||
|
|
||||||
|
# Validate the code returned by the OP.
|
||||||
|
code = (response['Location'].split('code='))[1].split('&')[0]
|
||||||
|
try:
|
||||||
|
code = Code.objects.get(code=code)
|
||||||
|
if (code.client == self.client) or (code.user == self.user):
|
||||||
|
is_code_ok = True
|
||||||
|
else:
|
||||||
|
is_code_ok = False
|
||||||
|
except:
|
||||||
|
is_code_ok = False
|
||||||
|
self.assertEqual(is_code_ok, True)
|
||||||
|
|
||||||
|
# Check if the state is returned.
|
||||||
|
state = (response['Location'].split('state='))[1].split('&')[0]
|
||||||
|
self.assertEqual(state == self.state, True)
|
Loading…
Reference in a new issue