2015-02-12 18:04:58 +00:00
|
|
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
|
|
|
from django.contrib.auth.models import AnonymousUser
|
2015-02-11 18:37:51 +00:00
|
|
|
from django.core.urlresolvers import reverse
|
|
|
|
from django.test import RequestFactory
|
|
|
|
from django.test import TestCase
|
2015-02-18 18:07:22 +00:00
|
|
|
from oidc_provider import settings
|
|
|
|
from oidc_provider.tests.utils import *
|
|
|
|
from oidc_provider.views import *
|
2015-02-11 20:38:37 +00:00
|
|
|
import urllib
|
2015-02-11 18:37:51 +00:00
|
|
|
|
|
|
|
|
2015-02-19 18:45:51 +00:00
|
|
|
class AuthorizationCodeFlowTestCase(TestCase):
|
2015-02-11 18:37:51 +00:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.factory = RequestFactory()
|
|
|
|
self.user = create_fake_user()
|
|
|
|
self.client = create_fake_client(response_type='code')
|
|
|
|
|
2015-02-12 18:04:58 +00:00
|
|
|
def _create_authorize_url(self, response_type, scope=['openid', 'email']):
|
2015-02-12 19:56:35 +00:00
|
|
|
"""
|
|
|
|
Generate an OpenID Authentication Request using the fake client data.
|
|
|
|
"""
|
2015-02-18 18:07:22 +00:00
|
|
|
path = reverse('oidc_provider:authorize')
|
2015-02-12 19:56:35 +00:00
|
|
|
|
|
|
|
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
|
2015-02-12 18:04:58 +00:00
|
|
|
|
|
|
|
return url
|
|
|
|
|
2015-02-11 18:37:51 +00:00
|
|
|
def test_authorize_invalid_parameters(self):
|
|
|
|
"""
|
|
|
|
If the request fails due to a missing, invalid, or mismatching
|
|
|
|
redirection URI, or if the client identifier is missing or invalid,
|
|
|
|
the authorization server SHOULD inform the resource owner of the error.
|
|
|
|
|
|
|
|
See: https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
|
|
|
"""
|
2015-02-18 18:07:22 +00:00
|
|
|
url = reverse('oidc_provider:authorize')
|
2015-02-11 18:37:51 +00:00
|
|
|
request = self.factory.get(url)
|
|
|
|
|
|
|
|
response = AuthorizeView.as_view()(request)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
2015-02-11 20:38:37 +00:00
|
|
|
self.assertEqual(bool(response.content), True)
|
|
|
|
|
|
|
|
def test_authorize_invalid_response_type(self):
|
|
|
|
"""
|
|
|
|
The OP informs the RP by using the Error Response parameters defined
|
|
|
|
in Section 4.1.2.1 of OAuth 2.0.
|
|
|
|
|
|
|
|
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
|
|
|
"""
|
|
|
|
# Create an authorize request with an unsupported response_type.
|
2015-02-12 18:04:58 +00:00
|
|
|
url = self._create_authorize_url(response_type='code id_token')
|
|
|
|
|
2015-02-11 20:38:37 +00:00
|
|
|
request = self.factory.get(url)
|
|
|
|
|
|
|
|
response = AuthorizeView.as_view()(request)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
self.assertEqual(response.has_header('Location'), True)
|
|
|
|
|
2015-02-12 18:04:58 +00:00
|
|
|
# Should be an 'error' component in query.
|
|
|
|
query_exists = 'error=' in response['Location']
|
|
|
|
self.assertEqual(query_exists, True)
|
|
|
|
|
|
|
|
def test_authorize_user_not_logged(self):
|
|
|
|
"""
|
|
|
|
The Authorization Server attempts to Authenticate the End-User by
|
|
|
|
redirecting to the login view.
|
|
|
|
|
|
|
|
See: http://openid.net/specs/openid-connect-core-1_0.html#Authenticates
|
|
|
|
"""
|
|
|
|
url = self._create_authorize_url(response_type='code')
|
|
|
|
|
|
|
|
request = self.factory.get(url)
|
|
|
|
request.user = AnonymousUser()
|
|
|
|
|
|
|
|
response = AuthorizeView.as_view()(request)
|
|
|
|
|
|
|
|
# Check if user was redirected to the login view.
|
|
|
|
login_url_exists = settings.get('LOGIN_URL') in response['Location']
|
|
|
|
self.assertEqual(login_url_exists, True)
|
|
|
|
|
|
|
|
# Check if the login will redirect to a valid url.
|
|
|
|
try:
|
|
|
|
next_value = response['Location'].split(REDIRECT_FIELD_NAME + '=')[1]
|
|
|
|
next_url = urllib.unquote(next_value)
|
|
|
|
is_next_ok = next_url == url
|
|
|
|
except:
|
|
|
|
is_next_ok = False
|
2015-02-13 13:44:09 +00:00
|
|
|
self.assertEqual(is_next_ok, True)
|
|
|
|
|
|
|
|
def test_authorize_user_consent(self):
|
2015-02-19 18:45:51 +00:00
|
|
|
response_type = 'code'
|
|
|
|
|
|
|
|
url = self._create_authorize_url(response_type=response_type)
|
2015-02-13 13:44:09 +00:00
|
|
|
|
|
|
|
request = self.factory.get(url)
|
|
|
|
# Simulate that the user is logged.
|
|
|
|
request.user = self.user
|
|
|
|
|
|
|
|
response = AuthorizeView.as_view()(request)
|
|
|
|
|
2015-02-19 18:45:51 +00:00
|
|
|
# Check if hidden inputs exists in the form, also
|
|
|
|
# check if their values are valid.
|
|
|
|
|
|
|
|
input_html = '<input name="{0}" type="hidden" value="{1}" />'
|
|
|
|
|
|
|
|
to_check = {
|
|
|
|
'client_id': self.client.client_id,
|
|
|
|
'redirect_uri': self.client.default_redirect_uri,
|
|
|
|
'response_type': response_type,
|
|
|
|
}
|
|
|
|
|
|
|
|
for key, value in to_check.iteritems():
|
|
|
|
is_input_ok = input_html.format(key, value) in response.content
|
|
|
|
self.assertEqual(is_input_ok, True,
|
|
|
|
msg='Hidden input for "'+key+'" fails.')
|