diff --git a/common/djangoapps/third_party_auth/models.py b/common/djangoapps/third_party_auth/models.py index d0d099dcac..9036be1a92 100644 --- a/common/djangoapps/third_party_auth/models.py +++ b/common/djangoapps/third_party_auth/models.py @@ -68,7 +68,7 @@ def clean_json(value, of_type): def clean_username(username=''): """ Simple helper method to ensure a username is compatible with our system requirements. """ - return re.sub(r'[^-\w]+', '_', username)[:USERNAME_MAX_LENGTH] + return ('_').join(re.findall(r'[a-zA-Z0-9\-]+', username))[:USERNAME_MAX_LENGTH] class AuthNotConfigured(SocialAuthBaseException): diff --git a/common/djangoapps/third_party_auth/tests/test_pipeline.py b/common/djangoapps/third_party_auth/tests/test_pipeline.py index b45ddfcd24..5e5c35d281 100644 --- a/common/djangoapps/third_party_auth/tests/test_pipeline.py +++ b/common/djangoapps/third_party_auth/tests/test_pipeline.py @@ -75,7 +75,7 @@ class PipelineOverridesTest(SamlIntegrationTestUtilities, IntegrationTestMixin, ('S', 'S9fe2', False), ('S', 'S9fe2', True), ('S.K', 'S_K', False), - ('S.K.', 'S_K_', False), + ('S.K.', 'S_K', False), ('S.K.', 'S_K_9fe2', True), ('usernamewithcharacterlengthofmorethan30chars', 'usernamewithcharacterlengthofm', False), ('usernamewithcharacterlengthofmorethan30chars', 'usernamewithcharacterlengt9fe2', True), diff --git a/openedx/core/djangoapps/user_authn/views/utils.py b/openedx/core/djangoapps/user_authn/views/utils.py index 4d1645987b..b284fdde9d 100644 --- a/openedx/core/djangoapps/user_authn/views/utils.py +++ b/openedx/core/djangoapps/user_authn/views/utils.py @@ -8,6 +8,7 @@ from ipware.ip import get_client_ip from common.djangoapps import third_party_auth from common.djangoapps.third_party_auth import pipeline +from common.djangoapps.third_party_auth.models import clean_username from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.geoinfo.api import country_code_from_ip @@ -70,6 +71,9 @@ def third_party_auth_context(request, redirect_to, tpa_hint=None): current_provider = third_party_auth.provider.Registry.get_from_pipeline(running_pipeline) user_details = running_pipeline['kwargs']['details'] if user_details: + username = running_pipeline['kwargs'].get('username') or user_details.get('username') + if username: + user_details['username'] = clean_username(username) context['pipeline_user_details'] = user_details if current_provider is not None: