Complete some tests. Also change a few things on them.

This commit is contained in:
juanifioren 2015-02-27 17:40:17 -03:00
parent d1c1e2adb3
commit 07c92e8182

View file

@ -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)