diff --git a/common/djangoapps/student/helpers.py b/common/djangoapps/student/helpers.py index 74e4e48ffa..fa925a1180 100644 --- a/common/djangoapps/student/helpers.py +++ b/common/djangoapps/student/helpers.py @@ -226,7 +226,7 @@ def check_verify_status_by_course(user, course_enrollments): POST_AUTH_PARAMS = ('course_id', 'enrollment_action', 'course_mode', 'email_opt_in', 'purchase_workflow') -def get_next_url_for_login_page(request): +def get_next_url_for_login_page(request, include_host=False): """ Determine the URL to redirect to following login/registration/third_party_auth @@ -249,6 +249,7 @@ def get_next_url_for_login_page(request): request_params=request_params, request_is_https=request.is_secure(), ) + root_url = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL) if not redirect_to: if settings.ROOT_URLCONF == 'lms.urls': login_redirect_url = configuration_helpers.get_value('DEFAULT_REDIRECT_AFTER_LOGIN') @@ -270,16 +271,26 @@ def get_next_url_for_login_page(request): elif settings.ROOT_URLCONF == 'cms.urls': redirect_to = reverse('home') + scheme = "https" if settings.HTTPS == "on" else "http" + root_url = '{}://{}'.format(scheme, settings.CMS_BASE) if any(param in request_params for param in POST_AUTH_PARAMS): # Before we redirect to next/dashboard, we need to handle auto-enrollment: params = [(param, request_params[param]) for param in POST_AUTH_PARAMS if param in request_params] + params.append(('next', redirect_to)) # After auto-enrollment, user will be sent to payment page or to this URL redirect_to = '{}?{}'.format(reverse('finish_auth'), urllib.parse.urlencode(params)) # Note: if we are resuming a third party auth pipeline, then the next URL will already # be saved in the session as part of the pipeline state. That URL will take priority # over this one. + if include_host: + (scheme, netloc, path, query, fragment) = list(urllib.parse.urlsplit(redirect_to)) + if not netloc: + parse_root_url = urllib.parse.urlsplit(root_url) + redirect_to = urllib.parse.urlunsplit((parse_root_url.scheme, parse_root_url.netloc, + path, query, fragment)) + # Append a tpa_hint query parameter, if one is configured tpa_hint = configuration_helpers.get_value( "THIRD_PARTY_AUTH_HINT", diff --git a/openedx/core/djangoapps/user_authn/views/login.py b/openedx/core/djangoapps/user_authn/views/login.py index c8ceea2a8a..638ca779d7 100644 --- a/openedx/core/djangoapps/user_authn/views/login.py +++ b/openedx/core/djangoapps/user_authn/views/login.py @@ -446,8 +446,9 @@ def login_user(request): if is_user_third_party_authenticated: running_pipeline = pipeline.get(request) redirect_url = pipeline.get_complete_url(backend_name=running_pipeline['backend']) + elif should_redirect_to_logistration_mircrofrontend(): - redirect_url = get_next_url_for_login_page(request) + redirect_url = get_next_url_for_login_page(request, include_host=True) response = JsonResponse({ 'success': True, diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py index dcfd42bf63..7220771e84 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py @@ -18,7 +18,6 @@ from django.http import HttpResponse from django.test.client import Client from django.test.utils import override_settings from django.urls import NoReverseMatch, reverse -from freezegun import freeze_time from mock import patch from six.moves import range @@ -90,25 +89,19 @@ class LoginTest(SiteMixin, CacheIsolationTestCase): { 'next_url': None, 'course_id': None, - 'expected_redirect': '/dashboard', + 'expected_redirect': settings.LMS_ROOT_URL + '/dashboard', }, - # A relative path is an acceptable redirect. + # Added root url in next . { 'next_url': '/harmless-relative-page', 'course_id': None, - 'expected_redirect': '/harmless-relative-page', - }, - # Paths without trailing slashes are also considered relative. - { - 'next_url': 'courses', - 'course_id': None, - 'expected_redirect': 'courses', + 'expected_redirect': settings.LMS_ROOT_URL + '/harmless-relative-page', }, # An absolute URL to a non-whitelisted domain is not an acceptable redirect. { 'next_url': 'https://evil.sketchysite', 'course_id': None, - 'expected_redirect': '/dashboard', + 'expected_redirect': settings.LMS_ROOT_URL + '/dashboard', }, # An absolute URL to a whitelisted domain is acceptable. { @@ -121,7 +114,8 @@ class LoginTest(SiteMixin, CacheIsolationTestCase): 'next_url': None, 'course_id': 'coursekey', 'expected_redirect': ( - '/account/finish_auth?course_id=coursekey&next=%2Fdashboard' + '{root_url}/account/finish_auth?course_id=coursekey&next=%2Fdashboard'. + format(root_url=settings.LMS_ROOT_URL) ), }, # If valid course_id AND next_url are provided, redirect to finish_auth with @@ -130,7 +124,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase): 'next_url': 'freshpage', 'course_id': 'coursekey', 'expected_redirect': ( - '/account/finish_auth?course_id=coursekey&next=freshpage' + settings.LMS_ROOT_URL + '/account/finish_auth?course_id=coursekey&next=freshpage' ) }, # If course_id is provided with invalid next_url, redirect to finish_auth with @@ -139,7 +133,8 @@ class LoginTest(SiteMixin, CacheIsolationTestCase): 'next_url': 'http://scam.scam', 'course_id': 'coursekey', 'expected_redirect': ( - '/account/finish_auth?course_id=coursekey&next=%2Fdashboard' + '{root_url}/account/finish_auth?course_id=coursekey&next=%2Fdashboard'. + format(root_url=settings.LMS_ROOT_URL) ), }, )