From 57085a1e46b4fca74beff7c222d10b33e79ec897 Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 01:12:51 -0400 Subject: [PATCH 1/6] Add support for claims_provided in provider info - Add OIDC_CLAIMS_SUPPORTED into settings.py with default empty list - Add entry for claims_supported in ProviderInfo.views that returns value from settings --- oidc_provider/settings.py | 10 ++++++++++ oidc_provider/views.py | 2 ++ 2 files changed, 12 insertions(+) diff --git a/oidc_provider/settings.py b/oidc_provider/settings.py index 90750fda..3dbbe904 100644 --- a/oidc_provider/settings.py +++ b/oidc_provider/settings.py @@ -161,6 +161,16 @@ def OIDC_GRANT_TYPE_PASSWORD_ENABLE(self): """ return False + @property + def OIDC_CLAIMS_SUPPORTED(self): + """ + RECOMMENDED. A list of Claims names that you may support. Does not need + to be exhaustive for security reasons. + + https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata + """ + return [] + @property def OIDC_TEMPLATES(self): return { diff --git a/oidc_provider/views.py b/oidc_provider/views.py index 06501d5d..2dc2a756 100644 --- a/oidc_provider/views.py +++ b/oidc_provider/views.py @@ -284,6 +284,8 @@ def get(self, request, *args, **kwargs): dic['token_endpoint_auth_methods_supported'] = ['client_secret_post', 'client_secret_basic'] + + dic['claims_supported'] = settings.get('OIDC_CLAIMS_SUPPORTED', []) if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'): dic['check_session_iframe'] = site_url + reverse('oidc_provider:check-session-iframe') From ef50204b42307a0923667b57cc6678e0634aecc3 Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 01:15:30 -0400 Subject: [PATCH 2/6] Add docs for OIDC_CLAIMS_SUPPORTED --- docs/sections/settings.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/sections/settings.rst b/docs/sections/settings.rst index 984d2df2..0ec7548f 100644 --- a/docs/sections/settings.rst +++ b/docs/sections/settings.rst @@ -244,4 +244,13 @@ A flag which toggles whether the scope is returned with successful response on i Must be ``True`` to include ``scope`` into the successful response -Default is ``False``. \ No newline at end of file +Default is ``False``. + +OIDC_CLAIMS_SUPPORTED +================= + +RECOMMENDED. ``list``. RECOMMENDED. List containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able to supply values for. Note that for privacy or other reasons, this might not be an exhaustive list. + +https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata + +Default is an empty list as this application will not make assumptions about what the provider will support. From ad90788a81d209c9717a123c79dce5386143e9a7 Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 01:15:47 -0400 Subject: [PATCH 3/6] Add tests for claims_supported --- .../cases/test_provider_info_endpoint.py | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/oidc_provider/tests/cases/test_provider_info_endpoint.py b/oidc_provider/tests/cases/test_provider_info_endpoint.py index 2265ef66..c533612b 100644 --- a/oidc_provider/tests/cases/test_provider_info_endpoint.py +++ b/oidc_provider/tests/cases/test_provider_info_endpoint.py @@ -1,9 +1,10 @@ +import json + try: from django.urls import reverse except ImportError: from django.core.urlresolvers import reverse -from django.test import RequestFactory -from django.test import TestCase +from django.test import RequestFactory, TestCase, override_settings from oidc_provider.views import ProviderInfoView @@ -27,3 +28,66 @@ def test_response(self): self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'] == 'application/json', True) self.assertEqual(bool(response.content), True) + + def test_expected_keys_in_response(self): + """ + Test that response contains all ncecessary keys + """ + required_keys = { + 'issuer', + 'authorization_endpoint', + 'token_endpoint', + 'userinfo_endpoint', + 'end_session_endpoint', + 'introspection_endpoint', + 'response_types_supported', + 'jwks_uri', + 'id_token_signing_alg_values_supported', + 'subject_types_supported', + 'token_endpoint_auth_methods_supported', + 'claims_supported', + } + url = reverse('oidc_provider:provider-info') + + request = self.factory.get(url) + + response = ProviderInfoView.as_view()(request) + resp_keys = set(json.loads(response.content.decode('utf-8')).keys()) + self.assertEqual(required_keys, resp_keys) + + def test_claims_supported_not_set(self): + """ + If OIDC_CLAIMS_SUPPORTED is not set in settings.py, the claims_supported + entry is an empty list + """ + url = reverse('oidc_provider:provider-info') + + request = self.factory.get(url) + + response = ProviderInfoView.as_view()(request) + dic = json.loads(response.content.decode('utf-8')) + self.assertEqual(dic['claims_supported'], []) + + @override_settings(OIDC_CLAIMS_SUPPORTED=['openid', 'email']) + def test_claims_supported_set(self): + """ + If OIDC_CLAIMS_SUPPORTED is not set in settings.py, the claims_supported + entry is an empty list + """ + url = reverse('oidc_provider:provider-info') + expected_claims = ['openid', 'email'] + + request = self.factory.get(url) + + response = ProviderInfoView.as_view()(request) + dic = json.loads(response.content.decode('utf-8')) + self.assertEqual(dic['claims_supported'], expected_claims) + + + + + + + + + From 2dd4d4d4bb76cd371e84d850f56576266cbfc0e5 Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 13:38:33 -0400 Subject: [PATCH 4/6] Move url to setUpClass in TestProviderInfo --- .../tests/cases/test_provider_info_endpoint.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/oidc_provider/tests/cases/test_provider_info_endpoint.py b/oidc_provider/tests/cases/test_provider_info_endpoint.py index c533612b..2b933765 100644 --- a/oidc_provider/tests/cases/test_provider_info_endpoint.py +++ b/oidc_provider/tests/cases/test_provider_info_endpoint.py @@ -11,6 +11,11 @@ class ProviderInfoTestCase(TestCase): + @classmethod + def setUpClass(cls): + super(ProviderInfoTestCase, cls).setUpClass() + cls.url = reverse('oidc_provider:provider-info') + def setUp(self): self.factory = RequestFactory() @@ -19,9 +24,8 @@ def test_response(self): See if the endpoint is returning the corresponding server information by checking status, content type, etc. """ - url = reverse('oidc_provider:provider-info') - request = self.factory.get(url) + request = self.factory.get(self.url) response = ProviderInfoView.as_view()(request) @@ -47,9 +51,8 @@ def test_expected_keys_in_response(self): 'token_endpoint_auth_methods_supported', 'claims_supported', } - url = reverse('oidc_provider:provider-info') - request = self.factory.get(url) + request = self.factory.get(self.url) response = ProviderInfoView.as_view()(request) resp_keys = set(json.loads(response.content.decode('utf-8')).keys()) @@ -60,9 +63,7 @@ def test_claims_supported_not_set(self): If OIDC_CLAIMS_SUPPORTED is not set in settings.py, the claims_supported entry is an empty list """ - url = reverse('oidc_provider:provider-info') - - request = self.factory.get(url) + request = self.factory.get(self.url) response = ProviderInfoView.as_view()(request) dic = json.loads(response.content.decode('utf-8')) @@ -74,10 +75,9 @@ def test_claims_supported_set(self): If OIDC_CLAIMS_SUPPORTED is not set in settings.py, the claims_supported entry is an empty list """ - url = reverse('oidc_provider:provider-info') expected_claims = ['openid', 'email'] - request = self.factory.get(url) + request = self.factory.get(self.url) response = ProviderInfoView.as_view()(request) dic = json.loads(response.content.decode('utf-8')) From 12a3dc9b4078cb19ecb08a2e9f83bea17287ab3f Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 14:17:50 -0400 Subject: [PATCH 5/6] Remove duplice RECOMMEND in docs; fix ==' length --- docs/sections/settings.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sections/settings.rst b/docs/sections/settings.rst index 0ec7548f..057c38e5 100644 --- a/docs/sections/settings.rst +++ b/docs/sections/settings.rst @@ -247,9 +247,9 @@ Must be ``True`` to include ``scope`` into the successful response Default is ``False``. OIDC_CLAIMS_SUPPORTED -================= +===================== -RECOMMENDED. ``list``. RECOMMENDED. List containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able to supply values for. Note that for privacy or other reasons, this might not be an exhaustive list. +RECOMMENDED. ``list``. List containing a list of the Claim Names of the Claims that the OpenID Provider MAY be able to supply values for. Note that for privacy or other reasons, this might not be an exhaustive list. https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata From 77795356874096b2e7e78f0814de69320e5bf53d Mon Sep 17 00:00:00 2001 From: Geoff Von Allmen Date: Sat, 27 Jul 2019 14:32:31 -0400 Subject: [PATCH 6/6] Fix Flake8 Errors --- oidc_provider/settings.py | 2 +- .../tests/cases/test_provider_info_endpoint.py | 13 ++----------- oidc_provider/views.py | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/oidc_provider/settings.py b/oidc_provider/settings.py index 3dbbe904..d88e76bd 100644 --- a/oidc_provider/settings.py +++ b/oidc_provider/settings.py @@ -167,7 +167,7 @@ def OIDC_CLAIMS_SUPPORTED(self): RECOMMENDED. A list of Claims names that you may support. Does not need to be exhaustive for security reasons. - https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata + https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata """ return [] diff --git a/oidc_provider/tests/cases/test_provider_info_endpoint.py b/oidc_provider/tests/cases/test_provider_info_endpoint.py index 2b933765..79a6b9a7 100644 --- a/oidc_provider/tests/cases/test_provider_info_endpoint.py +++ b/oidc_provider/tests/cases/test_provider_info_endpoint.py @@ -32,7 +32,7 @@ def test_response(self): self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'] == 'application/json', True) self.assertEqual(bool(response.content), True) - + def test_expected_keys_in_response(self): """ Test that response contains all ncecessary keys @@ -57,7 +57,7 @@ def test_expected_keys_in_response(self): response = ProviderInfoView.as_view()(request) resp_keys = set(json.loads(response.content.decode('utf-8')).keys()) self.assertEqual(required_keys, resp_keys) - + def test_claims_supported_not_set(self): """ If OIDC_CLAIMS_SUPPORTED is not set in settings.py, the claims_supported @@ -82,12 +82,3 @@ def test_claims_supported_set(self): response = ProviderInfoView.as_view()(request) dic = json.loads(response.content.decode('utf-8')) self.assertEqual(dic['claims_supported'], expected_claims) - - - - - - - - - diff --git a/oidc_provider/views.py b/oidc_provider/views.py index 2dc2a756..7f574e4d 100644 --- a/oidc_provider/views.py +++ b/oidc_provider/views.py @@ -284,7 +284,7 @@ def get(self, request, *args, **kwargs): dic['token_endpoint_auth_methods_supported'] = ['client_secret_post', 'client_secret_basic'] - + dic['claims_supported'] = settings.get('OIDC_CLAIMS_SUPPORTED', []) if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):