remove studio signin and signup pages

This completes the work started in https://github.com/edx/edx-platform/pull/19453
to use the LMS login and registration for Studio, rather than Studio
providing its own implementation.

LMS login/registration are being used for the following reasons:
1. LMS logistration properly handles all SSO integrations.
2. A single logistration is simpler to maintain and understand.
3. Allows Studio to work more like all other IDAs that use LMS
logistration.

The original switch to use LMS logistration for Studio also added the
toggle `DISABLE_STUDIO_SSO_OVER_LMS` to provide the community some
additional time for switching. This commit removes this toggle, which
at this point means all deployments will use the LMS logistration.

This change requires sharing cookies across LMS and Studio. Should that
prove to be a problem for certain Open edX instances, there are
discussions of possible alternative solutions.
See https://github.com/edx/edx-platform/pull/19845#issuecomment-559154256

Detailed changes:
* Fix some Studio links that still went to old Studio signin and signup.
* Remove DISABLE_STUDIO_SSO_OVER_LMS feature toggle.
* Remove old studio signin and signup pages and templates.
* Fix url name "login", which had different meanings for Studio and LMS.
* Use the following settings: LOGIN_URL, FRONTEND_LOGIN_URL,
FRONTEND_LOGOUT_URL, and FRONTEND_REGISTER_URL.
* Redirect /signin and /signup to the LMS logistration.
* Add custom metric `uses_pattern_library`.
* Add custom metric `student_activate_account`.
* Add Django Settings to allow /signin, /signup, and /login_post to be
disabled once ready.

This work also relates to ARCH-218 and DEPR-6.

ARCH-1253
This commit is contained in:
Robert Raposa
2019-11-27 11:31:24 -05:00
parent 8fc357bb2e
commit 2202545aec
42 changed files with 227 additions and 1069 deletions

View File

@@ -10,7 +10,6 @@ from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from testfixtures import LogCapture
@@ -57,7 +56,7 @@ class TestLoginHelper(TestCase):
def test_next_failures(self, log_level, log_name, unsafe_url, http_accept, user_agent, expected_log):
""" Test unsafe next parameter """
with LogCapture(LOGGER_NAME, level=log_level) as logger:
req = self.request.get(reverse("login") + "?next={url}".format(url=unsafe_url))
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=unsafe_url))
req.META["HTTP_ACCEPT"] = http_accept # pylint: disable=no-member
req.META["HTTP_USER_AGENT"] = user_agent # pylint: disable=no-member
get_next_url_for_login_page(req)
@@ -75,7 +74,7 @@ class TestLoginHelper(TestCase):
@override_settings(LOGIN_REDIRECT_WHITELIST=['test.edx.org', 'test2.edx.org'])
def test_safe_next(self, next_url, host):
""" Test safe next parameter """
req = self.request.get(reverse("login") + "?next={url}".format(url=next_url), HTTP_HOST=host)
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url), HTTP_HOST=host)
req.META["HTTP_ACCEPT"] = "text/html" # pylint: disable=no-member
next_page = get_next_url_for_login_page(req)
self.assertEqual(next_page, next_url)
@@ -103,7 +102,7 @@ class TestLoginHelper(TestCase):
mock_running_pipeline.return_value = running_pipeline
def validate_login():
req = self.request.get(reverse("login") + "?next={url}".format(url=next_url))
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url))
req.META["HTTP_ACCEPT"] = "text/html" # pylint: disable=no-member
self._add_session(req)
next_page = get_next_url_for_login_page(req)

View File

@@ -14,10 +14,7 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import AnonymousUser, User
from django.contrib.auth.views import password_reset_confirm
from django.contrib.sites.models import Site
from django.core import mail
from django.core.exceptions import ObjectDoesNotExist
from django.core.validators import ValidationError, validate_email
from django.db import transaction
from django.db.models.signals import post_save
@@ -25,10 +22,7 @@ from django.dispatch import Signal, receiver
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import redirect
from django.template.context_processors import csrf
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.encoding import force_bytes, force_text
from django.utils.http import base36_to_int, urlsafe_base64_encode
from django.utils.translation import ugettext as _
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
from django.views.decorators.http import require_GET, require_http_methods, require_POST
@@ -53,16 +47,11 @@ from openedx.core.djangoapps.ace_common.template_context import get_base_templat
from openedx.core.djangoapps.catalog.utils import get_programs_with_type
from openedx.core.djangoapps.embargo import api as embargo_api
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
from openedx.core.djangoapps.oauth_dispatch.api import destroy_oauth_tokens
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming import helpers as theming_helpers
from openedx.core.djangoapps.theming.helpers import get_current_site
from openedx.core.djangoapps.user_api.accounts.utils import is_secondary_email_feature_enabled
from openedx.core.djangoapps.user_api.config.waffle import PREVENT_AUTH_USER_WRITES, SYSTEM_MAINTENANCE_MSG, waffle
from openedx.core.djangoapps.user_api.models import UserRetirementRequest
from openedx.core.djangoapps.user_api.preferences import api as preferences_api
from openedx.core.djangoapps.user_authn.message_types import PasswordReset
from openedx.core.djangolib.markup import HTML, Text
from student.helpers import DISABLE_UNENROLL_CERT_STATES, cert_info, generate_activation_email_context
from student.message_types import AccountActivation, EmailChange, EmailChangeConfirmation, RecoveryEmailCreate
@@ -83,10 +72,8 @@ from student.models import (
from student.signals import REFUND_ORDER
from student.tasks import send_activation_email
from student.text_me_the_app import TextMeTheAppFragmentView
from util.request_rate_limiter import BadRequestRateLimiter, PasswordResetEmailRateLimiter
from util.db import outer_atomic
from util.json_request import JsonResponse
from util.password_policy_validators import normalize_password, validate_password
from xmodule.modulestore.django import modulestore
log = logging.getLogger("edx.student")
@@ -519,8 +506,12 @@ def activate_account(request, key):
"""
# If request is in Studio call the appropriate view
if theming_helpers.get_project_root_name().lower() == u'cms':
monitoring_utils.set_custom_metric('student_activate_account', 'cms')
return activate_account_studio(request, key)
# TODO: Use metric to determine if there are any `activate_account` calls for cms in Production.
# If not, the templates wouldn't be needed for cms, but we still need a way to activate for cms tests.
monitoring_utils.set_custom_metric('student_activate_account', 'lms')
try:
registration = Registration.objects.get(activation_key=key)
except (Registration.DoesNotExist, Registration.MultipleObjectsReturned):