Beispiel #1
0
    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
        )
Beispiel #2
0
    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))
Beispiel #3
0
    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)