diff --git a/common/djangoapps/third_party_auth/pipeline.py b/common/djangoapps/third_party_auth/pipeline.py index b6561c9259..6701ee372f 100644 --- a/common/djangoapps/third_party_auth/pipeline.py +++ b/common/djangoapps/third_party_auth/pipeline.py @@ -112,7 +112,6 @@ AUTH_EMAIL_OPT_IN_KEY = 'email_opt_in' AUTH_ENTRY_DASHBOARD = 'dashboard' AUTH_ENTRY_LOGIN = 'login' -AUTH_ENTRY_PROFILE = 'profile' AUTH_ENTRY_REGISTER = 'register' # This is left-over from an A/B test @@ -143,16 +142,11 @@ AUTH_DISPATCH_URLS = { AUTH_ENTRY_LOGIN_2: '/account/login/', AUTH_ENTRY_REGISTER_2: '/account/register/', - # If linking/unlinking an account from the new student profile - # page, redirect to the profile page. Only used if - # `FEATURES['ENABLE_NEW_DASHBOARD']` is true. - AUTH_ENTRY_PROFILE: '/profile/', } _AUTH_ENTRY_CHOICES = frozenset([ AUTH_ENTRY_DASHBOARD, AUTH_ENTRY_LOGIN, - AUTH_ENTRY_PROFILE, AUTH_ENTRY_REGISTER, # This is left-over from an A/B test @@ -452,8 +446,6 @@ def parse_query_params(strategy, response, *args, **kwargs): 'is_login': auth_entry in [AUTH_ENTRY_LOGIN, AUTH_ENTRY_LOGIN_2], # Whether the auth pipeline entered from /register. 'is_register': auth_entry in [AUTH_ENTRY_REGISTER, AUTH_ENTRY_REGISTER_2], - # Whether the auth pipeline entered from /profile. - 'is_profile': auth_entry == AUTH_ENTRY_PROFILE, # Whether the auth pipeline entered from an API 'is_api': auth_entry == AUTH_ENTRY_API, } diff --git a/common/djangoapps/third_party_auth/settings.py b/common/djangoapps/third_party_auth/settings.py index 7244f05bfe..9bba287743 100644 --- a/common/djangoapps/third_party_auth/settings.py +++ b/common/djangoapps/third_party_auth/settings.py @@ -51,8 +51,6 @@ _MIDDLEWARE_CLASSES = ( 'third_party_auth.middleware.ExceptionMiddleware', ) _SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/dashboard' -_SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/profile' -_SOCIAL_AUTH_DISCONNECT_REDIRECT_URL = '/profile' def _merge_auth_info(django_settings, auth_info): @@ -97,11 +95,6 @@ def _set_global_settings(django_settings): # Where to send the user once social authentication is successful. django_settings.SOCIAL_AUTH_LOGIN_REDIRECT_URL = _SOCIAL_AUTH_LOGIN_REDIRECT_URL - # Change redirects to the profile page if we enable the new dashboard. - if django_settings.FEATURES.get('ENABLE_NEW_DASHBOARD', ''): - django_settings.SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = _SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL - django_settings.SOCIAL_AUTH_DISCONNECT_REDIRECT_URL = _SOCIAL_AUTH_DISCONNECT_REDIRECT_URL - # Inject our customized auth pipeline. All auth backends must work with # this pipeline. django_settings.SOCIAL_AUTH_PIPELINE = ( diff --git a/lms/djangoapps/student_account/test/test_views.py b/lms/djangoapps/student_account/test/test_views.py index c9a708a6c7..75a2354b0a 100644 --- a/lms/djangoapps/student_account/test/test_views.py +++ b/lms/djangoapps/student_account/test/test_views.py @@ -59,7 +59,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase): INVALID_KEY = u"123abc" - @mock.patch.dict(settings.FEATURES, {'ENABLE_NEW_DASHBOARD': True}) def setUp(self): super(StudentAccountUpdateTest, self).setUp("student_account.urls") @@ -71,141 +70,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase): result = self.client.login(username=self.USERNAME, password=self.OLD_PASSWORD) self.assertTrue(result) - def test_index(self): - response = self.client.get(reverse('account_index')) - self.assertContains(response, "Student Account") - - def test_change_email(self): - response = self._change_email(self.NEW_EMAIL, self.OLD_PASSWORD) - self.assertEquals(response.status_code, 200) - - # Verify that the email associated with the account remains unchanged - profile_info = profile_api.profile_info(self.USERNAME) - self.assertEquals(profile_info['email'], self.OLD_EMAIL) - - # Check that an email was sent with the activation key - self.assertEqual(len(mail.outbox), 1) - self._assert_email( - mail.outbox[0], - [self.NEW_EMAIL], - u"Email Change Request", - u"There was recently a request to change the email address" - ) - - # Retrieve the activation key from the email - email_body = mail.outbox[0].body - result = re.search('/email/confirmation/([^ \n]+)', email_body) - self.assertIsNot(result, None) - activation_key = result.group(1) - - # Attempt to activate the email - response = self.client.get(reverse('email_change_confirm', kwargs={'key': activation_key})) - self.assertEqual(response.status_code, 200) - - # Verify that the email was changed - profile_info = profile_api.profile_info(self.USERNAME) - self.assertEquals(profile_info['email'], self.NEW_EMAIL) - - # Verify that notification emails were sent - self.assertEqual(len(mail.outbox), 2) - self._assert_email( - mail.outbox[1], - [self.OLD_EMAIL, self.NEW_EMAIL], - u"Email Change Successful", - u"You successfully changed the email address" - ) - - def test_email_change_wrong_password(self): - response = self._change_email(self.NEW_EMAIL, "wrong password") - self.assertEqual(response.status_code, 401) - - def test_email_change_request_no_user(self): - # Patch account API to raise an internal error when an email change is requested - with mock.patch('student_account.views.account_api.request_email_change') as mock_call: - mock_call.side_effect = account_api.AccountUserNotFound - response = self._change_email(self.NEW_EMAIL, self.OLD_PASSWORD) - - self.assertEquals(response.status_code, 400) - - def test_email_change_request_email_taken_by_active_account(self): - # Create/activate a second user with the new email - activation_key = account_api.create_account(self.ALTERNATE_USERNAME, self.OLD_PASSWORD, self.NEW_EMAIL) - account_api.activate_account(activation_key) - - # Request to change the original user's email to the email now used by the second user - response = self._change_email(self.NEW_EMAIL, self.OLD_PASSWORD) - self.assertEquals(response.status_code, 409) - - def test_email_change_request_email_taken_by_inactive_account(self): - # Create a second user with the new email, but don't active them - account_api.create_account(self.ALTERNATE_USERNAME, self.OLD_PASSWORD, self.NEW_EMAIL) - - # Request to change the original user's email to the email used by the inactive user - response = self._change_email(self.NEW_EMAIL, self.OLD_PASSWORD) - self.assertEquals(response.status_code, 200) - - @ddt.data(*INVALID_EMAILS) - def test_email_change_request_email_invalid(self, invalid_email): - # Request to change the user's email to an invalid address - response = self._change_email(invalid_email, self.OLD_PASSWORD) - self.assertEquals(response.status_code, 400) - - def test_email_change_confirmation(self): - # Get an email change activation key - activation_key = account_api.request_email_change(self.USERNAME, self.NEW_EMAIL, self.OLD_PASSWORD) - - # Follow the link sent in the confirmation email - response = self.client.get(reverse('email_change_confirm', kwargs={'key': activation_key})) - self.assertContains(response, "Email change successful") - - # Verify that the email associated with the account has changed - profile_info = profile_api.profile_info(self.USERNAME) - self.assertEquals(profile_info['email'], self.NEW_EMAIL) - - def test_email_change_confirmation_invalid_key(self): - # Visit the confirmation page with an invalid key - response = self.client.get(reverse('email_change_confirm', kwargs={'key': self.INVALID_KEY})) - self.assertContains(response, "Something went wrong") - - # Verify that the email associated with the account has not changed - profile_info = profile_api.profile_info(self.USERNAME) - self.assertEquals(profile_info['email'], self.OLD_EMAIL) - - def test_email_change_confirmation_email_already_exists(self): - # Get an email change activation key - email_activation_key = account_api.request_email_change(self.USERNAME, self.NEW_EMAIL, self.OLD_PASSWORD) - - # Create/activate a second user with the new email - account_activation_key = account_api.create_account(self.ALTERNATE_USERNAME, self.OLD_PASSWORD, self.NEW_EMAIL) - account_api.activate_account(account_activation_key) - - # Follow the link sent to the original user - response = self.client.get(reverse('email_change_confirm', kwargs={'key': email_activation_key})) - self.assertContains(response, "address you wanted to use is already used") - - # Verify that the email associated with the original account has not changed - profile_info = profile_api.profile_info(self.USERNAME) - self.assertEquals(profile_info['email'], self.OLD_EMAIL) - - def test_email_change_confirmation_internal_error(self): - # Get an email change activation key - activation_key = account_api.request_email_change(self.USERNAME, self.NEW_EMAIL, self.OLD_PASSWORD) - - # Patch account API to return an internal error - with mock.patch('student_account.views.account_api.confirm_email_change') as mock_call: - mock_call.side_effect = account_api.AccountInternalError - response = self.client.get(reverse('email_change_confirm', kwargs={'key': activation_key})) - - self.assertContains(response, "Something went wrong") - - def test_email_change_request_missing_email_param(self): - response = self._change_email(None, self.OLD_PASSWORD) - self.assertEqual(response.status_code, 400) - - def test_email_change_request_missing_password_param(self): - response = self._change_email(self.OLD_EMAIL, None) - self.assertEqual(response.status_code, 400) - @skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in LMS') def test_password_change(self): # Request a password change while logged in, simulating @@ -316,25 +180,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase): self.assertEqual(response.status_code, 403) @ddt.data( - ('get', 'account_index', []), - ('post', 'email_change_request', []), - ('get', 'email_change_confirm', [123]) - ) - @ddt.unpack - def test_require_login(self, method, url_name, args): - # Access the page while logged out - self.client.logout() - url = reverse(url_name, args=args) - response = getattr(self.client, method)(url, follow=True) - - # Should have been redirected to the login page - self.assertEqual(len(response.redirect_chain), 1) - self.assertIn('accounts/login?next=', response.redirect_chain[0][0]) - - @ddt.data( - ('get', 'account_index', []), - ('post', 'email_change_request', []), - ('get', 'email_change_confirm', [123]), ('post', 'password_change_request', []), ) @ddt.unpack @@ -346,24 +191,6 @@ class StudentAccountUpdateTest(UrlResetMixin, TestCase): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 405) - def _assert_email(self, email, expected_to, expected_subject, expected_body): - """Check whether an email has the correct properties. """ - self.assertEqual(email.to, expected_to) - self.assertIn(expected_subject, email.subject) - self.assertIn(expected_body, email.body) - - def _change_email(self, new_email, password): - """Request to change the user's email. """ - data = {} - - if new_email is not None: - data['email'] = new_email - if password is not None: - # We can't pass a Unicode object to urlencode, so we encode the Unicode object - data['password'] = password.encode('utf-8') - - return self.client.post(path=reverse('email_change_request'), data=data) - def _change_password(self, email=None): """Request to change the user's password. """ data = {} diff --git a/lms/djangoapps/student_account/urls.py b/lms/djangoapps/student_account/urls.py index 945edbd9cd..4f5eba7c04 100644 --- a/lms/djangoapps/student_account/urls.py +++ b/lms/djangoapps/student_account/urls.py @@ -11,11 +11,3 @@ if settings.FEATURES.get('ENABLE_COMBINED_LOGIN_REGISTRATION'): url(r'^register/$', 'login_and_registration_form', {'initial_mode': 'register'}, name='account_register'), url(r'^password$', 'password_change_request_handler', name='password_change_request'), ) - -if settings.FEATURES.get('ENABLE_NEW_DASHBOARD'): - urlpatterns += patterns( - 'student_account.views', - url(r'^$', 'index', name='account_index'), - url(r'^email$', 'email_change_request_handler', name='email_change_request'), - url(r'^email/confirmation/(?P[^/]*)$', 'email_change_confirmation_handler', name='email_change_confirm'), - ) diff --git a/lms/djangoapps/student_account/views.py b/lms/djangoapps/student_account/views.py index 36d5aa7209..042f893422 100644 --- a/lms/djangoapps/student_account/views.py +++ b/lms/djangoapps/student_account/views.py @@ -42,31 +42,6 @@ from student_account.helpers import auth_pipeline_urls AUDIT_LOG = logging.getLogger("audit") -@login_required -@require_http_methods(['GET']) -def index(request): - """Render the account info page. - - Args: - request (HttpRequest) - - Returns: - HttpResponse: 200 if the index page was sent successfully - HttpResponse: 302 if not logged in (redirect to login page) - HttpResponse: 405 if using an unsupported HTTP method - - Example usage: - - GET /account - - """ - return render_to_response( - 'student_account/index.html', { - 'disable_courseware_js': True, - } - ) - - @require_http_methods(['GET']) @ensure_csrf_cookie def login_and_registration_form(request, initial_mode="login"): @@ -124,145 +99,6 @@ def login_and_registration_form(request, initial_mode="login"): return render_to_response('student_account/login_and_register.html', context) -@login_required -@require_http_methods(['POST']) -@ensure_csrf_cookie -def email_change_request_handler(request): - """Handle a request to change the user's email address. - - Sends an email to the newly specified address containing a link - to a confirmation page. - - Args: - request (HttpRequest) - - Returns: - HttpResponse: 200 if the confirmation email was sent successfully - HttpResponse: 302 if not logged in (redirect to login page) - HttpResponse: 400 if the format of the new email is incorrect, or if - an email change is requested for a user which does not exist - HttpResponse: 401 if the provided password (in the form) is incorrect - HttpResponse: 405 if using an unsupported HTTP method - HttpResponse: 409 if the provided email is already in use - - Example usage: - - POST /account/email - - """ - username = request.user.username - password = request.POST.get('password') - new_email = request.POST.get('email') - - if new_email is None: - return HttpResponseBadRequest("Missing param 'email'") - if password is None: - return HttpResponseBadRequest("Missing param 'password'") - - old_email = profile_api.profile_info(username)['email'] - - try: - key = account_api.request_email_change(username, new_email, password) - except (account_api.AccountEmailInvalid, account_api.AccountUserNotFound): - return HttpResponseBadRequest() - except account_api.AccountEmailAlreadyExists: - return HttpResponse(status=409) - except account_api.AccountNotAuthorized: - return HttpResponse(status=401) - - context = { - 'key': key, - 'old_email': old_email, - 'new_email': new_email, - } - - subject = render_to_string('student_account/emails/email_change_request/subject_line.txt', context) - subject = ''.join(subject.splitlines()) - message = render_to_string('student_account/emails/email_change_request/message_body.txt', context) - - from_address = microsite.get_value( - 'email_from_address', - settings.DEFAULT_FROM_EMAIL - ) - - # Send a confirmation email to the new address containing the activation key - send_mail(subject, message, from_address, [new_email]) - - return HttpResponse(status=200) - - -@login_required -@require_http_methods(['GET']) -def email_change_confirmation_handler(request, key): - """Complete a change of the user's email address. - - This is called when the activation link included in the confirmation - email is clicked. - - Args: - request (HttpRequest) - - Returns: - HttpResponse: 200 if the email change is successful, the activation key - is invalid, the new email is already in use, or the - user to which the email change will be applied does - not exist - HttpResponse: 302 if not logged in (redirect to login page) - HttpResponse: 405 if using an unsupported HTTP method - - Example usage: - - GET /account/email/confirmation/{key} - - """ - try: - old_email, new_email = account_api.confirm_email_change(key) - except account_api.AccountNotAuthorized: - return render_to_response( - 'student_account/email_change_failed.html', { - 'disable_courseware_js': True, - 'error': 'key_invalid', - } - ) - except account_api.AccountEmailAlreadyExists: - return render_to_response( - 'student_account/email_change_failed.html', { - 'disable_courseware_js': True, - 'error': 'email_used', - } - ) - except account_api.AccountInternalError: - return render_to_response( - 'student_account/email_change_failed.html', { - 'disable_courseware_js': True, - 'error': 'internal', - } - ) - - context = { - 'old_email': old_email, - 'new_email': new_email, - } - - subject = render_to_string('student_account/emails/email_change_confirmation/subject_line.txt', context) - subject = ''.join(subject.splitlines()) - message = render_to_string('student_account/emails/email_change_confirmation/message_body.txt', context) - - from_address = microsite.get_value( - 'email_from_address', - settings.DEFAULT_FROM_EMAIL - ) - - # Notify both old and new emails of the change - send_mail(subject, message, from_address, [old_email, new_email]) - - return render_to_response( - 'student_account/email_change_successful.html', { - 'disable_courseware_js': True, - } - ) - - @require_http_methods(['POST']) def password_change_request_handler(request): """Handle password change requests originating from the account page. diff --git a/lms/envs/common.py b/lms/envs/common.py index d35f902666..fdf7b6aaef 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -313,9 +313,6 @@ FEATURES = { # ENABLE_OAUTH2_PROVIDER to True 'ENABLE_MOBILE_REST_API': False, - # Enable the new dashboard, account, and profile pages - 'ENABLE_NEW_DASHBOARD': False, - # Enable the combined login/registration form 'ENABLE_COMBINED_LOGIN_REGISTRATION': False, diff --git a/lms/templates/student_account/email_change_failed.html b/lms/templates/student_account/email_change_failed.html deleted file mode 100644 index 5b24f9c262..0000000000 --- a/lms/templates/student_account/email_change_failed.html +++ /dev/null @@ -1,30 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> -<%! from django.core.urlresolvers import reverse %> -<%inherit file="../main.html" /> - -
-
-

${_("Email change failed.")}

-
- -

- % if error is 'key_invalid' or error is 'internal': - ${_("Something went wrong. Please contact {support} for help.").format( - support="{support_email}".format( - support_email=settings.TECH_SUPPORT_EMAIL - ) - )} - % elif error is 'email_used': - ${_("The email address you wanted to use is already used by another " - "{platform_name} account.").format(platform_name=settings.PLATFORM_NAME)} - % endif -

- -

- ${_("You can try again from the {link_start}account settings{link_end} page.").format( - link_start="".format(url=reverse('account_index')), - link_end="" - )} -

-
-
diff --git a/lms/templates/student_account/email_change_successful.html b/lms/templates/student_account/email_change_successful.html deleted file mode 100644 index 5cc4d17444..0000000000 --- a/lms/templates/student_account/email_change_successful.html +++ /dev/null @@ -1,18 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> -<%! from django.core.urlresolvers import reverse %> -<%inherit file="../main.html" /> - -
-
-

${_("Email change successful!")}

-
- -

- ${_("You should see your new email address listed on the " - "{link_start}account settings{link_end} page.").format( - link_start="".format(url=reverse('account_index')), - link_end="", - )} -

-
-
diff --git a/lms/templates/student_account/emails/email_change_confirmation/message_body.txt b/lms/templates/student_account/emails/email_change_confirmation/message_body.txt deleted file mode 100644 index 8608aa6d8d..0000000000 --- a/lms/templates/student_account/emails/email_change_confirmation/message_body.txt +++ /dev/null @@ -1,21 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> - -## TODO: Get sign-off from Product on new copy, and think about -## turning this into a large, multi-line message for i18n purposes. -## Greeting -${_("Hi there,")} - -## Preamble -${_("You successfully changed the email address associated with your " - "{platform_name} account from {old_email} to {new_email}.").format( - platform_name=settings.PLATFORM_NAME, - old_email=old_email, - new_email=new_email - ) -} - -## Translators: This is the signature of an email. "\n" is a newline character, -## and should be placed between the closing word and the signing team's name. -${_("Thanks,\n - The {platform_name} Team").format( - platform_name=settings.PLATFORM_NAME, -)} diff --git a/lms/templates/student_account/emails/email_change_confirmation/subject_line.txt b/lms/templates/student_account/emails/email_change_confirmation/subject_line.txt deleted file mode 100644 index 57eeadc97c..0000000000 --- a/lms/templates/student_account/emails/email_change_confirmation/subject_line.txt +++ /dev/null @@ -1,3 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> - -${_("{platform_name} Email Change Successful").format(platform_name=settings.PLATFORM_NAME)} diff --git a/lms/templates/student_account/emails/email_change_request/message_body.txt b/lms/templates/student_account/emails/email_change_request/message_body.txt deleted file mode 100644 index ab7a6999ef..0000000000 --- a/lms/templates/student_account/emails/email_change_request/message_body.txt +++ /dev/null @@ -1,34 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> - -## TODO: Get sign-off from Product on new copy, and think about -## turning this into a large, multi-line message for i18n purposes. -## Greeting -${_("Hi there,")} - -## Preamble -${_("There was recently a request to change the email address associated " - "with your {platform_name} account from {old_email} to {new_email}. " - "If you requested this change, please confirm your new email address " - "by following the link below:").format( - platform_name=settings.PLATFORM_NAME, - old_email=old_email, - new_email=new_email - ) -} - -## Confirmation link -% if is_secure: -https://${site}/account/email/confirmation/${key} -% else: -http://${site}/account/email/confirmation/${key} -% endif - -## Closing -${_("If you don't want to change the email address associated with your " - "account, ignore this message.")} - -## Translators: This is the signature of an email. "\n" is a newline character, -## and should be placed between the closing word and the signing team's name. -${_("Thanks,\n - The {platform_name} Team").format( - platform_name=settings.PLATFORM_NAME, -)} diff --git a/lms/templates/student_account/emails/email_change_request/subject_line.txt b/lms/templates/student_account/emails/email_change_request/subject_line.txt deleted file mode 100644 index a409534d94..0000000000 --- a/lms/templates/student_account/emails/email_change_request/subject_line.txt +++ /dev/null @@ -1,3 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> - -${_("{platform_name} Email Change Request").format(platform_name=settings.PLATFORM_NAME)} diff --git a/lms/templates/student_account/index.html b/lms/templates/student_account/index.html deleted file mode 100644 index 0b9ed36aa5..0000000000 --- a/lms/templates/student_account/index.html +++ /dev/null @@ -1,26 +0,0 @@ -<%! from django.utils.translation import ugettext as _ %> -<%namespace name='static' file='/static_content.html'/> - -<%inherit file="../main.html" /> - -<%block name="pagetitle">${_("Student Account")} - -<%block name="js_extra"> - - - <%static:js group='student_account'/> - - -<%block name="header_extras"> -% for template_name in ["account"]: - -% endfor - - -

Student Account

- -

This is a placeholder for the student's account page.

- -