diff --git a/common/djangoapps/third_party_auth/identityserver3.py b/common/djangoapps/third_party_auth/identityserver3.py index ebec0ebb0e..9132643146 100644 --- a/common/djangoapps/third_party_auth/identityserver3.py +++ b/common/djangoapps/third_party_auth/identityserver3.py @@ -39,11 +39,26 @@ class IdentityServer3(BaseOAuth2): header = {"Authorization": u"Bearer %s" % access_token} return self.get_json(url, headers=header) + def get_setting_if_exist(self, name, default): + """ + Return provider config setting if exist otherwise return default + """ + try: + return self.get_config().get_setting(name) + except KeyError: + return default + def get_user_details(self, response): """ Return details about the user account from the service """ - details = {"fullname": response["name"], "email": response["email"]} + details = { + "fullname": response.get(self.get_setting_if_exist("full_name_claim_key", "name")), + "email": response.get(self.get_setting_if_exist("email_claim_key", "email")), + "username": response.get(self.get_setting_if_exist("username_claim_key", "given_name")), + "first_name": response.get(self.get_setting_if_exist("first_name_claim_key", "given_name")), + "last_name": response.get(self.get_setting_if_exist("last_name_claim_key", "family_name")), + } return details def get_user_id(self, details, response): diff --git a/common/djangoapps/third_party_auth/tests/test_identityserver3.py b/common/djangoapps/third_party_auth/tests/test_identityserver3.py index 189c16666e..fa95835646 100644 --- a/common/djangoapps/third_party_auth/tests/test_identityserver3.py +++ b/common/djangoapps/third_party_auth/tests/test_identityserver3.py @@ -1,12 +1,15 @@ """ Unit tests for the IdentityServer3 OAuth2 Backend """ +import json +import ddt import unittest from third_party_auth.identityserver3 import IdentityServer3 from third_party_auth.tests import testutil @unittest.skipUnless(testutil.AUTH_FEATURE_ENABLED, testutil.AUTH_FEATURES_KEY + ' not enabled') +@ddt.ddt class IdentityServer3Test(testutil.TestCase): """ Unit tests for the IdentityServer3 OAuth2 Backend @@ -15,6 +18,22 @@ class IdentityServer3Test(testutil.TestCase): def setUp(self): super(IdentityServer3Test, self).setUp() self.id3_instance = IdentityServer3() + self.response = { + "sub": "020cadec-919a-4b06-845e-57915bf76826", + "refresh_token": "xyz", + "token_type": "bearer", + "name": "Edx Openid", + "session_state": "fcf85c29-5ecf-4edb-b29b-72ce9871cdf7", + "refresh_expires_in": 1800, + "family_name": "Openid", + "scope": "openid email profile", + "email_verified": False, + "given_name": "Edx", + "email": "edxopenid@example.com", + "not-before-policy": 0, + "preferred_username": "edxopenid", + "expires_in": 300 + } def test_proper_get_of_user_id(self): """ @@ -48,3 +67,43 @@ class IdentityServer3Test(testutil.TestCase): ) self.assertEqual(self.id3_instance.get_config(), updated_provider_config) self.assertNotEqual(self.id3_instance.get_config(), original_provider_config) + + @ddt.data( + ('first_name_claim_key', 'given_name', 'first_name', 'Edx'), + ('last_name_claim_key', 'family_name', 'last_name', 'Openid'), + ('full_name_claim_key', 'name', 'fullname', 'Edx Openid'), + ('email_claim_key', 'email', 'email', 'edxopenid@example.com'), + ('username_claim_key', 'preferred_username', 'username', 'edxopenid'), + ('first_name_claim_key', 'family_name', 'first_name', 'Openid'), + ('last_name_claim_key', 'given_name', 'last_name', 'Edx'), + ('email_claim_key', 'name', 'email', 'Edx Openid'), + ('username_claim_key', 'given_name', 'username', 'Edx'), + ) + @ddt.unpack + def test_user_details_and_settings(self, setting_field_key, setting_field_value, output_name, output_value): + """ + Test user details are picked based on the field mapping defined in settings + """ + provider_config = self.configure_identityServer3_provider( + enabled=True, + other_settings=json.dumps({ + setting_field_key: setting_field_value, + }) + ) + self.assertEqual(provider_config.backend_class().get_user_details(self.response)[output_name], output_value) + + def test_user_details_without_settings(self): + """ + Test user details fields are mapped to default keys + """ + provider_config = self.configure_identityServer3_provider(enabled=True) + self.assertDictContainsSubset( + { + "username": "Edx", + "email": "edxopenid@example.com", + "first_name": "Edx", + "last_name": "Openid", + "fullname": "Edx Openid" + }, + provider_config.backend_class().get_user_details(self.response) + ) diff --git a/lms/envs/test.py b/lms/envs/test.py index 895621ef6c..586c2fbe58 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -261,6 +261,7 @@ AUTHENTICATION_BACKENDS = [ 'social_core.backends.facebook.FacebookOAuth2', 'social_core.backends.azuread.AzureADOAuth2', 'social_core.backends.twitter.TwitterOAuth', + 'third_party_auth.identityserver3.IdentityServer3', 'third_party_auth.dummy.DummyBackend', 'third_party_auth.saml.SAMLAuthBackend', 'third_party_auth.lti.LTIAuthBackend',