Skip to content
Snippets Groups Projects
Unverified Commit 7eb21f4d authored by Zainab Amir's avatar Zainab Amir Committed by GitHub
Browse files

Change version of social-auth-app-django (#21956)

Microsoft social login is not working on edx mobile app. The issue
is fixed in newer version of social-auth-app-django.

PROD-718
parent 3e426cce
No related merge requests found
...@@ -209,6 +209,11 @@ def get(request): ...@@ -209,6 +209,11 @@ def get(request):
"""Gets the running pipeline's data from the passed request.""" """Gets the running pipeline's data from the passed request."""
strategy = social_django.utils.load_strategy(request) strategy = social_django.utils.load_strategy(request)
token = strategy.session_get('partial_pipeline_token') token = strategy.session_get('partial_pipeline_token')
if not token:
strategy.session_set('partial_pipeline_token', strategy.session_get('partial_pipeline_token_'))
token = strategy.session_get('partial_pipeline_token')
partial_object = strategy.partial_load(token) partial_object = strategy.partial_load(token)
pipeline_data = None pipeline_data = None
if partial_object: if partial_object:
...@@ -560,6 +565,10 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia ...@@ -560,6 +565,10 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
return (current_provider and return (current_provider and
current_provider.slug in [saml_provider.slug for saml_provider in saml_providers_list]) current_provider.slug in [saml_provider.slug for saml_provider in saml_providers_list])
if current_partial:
strategy.session_set('partial_pipeline_token_', current_partial.token)
strategy.storage.partial.store(current_partial)
if not user: if not user:
# Use only email for user existence check in case of saml provider # Use only email for user existence check in case of saml provider
if is_provider_saml(): if is_provider_saml():
......
...@@ -542,6 +542,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -542,6 +542,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
request.user = self.create_user_models_for_existing_account( request.user = self.create_user_models_for_existing_account(
strategy, 'user@example.com', 'password', self.get_username(), skip_social_auth=True) strategy, 'user@example.com', 'password', self.get_username(), skip_social_auth=True)
partial_pipeline_token = strategy.session_get('partial_pipeline_token')
partial_data = strategy.storage.partial.load(partial_pipeline_token)
# Instrument the pipeline to get to the dashboard with the full # Instrument the pipeline to get to the dashboard with the full
# expected state. # expected state.
...@@ -561,24 +563,14 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -561,24 +563,14 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
# We should be redirected back to the complete page, setting # We should be redirected back to the complete page, setting
# the "logged in" cookie for the marketing site. # the "logged in" cookie for the marketing site.
self.assert_logged_in_cookie_redirect(actions.do_complete( self.assert_logged_in_cookie_redirect(self.do_complete(strategy, request, partial_pipeline_token, partial_data))
request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access
redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request
))
# Set the cookie and try again # Set the cookie and try again
self.set_logged_in_cookies(request) self.set_logged_in_cookies(request)
# Fire off the auth pipeline to link. # Fire off the auth pipeline to link.
self.assert_redirect_after_pipeline_completes( self.assert_redirect_after_pipeline_completes(
actions.do_complete( self.do_complete(strategy, request, partial_pipeline_token, partial_data)
request.backend,
social_views._do_login, # pylint: disable=protected-access
request.user,
None,
redirect_field_name=auth.REDIRECT_FIELD_NAME,
request=request
)
) )
# Now we expect to be in the linked state, with a backend entry. # Now we expect to be in the linked state, with a backend entry.
...@@ -694,6 +686,9 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -694,6 +686,9 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
user = self.create_user_models_for_existing_account( user = self.create_user_models_for_existing_account(
strategy, 'user@example.com', 'password', self.get_username()) strategy, 'user@example.com', 'password', self.get_username())
partial_pipeline_token = strategy.session_get('partial_pipeline_token')
partial_data = strategy.storage.partial.load(partial_pipeline_token)
self.assert_social_auth_exists_for_user(user, strategy) self.assert_social_auth_exists_for_user(user, strategy)
self.assertTrue(user.is_active) self.assertTrue(user.is_active)
...@@ -734,7 +729,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -734,7 +729,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
self.set_logged_in_cookies(request) self.set_logged_in_cookies(request)
self.assert_redirect_after_pipeline_completes( self.assert_redirect_after_pipeline_completes(
actions.do_complete(request.backend, social_views._do_login, user=user, request=request)) self.do_complete(strategy, request, partial_pipeline_token, partial_data, user)
)
self.assert_account_settings_context_looks_correct(account_settings_context(request)) self.assert_account_settings_context_looks_correct(account_settings_context(request))
def test_signin_fails_if_account_not_active(self): def test_signin_fails_if_account_not_active(self):
...@@ -793,6 +789,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -793,6 +789,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
request, strategy = self.get_request_and_strategy( request, strategy = self.get_request_and_strategy(
auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete')
strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
partial_pipeline_token = strategy.session_get('partial_pipeline_token')
partial_data = strategy.storage.partial.load(partial_pipeline_token)
# Begin! Grab the registration page and check the login control on it. # Begin! Grab the registration page and check the login control on it.
self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register')) self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register'))
...@@ -846,15 +844,13 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -846,15 +844,13 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
# We should be redirected back to the complete page, setting # We should be redirected back to the complete page, setting
# the "logged in" cookie for the marketing site. # the "logged in" cookie for the marketing site.
self.assert_logged_in_cookie_redirect(actions.do_complete( self.assert_logged_in_cookie_redirect(self.do_complete(strategy, request, partial_pipeline_token, partial_data))
request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access
redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request
))
# Set the cookie and try again # Set the cookie and try again
self.set_logged_in_cookies(request) self.set_logged_in_cookies(request)
self.assert_redirect_after_pipeline_completes( self.assert_redirect_after_pipeline_completes(
actions.do_complete(strategy.request.backend, social_views._do_login, user=created_user, request=request)) self.do_complete(strategy, request, partial_pipeline_token, partial_data, created_user)
)
# Now the user has been redirected to the dashboard. Their third party account should now be linked. # Now the user has been redirected to the dashboard. Their third party account should now be linked.
self.assert_social_auth_exists_for_user(created_user, strategy) self.assert_social_auth_exists_for_user(created_user, strategy)
self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True) self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
...@@ -974,6 +970,19 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin): ...@@ -974,6 +970,19 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
""" """
raise NotImplementedError raise NotImplementedError
def do_complete(self, strategy, request, partial_pipeline_token, partial_data, user=None):
"""
Makes sure that strategy store includes the partial data object before
calling actions.do_complete
"""
strategy.storage.partial.store(partial_data)
if not user:
user = request.user
return actions.do_complete(
request.backend, social_views._do_login, user, None, # pylint: disable=protected-access
redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request, partial_token=partial_pipeline_token
)
# pylint: disable=abstract-method # pylint: disable=abstract-method
@django_utils.override_settings(ECOMMERCE_API_URL=TEST_API_URL) @django_utils.override_settings(ECOMMERCE_API_URL=TEST_API_URL)
......
...@@ -4,6 +4,15 @@ from __future__ import absolute_import ...@@ -4,6 +4,15 @@ from __future__ import absolute_import
from third_party_auth.tests.specs import base from third_party_auth.tests.specs import base
def get_localized_name(name):
"""Returns the localizedName from the name object"""
locale = "{}_{}".format(
name["preferredLocale"]["language"],
name["preferredLocale"]["country"]
)
return name['localized'].get(locale, '')
class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest): class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest):
"""Integration tests for provider.LinkedInOauth2.""" """Integration tests for provider.LinkedInOauth2."""
...@@ -21,11 +30,29 @@ class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest): ...@@ -21,11 +30,29 @@ class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest):
'expires_in': 'expires_in_value', 'expires_in': 'expires_in_value',
} }
USER_RESPONSE_DATA = { USER_RESPONSE_DATA = {
'lastName': 'lastName_value', 'lastName': {
"localized": {
"en_US": "Doe"
},
"preferredLocale": {
"country": "US",
"language": "en"
}
},
'id': 'id_value', 'id': 'id_value',
'firstName': 'firstName_value', 'firstName': {
"localized": {
"en_US": "Doe"
},
"preferredLocale": {
"country": "US",
"language": "en"
}
},
} }
def get_username(self): def get_username(self):
response_data = self.get_response_data() response_data = self.get_response_data()
return response_data.get('firstName') + response_data.get('lastName') first_name = get_localized_name(response_data.get('firstName'))
last_name = get_localized_name(response_data.get('lastName'))
return first_name + last_name
...@@ -98,7 +98,7 @@ class ThirdPartyOAuthTestMixinFacebook(object): ...@@ -98,7 +98,7 @@ class ThirdPartyOAuthTestMixinFacebook(object):
class ThirdPartyOAuthTestMixinGoogle(object): class ThirdPartyOAuthTestMixinGoogle(object):
"""Tests oauth with the Google backend""" """Tests oauth with the Google backend"""
BACKEND = "google-oauth2" BACKEND = "google-oauth2"
USER_URL = "https://www.googleapis.com/plus/v1/people/me" USER_URL = "https://www.googleapis.com/oauth2/v3/userinfo"
# In google-oauth2 responses, the "email" field is used as the user's identifier # In google-oauth2 responses, the "email" field is used as the user's identifier
UID_FIELD = "email" UID_FIELD = "email"
......
...@@ -133,8 +133,8 @@ pyuca==1.1 # For more accurate sorting of translated co ...@@ -133,8 +133,8 @@ pyuca==1.1 # For more accurate sorting of translated co
recommender-xblock # https://github.com/edx/RecommenderXBlock recommender-xblock # https://github.com/edx/RecommenderXBlock
rest-condition # DRF's recommendation for supporting complex permissions rest-condition # DRF's recommendation for supporting complex permissions
rfc6266-parser # Used to generate Content-Disposition headers. rfc6266-parser # Used to generate Content-Disposition headers.
social-auth-app-django<3.0.0 social-auth-app-django==3.1.0
social-auth-core<2.0.0 social-auth-core==3.2.0
pysrt # Support for SubRip subtitle files, used in the video XModule pysrt # Support for SubRip subtitle files, used in the video XModule
pytz # Time zone information database pytz # Time zone information database
PyYAML # Used to parse XModule resource templates PyYAML # Used to parse XModule resource templates
......
...@@ -227,8 +227,8 @@ simplejson==3.17.0 ...@@ -227,8 +227,8 @@ simplejson==3.17.0
singledispatch==3.4.0.3 singledispatch==3.4.0.3
six==1.13.0 six==1.13.0
slumber==0.7.1 # via edx-bulk-grades, edx-enterprise, edx-rest-api-client slumber==0.7.1 # via edx-bulk-grades, edx-enterprise, edx-rest-api-client
social-auth-app-django==2.1.0 social-auth-app-django==3.1.0
social-auth-core==1.7.0 social-auth-core==3.2.0
sorl-thumbnail==12.3 sorl-thumbnail==12.3
sortedcontainers==2.1.0 sortedcontainers==2.1.0
soupsieve==1.9.5 # via beautifulsoup4 soupsieve==1.9.5 # via beautifulsoup4
......
...@@ -305,8 +305,8 @@ singledispatch==3.4.0.3 ...@@ -305,8 +305,8 @@ singledispatch==3.4.0.3
six==1.13.0 six==1.13.0
slumber==0.7.1 slumber==0.7.1
snowballstemmer==2.0.0 # via sphinx snowballstemmer==2.0.0 # via sphinx
social-auth-app-django==2.1.0 social-auth-app-django==3.1.0
social-auth-core==1.7.0 social-auth-core==3.2.0
sorl-thumbnail==12.3 sorl-thumbnail==12.3
sortedcontainers==2.1.0 sortedcontainers==2.1.0
soupsieve==1.9.5 soupsieve==1.9.5
......
...@@ -292,8 +292,8 @@ simplejson==3.17.0 ...@@ -292,8 +292,8 @@ simplejson==3.17.0
singledispatch==3.4.0.3 singledispatch==3.4.0.3
six==1.13.0 six==1.13.0
slumber==0.7.1 slumber==0.7.1
social-auth-app-django==2.1.0 social-auth-app-django==3.1.0
social-auth-core==1.7.0 social-auth-core==3.2.0
sorl-thumbnail==12.3 sorl-thumbnail==12.3
sortedcontainers==2.1.0 sortedcontainers==2.1.0
soupsieve==1.9.5 soupsieve==1.9.5
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment