2016-08-11 22:05:13 +00:00
|
|
|
import json
|
|
|
|
|
2015-05-07 18:47:49 +00:00
|
|
|
from datetime import timedelta
|
2015-07-27 21:28:12 +00:00
|
|
|
try:
|
|
|
|
from urllib.parse import urlencode
|
|
|
|
except ImportError:
|
|
|
|
from urllib import urlencode
|
2015-05-07 18:47:49 +00:00
|
|
|
|
2018-02-01 17:00:57 +00:00
|
|
|
try:
|
|
|
|
from django.urls import reverse
|
|
|
|
except ImportError:
|
|
|
|
from django.core.urlresolvers import reverse
|
2015-05-07 18:47:49 +00:00
|
|
|
from django.test import RequestFactory
|
|
|
|
from django.test import TestCase
|
|
|
|
from django.utils import timezone
|
|
|
|
|
2016-08-11 22:05:13 +00:00
|
|
|
from oidc_provider.lib.utils.token import (
|
|
|
|
create_id_token,
|
|
|
|
create_token,
|
|
|
|
)
|
|
|
|
from oidc_provider.tests.app.utils import (
|
|
|
|
create_fake_user,
|
|
|
|
create_fake_client,
|
|
|
|
FAKE_NONCE,
|
|
|
|
)
|
2015-05-07 18:47:49 +00:00
|
|
|
from oidc_provider.views import userinfo
|
|
|
|
|
|
|
|
|
|
|
|
class UserInfoTestCase(TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.factory = RequestFactory()
|
|
|
|
self.user = create_fake_user()
|
|
|
|
self.client = create_fake_client(response_type='code')
|
|
|
|
|
2017-08-08 22:41:42 +00:00
|
|
|
def _create_token(self, extra_scope=None):
|
2015-05-07 18:47:49 +00:00
|
|
|
"""
|
|
|
|
Generate a valid token.
|
|
|
|
"""
|
2017-08-08 22:41:42 +00:00
|
|
|
if extra_scope is None:
|
|
|
|
extra_scope = []
|
2016-09-09 16:10:12 +00:00
|
|
|
scope = ['openid', 'email'] + extra_scope
|
|
|
|
|
2017-12-15 08:29:49 +00:00
|
|
|
token = create_token(
|
|
|
|
user=self.user,
|
|
|
|
client=self.client,
|
|
|
|
scope=scope)
|
|
|
|
|
2016-09-09 16:10:12 +00:00
|
|
|
id_token_dic = create_id_token(
|
2018-04-10 21:41:38 +00:00
|
|
|
token=token,
|
2016-09-09 16:10:12 +00:00
|
|
|
user=self.user,
|
|
|
|
aud=self.client.client_id,
|
|
|
|
nonce=FAKE_NONCE,
|
|
|
|
scope=scope,
|
|
|
|
)
|
2015-05-07 18:47:49 +00:00
|
|
|
|
2018-04-10 21:41:38 +00:00
|
|
|
token.id_token = id_token_dic
|
2015-05-07 18:47:49 +00:00
|
|
|
token.save()
|
|
|
|
|
|
|
|
return token
|
|
|
|
|
|
|
|
def _post_request(self, access_token):
|
|
|
|
"""
|
|
|
|
Makes a request to the userinfo endpoint by sending the
|
|
|
|
`post_data` parameters using the 'multipart/form-data'
|
|
|
|
format.
|
|
|
|
"""
|
|
|
|
url = reverse('oidc_provider:userinfo')
|
|
|
|
|
2017-08-08 22:41:42 +00:00
|
|
|
request = self.factory.post(url, data={}, content_type='multipart/form-data')
|
2015-05-07 18:47:49 +00:00
|
|
|
|
|
|
|
request.META['HTTP_AUTHORIZATION'] = 'Bearer ' + access_token
|
|
|
|
|
|
|
|
response = userinfo(request)
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
def test_response_with_valid_token(self):
|
|
|
|
token = self._create_token()
|
|
|
|
|
|
|
|
# Test a valid request to the userinfo endpoint.
|
|
|
|
response = self._post_request(token.access_token)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(bool(response.content), True)
|
|
|
|
|
|
|
|
def test_response_with_expired_token(self):
|
|
|
|
token = self._create_token()
|
|
|
|
|
|
|
|
# Make token expired.
|
|
|
|
token.expires_at = timezone.now() - timedelta(hours=1)
|
|
|
|
token.save()
|
|
|
|
|
|
|
|
response = self._post_request(token.access_token)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 401)
|
|
|
|
|
|
|
|
try:
|
|
|
|
is_header_field_ok = 'invalid_token' in response['WWW-Authenticate']
|
|
|
|
except KeyError:
|
|
|
|
is_header_field_ok = False
|
2015-05-07 19:08:12 +00:00
|
|
|
self.assertEqual(is_header_field_ok, True)
|
|
|
|
|
|
|
|
def test_response_with_invalid_scope(self):
|
|
|
|
token = self._create_token()
|
|
|
|
|
|
|
|
token.scope = ['otherone']
|
|
|
|
token.save()
|
|
|
|
|
|
|
|
response = self._post_request(token.access_token)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
|
|
|
|
try:
|
|
|
|
is_header_field_ok = 'insufficient_scope' in response['WWW-Authenticate']
|
|
|
|
except KeyError:
|
|
|
|
is_header_field_ok = False
|
2015-07-23 19:07:55 +00:00
|
|
|
self.assertEqual(is_header_field_ok, True)
|
2015-07-27 21:28:12 +00:00
|
|
|
|
|
|
|
def test_accesstoken_query_string_parameter(self):
|
|
|
|
"""
|
|
|
|
Make a GET request to the UserInfo Endpoint by sending access_token
|
|
|
|
as query string parameter.
|
|
|
|
"""
|
|
|
|
token = self._create_token()
|
|
|
|
|
|
|
|
url = reverse('oidc_provider:userinfo') + '?' + urlencode({
|
|
|
|
'access_token': token.access_token,
|
|
|
|
})
|
|
|
|
|
|
|
|
request = self.factory.get(url)
|
|
|
|
response = userinfo(request)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(bool(response.content), True)
|
2015-08-11 18:59:57 +00:00
|
|
|
|
|
|
|
def test_user_claims_in_response(self):
|
|
|
|
token = self._create_token(extra_scope=['profile'])
|
|
|
|
response = self._post_request(token.access_token)
|
|
|
|
response_dic = json.loads(response.content.decode('utf-8'))
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertEqual(bool(response.content), True)
|
2017-08-08 22:41:42 +00:00
|
|
|
self.assertIn('given_name', response_dic, msg='"given_name" claim should be in response.')
|
|
|
|
self.assertNotIn('profile', response_dic, msg='"profile" claim should not be in response.')
|
2015-08-11 18:59:57 +00:00
|
|
|
|
|
|
|
# Now adding `address` scope.
|
|
|
|
token = self._create_token(extra_scope=['profile', 'address'])
|
|
|
|
response = self._post_request(token.access_token)
|
|
|
|
response_dic = json.loads(response.content.decode('utf-8'))
|
|
|
|
|
2017-08-08 22:41:42 +00:00
|
|
|
self.assertIn('address', response_dic, msg='"address" claim should be in response.')
|
2018-03-23 18:46:12 +00:00
|
|
|
self.assertIn(
|
|
|
|
'country', response_dic['address'], msg='"country" claim should be in response.')
|