def test_saml_auth_with_error( self, url_name, current_backend, current_provider, enterprise_customer_mock, ): params = [] request = RequestFactory().get(reverse(url_name), params, HTTP_ACCEPT='text/html') SessionMiddleware().process_request(request) request.user = AnonymousUser() self.enable_saml() dummy_idp = 'testshib' self._configure_testshib_provider(current_provider, dummy_idp) enterprise_customer_data = { 'uuid': '72416e52-8c77-4860-9584-15e5b06220fb', 'name': 'Dummy Enterprise', 'identity_provider': dummy_idp, } enterprise_customer_mock.return_value = enterprise_customer_data dummy_error_message = 'Authentication failed: SAML login failed ' \ '["invalid_response"] [SAML Response must contain 1 assertion]' # Add error message for error in auth pipeline MessageMiddleware().process_request(request) messages.error(request, dummy_error_message, extra_tags='social-auth') # Simulate a running pipeline pipeline_response = { 'response': { 'idp_name': dummy_idp } } pipeline_target = 'openedx.core.djangoapps.user_authn.views.login_form.third_party_auth.pipeline' with simulate_running_pipeline(pipeline_target, current_backend, **pipeline_response): with mock.patch('edxmako.request_context.get_current_request', return_value=request): response = login_and_registration_form(request) expected_error_message = Text(_( u'We are sorry, you are not authorized to access {platform_name} via this channel. ' u'Please contact your learning administrator or manager in order to access {platform_name}.' u'{line_break}{line_break}' u'Error Details:{line_break}{error_message}') ).format( platform_name=settings.PLATFORM_NAME, error_message=dummy_error_message, line_break=HTML('<br/>') ) self._assert_saml_auth_data_with_error( response, current_backend, current_provider, expected_error_message )
def test_new_account_registration_fails_if_email_exists(self): request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') backend = strategy.request.backend backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # pylint: disable=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(backend, social_views._do_login, request=request)) with self._patch_edxmako_current_request(request): self.assert_register_response_in_pipeline_looks_correct( login_and_registration_form(strategy.request, initial_mode='register'), pipeline.get(request)['kwargs'], ['name', 'username', 'email'] ) with self._patch_edxmako_current_request(strategy.request): strategy.request.POST = self.get_registration_post_vars() # Create twice: once successfully, and once causing a collision. create_account(strategy.request) self.assert_json_failure_response_is_username_collision(create_account(strategy.request))
def test_full_pipeline_succeeds_registering_new_account(self): # First, create, the request and strategy that store pipeline state. # Mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # Begin! Grab the registration page and check the login control on it. self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register')) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct(self.client.get( pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))) # Next, the provider makes a request against /auth/complete/<provider>. # pylint: disable=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(request.backend, social_views._do_login, request=request)) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the registration form. with self._patch_edxmako_current_request(request): self.assert_register_response_in_pipeline_looks_correct( login_and_registration_form(strategy.request, initial_mode='register'), pipeline.get(request)['kwargs'], ['name', 'username', 'email'] ) # Next, we invoke the view that handles the POST. Not all providers # supply email. Manually add it as the user would have to; this # also serves as a test of overriding provider values. Always provide a # password for us to check that we override it properly. overridden_password = strategy.request.POST.get('password') email = '*****@*****.**' if not strategy.request.POST.get('email'): strategy.request.POST = self.get_registration_post_vars({'email': email}) # The user must not exist yet... with self.assertRaises(auth_models.User.DoesNotExist): self.get_user_by_email(strategy, email) # ...but when we invoke create_account the existing edX view will make # it, but not social auths. The pipeline creates those later. with self._patch_edxmako_current_request(strategy.request): self.assert_json_success_response_looks_correct(create_account(strategy.request), verify_redirect_url=False) # We've overridden the user's password, so authenticate() with the old # value won't work: created_user = self.get_user_by_email(strategy, email) self.assert_password_overridden_by_pipeline(overridden_password, created_user.username) # At this point the user object exists, but there is no associated # social auth. self.assert_social_auth_does_not_exist_for_user(created_user, strategy) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect(actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request )) # Set the cookie and try again self.set_logged_in_cookies(request) self.assert_redirect_after_pipeline_completes( actions.do_complete(strategy.request.backend, social_views._do_login, user=created_user, request=request)) # Now the user has been redirected to the dashboard. Their third party account should now be linked. self.assert_social_auth_exists_for_user(created_user, strategy) self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)