django-oidc-provider/oidc_provider/tests/cases/test_userinfo_endpoint.py

167 lines
5.1 KiB
Python
Raw Normal View History

import json
2015-05-07 18:47:49 +00:00
from datetime import timedelta
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
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
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(
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
token.id_token = id_token_dic
2015-05-07 18:47:49 +00:00
token.save()
return token
def _post_request(self, access_token, schema='Bearer'):
2015-05-07 18:47:49 +00:00
"""
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'] = schema + ' ' + access_token
2015-05-07 18:47:49 +00:00
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_valid_token_lowercase_bearer(self):
"""
Some clients expect to be able to pass the token_type value from the token endpoint
("bearer") back to the identity provider unchanged.
"""
token = self._create_token()
response = self._post_request(token.access_token, schema='bearer')
self.assertEqual(response.status_code, 200)
self.assertEqual(bool(response.content), True)
2015-05-07 18:47:49 +00:00
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
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)
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.')