From 123584e5af3c25d3c608dc1ec6d3c2fd76cba053 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 3 May 2017 03:39:48 -0400 Subject: [PATCH] ENT-361: Allow hiding of IDP selection page during SSO Closes ENT-361. --- ...0010_add_skip_hinted_login_dialog_field.py | 29 +++++++++++++++++++ common/djangoapps/third_party_auth/models.py | 8 +++++ .../student_account/test/test_views.py | 14 ++++++++- lms/djangoapps/student_account/views.py | 9 +++++- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 common/djangoapps/third_party_auth/migrations/0010_add_skip_hinted_login_dialog_field.py diff --git a/common/djangoapps/third_party_auth/migrations/0010_add_skip_hinted_login_dialog_field.py b/common/djangoapps/third_party_auth/migrations/0010_add_skip_hinted_login_dialog_field.py new file mode 100644 index 0000000000..fe017147d8 --- /dev/null +++ b/common/djangoapps/third_party_auth/migrations/0010_add_skip_hinted_login_dialog_field.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('third_party_auth', '0009_auto_20170415_1144'), + ] + + operations = [ + migrations.AddField( + model_name='ltiproviderconfig', + name='skip_hinted_login_dialog', + field=models.BooleanField(default=False, help_text='If this option is enabled, users that visit a "TPA hinted" URL for this provider (e.g. a URL ending with `?tpa_hint=[provider_name]`) will be forwarded directly to the login URL of the provider instead of being first prompted with a login dialog.'), + ), + migrations.AddField( + model_name='oauth2providerconfig', + name='skip_hinted_login_dialog', + field=models.BooleanField(default=False, help_text='If this option is enabled, users that visit a "TPA hinted" URL for this provider (e.g. a URL ending with `?tpa_hint=[provider_name]`) will be forwarded directly to the login URL of the provider instead of being first prompted with a login dialog.'), + ), + migrations.AddField( + model_name='samlproviderconfig', + name='skip_hinted_login_dialog', + field=models.BooleanField(default=False, help_text='If this option is enabled, users that visit a "TPA hinted" URL for this provider (e.g. a URL ending with `?tpa_hint=[provider_name]`) will be forwarded directly to the login URL of the provider instead of being first prompted with a login dialog.'), + ), + ] diff --git a/common/djangoapps/third_party_auth/models.py b/common/djangoapps/third_party_auth/models.py index 1398384ebc..626fd22d05 100644 --- a/common/djangoapps/third_party_auth/models.py +++ b/common/djangoapps/third_party_auth/models.py @@ -117,6 +117,14 @@ class ProviderConfig(ConfigurationModel): 'The Site that this provider configuration belongs to.' ), ) + skip_hinted_login_dialog = models.BooleanField( + default=False, + help_text=_( + "If this option is enabled, users that visit a \"TPA hinted\" URL for this provider " + "(e.g. a URL ending with `?tpa_hint=[provider_name]`) will be forwarded directly to " + "the login URL of the provider instead of being first prompted with a login dialog." + ), + ) skip_registration_form = models.BooleanField( default=False, help_text=_( diff --git a/lms/djangoapps/student_account/test/test_views.py b/lms/djangoapps/student_account/test/test_views.py index 8463388ee3..19817f8701 100644 --- a/lms/djangoapps/student_account/test/test_views.py +++ b/lms/djangoapps/student_account/test/test_views.py @@ -290,7 +290,7 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi super(StudentAccountLoginAndRegistrationTest, self).setUp() # Several third party auth providers are created for these tests: - self.configure_google_provider(enabled=True, visible=True) + self.google_provider = self.configure_google_provider(enabled=True, visible=True) self.configure_facebook_provider(enabled=True, visible=True) self.configure_dummy_provider( visible=True, @@ -443,6 +443,18 @@ class StudentAccountLoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMi response = self.client.get(reverse('signin_user'), params, HTTP_ACCEPT="text/html") self.assertNotIn(response.content, tpa_hint) + def test_hinted_login_dialog_disabled(self): + """Test that the dialog doesn't show up for hinted logins when disabled. """ + self.google_provider.skip_hinted_login_dialog = True + self.google_provider.save() + params = [("next", "/courses/something/?tpa_hint=oa2-google-oauth2")] + response = self.client.get(reverse('signin_user'), params, HTTP_ACCEPT="text/html") + self.assertRedirects( + response, + 'auth/login/google-oauth2/?auth_entry=login&next=%2Fcourses%2Fsomething%2F%3Ftpa_hint%3Doa2-google-oauth2', + target_status_code=302 + ) + @override_settings(SITE_NAME=settings.MICROSITE_TEST_HOSTNAME) def test_microsite_uses_old_login_page(self): # Retrieve the login page from a microsite domain diff --git a/lms/djangoapps/student_account/views.py b/lms/djangoapps/student_account/views.py index aadbf9fee6..d22c78409e 100644 --- a/lms/djangoapps/student_account/views.py +++ b/lms/djangoapps/student_account/views.py @@ -83,7 +83,14 @@ def login_and_registration_form(request, initial_mode="login"): try: next_args = urlparse.parse_qs(urlparse.urlparse(redirect_to).query) provider_id = next_args['tpa_hint'][0] - if third_party_auth.provider.Registry.get(provider_id=provider_id): + tpa_hint_provider = third_party_auth.provider.Registry.get(provider_id=provider_id) + if tpa_hint_provider: + if tpa_hint_provider.skip_hinted_login_dialog: + # Forward the user directly to the provider's login URL when the provider is configured + # to skip the dialog. + return redirect( + pipeline.get_login_url(provider_id, pipeline.AUTH_ENTRY_LOGIN, redirect_url=redirect_to) + ) third_party_auth_hint = provider_id initial_mode = "hinted_login" except (KeyError, ValueError, IndexError):