Esempio n. 1
0
    def test_full_pipeline_succeeds_for_linking_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        pipeline.analytics.track = mock.MagicMock()
        request.user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username(), skip_social_auth=True)

        # Instrument the pipeline to get to the dashboard with the full
        # expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        signin_user(strategy.request)
        login_user(strategy.request)
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        # First we expect that we're in the unlinked state, and that there
        # really is no association in the backend.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=False)
        self.assert_social_auth_does_not_exist_for_user(request.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)

        # Fire off the auth pipeline to link.
        self.assert_redirect_to_dashboard_looks_correct(
            actions.do_complete(
                request.backend,
                social_views._do_login,  # pylint: disable=protected-access
                request.user,
                None,
                redirect_field_name=auth.REDIRECT_FIELD_NAME,
                request=request
            )
        )

        # Now we expect to be in the linked state, with a backend entry.
        self.assert_social_auth_exists_for_user(request.user, strategy)
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
Esempio n. 2
0
    def test_full_pipeline_succeeds_for_linking_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        pipeline.analytics.track = mock.MagicMock()
        request.user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username(), skip_social_auth=True)

        # Instrument the pipeline to get to the dashboard with the full
        # expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        signin_user(strategy.request)
        login_user(strategy.request)
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        # First we expect that we're in the unlinked state, and that there
        # really is no association in the backend.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=False)
        self.assert_social_auth_does_not_exist_for_user(request.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)

        # Fire off the auth pipeline to link.
        self.assert_redirect_to_dashboard_looks_correct(
            actions.do_complete(
                request.backend,
                social_views._do_login,  # pylint: disable=protected-access
                request.user,
                None,
                redirect_field_name=auth.REDIRECT_FIELD_NAME,
                request=request
            )
        )

        # Now we expect to be in the linked state, with a backend entry.
        self.assert_social_auth_exists_for_user(request.user, strategy)
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
Esempio n. 3
0
    def test_context_for_enterprise_learner(
            self, mock_get_auth_provider, mock_enterprise_customer_for_request
    ):
        dummy_enterprise_customer = {
            'uuid': 'real-ent-uuid',
            'name': 'Dummy Enterprise',
            'identity_provider': 'saml-ubc'
        }
        mock_enterprise_customer_for_request.return_value = dummy_enterprise_customer
        self.request.site = SiteFactory.create()
        mock_get_auth_provider.return_value.sync_learner_profile_data = True
        context = account_settings_context(self.request)

        user_accounts_api_url = reverse("accounts_api", kwargs={'username': self.user.username})
        assert context['user_accounts_api_url'] == user_accounts_api_url

        user_preferences_api_url = reverse('preferences_api', kwargs={'username': self.user.username})
        assert context['user_preferences_api_url'] == user_preferences_api_url

        for attribute in self.FIELDS:
            assert attribute in context['fields']

        assert context['user_accounts_api_url'] == reverse('accounts_api', kwargs={'username': self.user.username})
        assert context['user_preferences_api_url'] ==\
               reverse('preferences_api', kwargs={'username': self.user.username})

        assert context['duplicate_provider'] == 'facebook'
        assert context['auth']['providers'][0]['name'] == 'Facebook'
        assert context['auth']['providers'][1]['name'] == 'Google'

        assert context['sync_learner_profile_data'] == mock_get_auth_provider.return_value.sync_learner_profile_data
        assert context['edx_support_url'] == settings.SUPPORT_SITE_LINK
        assert context['enterprise_name'] == dummy_enterprise_customer['name']
        assert context['enterprise_readonly_account_fields'] ==\
               {'fields': list(get_enterprise_readonly_account_fields(self.user))}
Esempio n. 4
0
    def test_context(self, mock_get_enterprise_customer_for_learner):
        self.request.site = SiteFactory.create()
        mock_get_enterprise_customer_for_learner.return_value = {}
        context = account_settings_context(self.request)

        user_accounts_api_url = reverse("accounts_api", kwargs={'username': self.user.username})
        self.assertEqual(context['user_accounts_api_url'], user_accounts_api_url)

        user_preferences_api_url = reverse('preferences_api', kwargs={'username': self.user.username})
        self.assertEqual(context['user_preferences_api_url'], user_preferences_api_url)

        for attribute in self.FIELDS:
            self.assertIn(attribute, context['fields'])

        self.assertEqual(
            context['user_accounts_api_url'], reverse("accounts_api", kwargs={'username': self.user.username})
        )
        self.assertEqual(
            context['user_preferences_api_url'], reverse('preferences_api', kwargs={'username': self.user.username})
        )

        self.assertEqual(context['duplicate_provider'], 'facebook')
        self.assertEqual(context['auth']['providers'][0]['name'], 'Facebook')
        self.assertEqual(context['auth']['providers'][1]['name'], 'Google')

        self.assertEqual(context['sync_learner_profile_data'], False)
        self.assertEqual(context['edx_support_url'], settings.SUPPORT_SITE_LINK)
        self.assertEqual(context['enterprise_name'], None)
        self.assertEqual(
            context['enterprise_readonly_account_fields'], {'fields': settings.ENTERPRISE_READONLY_ACCOUNT_FIELDS}
        )
Esempio n. 5
0
    def test_already_associated_exception_populates_dashboard_with_error(self):
        # Instrument the pipeline with an exception. We test that the
        # exception is raised correctly separately, so it's ok that we're
        # raising it artificially here. This makes the linked=True artificial
        # in the final assert because in practice the account would be
        # unlinked, but getting that behavior is cumbersome here and already
        # covered in other tests. Using linked=True does, however, let us test
        # that the duplicate error has no effect on the state of the controls.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        self.client.get('/login')
        self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            signin_user(strategy.request)
            login_user(strategy.request)
            actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                                user=user, request=request)

        # Monkey-patch storage for messaging; pylint: disable=protected-access
        request._messages = fallback.FallbackStorage(request)
        middleware.ExceptionMiddleware().process_exception(
            request,
            exceptions.AuthAlreadyAssociated(self.provider.backend_name, 'account is already in use.'))

        self.assert_account_settings_context_looks_correct(
            account_settings_context(request), duplicate=True, linked=True)
Esempio n. 6
0
    def test_already_associated_exception_populates_dashboard_with_error(self):
        # Instrument the pipeline with an exception. We test that the
        # exception is raised correctly separately, so it's ok that we're
        # raising it artificially here. This makes the linked=True artificial
        # in the final assert because in practice the account would be
        # unlinked, but getting that behavior is cumbersome here and already
        # covered in other tests. Using linked=True does, however, let us test
        # that the duplicate error has no effect on the state of the controls.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        self.client.get('/login')
        self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            signin_user(strategy.request)
            login_user(strategy.request)
            actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                                user=user, request=request)

        # Monkey-patch storage for messaging; pylint: disable=protected-access
        request._messages = fallback.FallbackStorage(request)
        middleware.ExceptionMiddleware().process_exception(
            request,
            exceptions.AuthAlreadyAssociated(self.provider.backend_name, 'account is already in use.'))

        self.assert_account_settings_context_looks_correct(
            account_settings_context(request), duplicate=True, linked=True)
Esempio n. 7
0
    def test_full_pipeline_succeeds_for_unlinking_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        # We're already logged in, so simulate that the cookie is set correctly
        self.set_logged_in_cookies(request)

        # Instrument the pipeline to get to the dashboard with the full
        # expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            signin_user(strategy.request)
            login_user(strategy.request)
            actions.do_complete(request.backend, social_views._do_login, user=user,  # pylint: disable=protected-access
                                request=request)

        # First we expect that we're in the linked state, with a backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
        self.assert_social_auth_exists_for_user(request.user, strategy)

        # Fire off the disconnect pipeline to unlink.
        self.assert_redirect_to_dashboard_looks_correct(
            actions.do_disconnect(
                request.backend,
                request.user,
                None,
                redirect_field_name=auth.REDIRECT_FIELD_NAME
            )
        )

        # Now we expect to be in the unlinked state, with no backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=False)
        self.assert_social_auth_does_not_exist_for_user(user, strategy)
Esempio n. 8
0
    def test_full_pipeline_succeeds_for_unlinking_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        # We're already logged in, so simulate that the cookie is set correctly
        self.set_logged_in_cookies(request)

        # Instrument the pipeline to get to the dashboard with the full
        # expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            signin_user(strategy.request)
            login_user(strategy.request)
            actions.do_complete(request.backend, social_views._do_login, user=user,  # pylint: disable=protected-access
                                request=request)

        # First we expect that we're in the linked state, with a backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
        self.assert_social_auth_exists_for_user(request.user, strategy)

        # Fire off the disconnect pipeline to unlink.
        self.assert_redirect_after_pipeline_completes(
            actions.do_disconnect(
                request.backend,
                request.user,
                None,
                redirect_field_name=auth.REDIRECT_FIELD_NAME
            )
        )

        # Now we expect to be in the unlinked state, with no backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=False)
        self.assert_social_auth_does_not_exist_for_user(user, strategy)
    def test_context(self, mock_enterprise_customer_for_request):
        self.request.site = SiteFactory.create()
        UserPreferenceFactory(user=self.user, key='pref-lang', value='lt-lt')
        DarkLangConfig(released_languages='en',
                       changed_by=self.user,
                       enabled=True,
                       beta_languages='lt-lt',
                       enable_beta_languages=True).save()
        mock_enterprise_customer_for_request.return_value = {}

        with override_settings(LANGUAGES=[EN, LT_LT], LANGUAGE_CODE='en'):
            context = account_settings_context(self.request)

            user_accounts_api_url = reverse(
                "accounts_api", kwargs={'username': self.user.username})
            self.assertEqual(context['user_accounts_api_url'],
                             user_accounts_api_url)

            user_preferences_api_url = reverse(
                'preferences_api', kwargs={'username': self.user.username})
            self.assertEqual(context['user_preferences_api_url'],
                             user_preferences_api_url)

            for attribute in self.FIELDS:
                self.assertIn(attribute, context['fields'])

            self.assertEqual(
                context['user_accounts_api_url'],
                reverse("accounts_api",
                        kwargs={'username': self.user.username}))
            self.assertEqual(
                context['user_preferences_api_url'],
                reverse('preferences_api',
                        kwargs={'username': self.user.username}))

            self.assertEqual(context['duplicate_provider'], 'facebook')
            self.assertEqual(context['auth']['providers'][0]['name'],
                             'Facebook')
            self.assertEqual(context['auth']['providers'][1]['name'], 'Google')

            self.assertEqual(context['sync_learner_profile_data'], False)
            self.assertEqual(context['edx_support_url'],
                             settings.SUPPORT_SITE_LINK)
            self.assertEqual(context['enterprise_name'], None)
            self.assertEqual(context['enterprise_readonly_account_fields'], {
                'fields':
                list(get_enterprise_readonly_account_fields(self.user))
            })
            expected_beta_language = {
                'code': 'lt-lt',
                'name': settings.LANGUAGE_DICT.get('lt-lt')
            }
            self.assertEqual(context['beta_language'], expected_beta_language)
Esempio n. 10
0
    def test_full_pipeline_succeeds_for_signing_in_to_existing_active_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        pipeline.analytics.track = mock.MagicMock()
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)
        self.assertTrue(user.is_active)

        # Begin! Ensure that the login form contains expected controls before
        # the user starts the pipeline.
        self.assert_login_response_before_pipeline_looks_correct(self.client.get('/login'))

        # 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>
        # to resume the pipeline.
        # pylint: disable=protected-access
        self.assert_redirect_to_login_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 login form and posts it via JS.
        with self._patch_edxmako_current_request(strategy.request):
            self.assert_login_response_in_pipeline_looks_correct(signin_user(strategy.request))

        # Next, we invoke the view that handles the POST, and expect it
        # redirects to /auth/complete. In the browser ajax handlers will
        # redirect the user to the dashboard; we invoke it manually here.
        self.assert_json_success_response_looks_correct(login_user(strategy.request))

        # 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_to_dashboard_looks_correct(
            actions.do_complete(request.backend, social_views._do_login, user=user, request=request))
        self.assert_account_settings_context_looks_correct(account_settings_context(request))
Esempio n. 11
0
    def test_full_pipeline_succeeds_for_signing_in_to_existing_active_account(self):
        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
        pipeline.analytics.track = mock.MagicMock()
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)
        self.assertTrue(user.is_active)

        # Begin! Ensure that the login form contains expected controls before
        # the user starts the pipeline.
        self.assert_login_response_before_pipeline_looks_correct(self.client.get('/login'))

        # 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>
        # to resume the pipeline.
        # pylint: disable=protected-access
        self.assert_redirect_to_login_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 login form and posts it via JS.
        with self._patch_edxmako_current_request(strategy.request):
            self.assert_login_response_in_pipeline_looks_correct(signin_user(strategy.request))

        # Next, we invoke the view that handles the POST, and expect it
        # redirects to /auth/complete. In the browser ajax handlers will
        # redirect the user to the dashboard; we invoke it manually here.
        self.assert_json_success_response_looks_correct(login_user(strategy.request))

        # 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_to_dashboard_looks_correct(
            actions.do_complete(request.backend, social_views._do_login, user=user, request=request))
        self.assert_account_settings_context_looks_correct(account_settings_context(request))
Esempio n. 12
0
    def test_context_for_enterprise_learner(
            self, mock_get_auth_provider,
            mock_get_enterprise_customer_for_learner):
        dummy_enterprise_customer = {
            'uuid': 'real-ent-uuid',
            'name': 'Dummy Enterprise',
            'identity_provider': 'saml-ubc'
        }
        mock_get_enterprise_customer_for_learner.return_value = dummy_enterprise_customer
        self.request.site = SiteFactory.create()
        mock_get_auth_provider.return_value.sync_learner_profile_data = True
        context = account_settings_context(self.request)

        user_accounts_api_url = reverse(
            "accounts_api", kwargs={'username': self.user.username})
        self.assertEqual(context['user_accounts_api_url'],
                         user_accounts_api_url)

        user_preferences_api_url = reverse(
            'preferences_api', kwargs={'username': self.user.username})
        self.assertEqual(context['user_preferences_api_url'],
                         user_preferences_api_url)

        for attribute in self.FIELDS:
            self.assertIn(attribute, context['fields'])

        self.assertEqual(
            context['user_accounts_api_url'],
            reverse("accounts_api", kwargs={'username': self.user.username}))
        self.assertEqual(
            context['user_preferences_api_url'],
            reverse('preferences_api', kwargs={'username':
                                               self.user.username}))

        self.assertEqual(context['duplicate_provider'], 'facebook')
        self.assertEqual(context['auth']['providers'][0]['name'], 'Facebook')
        self.assertEqual(context['auth']['providers'][1]['name'], 'Google')

        self.assertEqual(
            context['sync_learner_profile_data'],
            mock_get_auth_provider.return_value.sync_learner_profile_data)
        self.assertEqual(context['edx_support_url'],
                         settings.SUPPORT_SITE_LINK)
        self.assertEqual(context['enterprise_name'],
                         dummy_enterprise_customer['name'])
        self.assertEqual(
            context['enterprise_readonly_account_fields'],
            {'fields': settings.ENTERPRISE_READONLY_ACCOUNT_FIELDS})
Esempio n. 13
0
    def test_context(self, mock_get_enterprise_customer_for_learner):
        self.request.site = SiteFactory.create()
        UserPreferenceFactory(user=self.user, key='pref-lang', value='lt-lt')
        DarkLangConfig(
            released_languages='en',
            changed_by=self.user,
            enabled=True,
            beta_languages='lt-lt',
            enable_beta_languages=True
        ).save()
        mock_get_enterprise_customer_for_learner.return_value = {}

        with override_settings(LANGUAGES=[EN, LT_LT], LANGUAGE_CODE='en'):
            context = account_settings_context(self.request)

            user_accounts_api_url = reverse("accounts_api", kwargs={'username': self.user.username})
            self.assertEqual(context['user_accounts_api_url'], user_accounts_api_url)

            user_preferences_api_url = reverse('preferences_api', kwargs={'username': self.user.username})
            self.assertEqual(context['user_preferences_api_url'], user_preferences_api_url)

            for attribute in self.FIELDS:
                self.assertIn(attribute, context['fields'])

            self.assertEqual(
                context['user_accounts_api_url'], reverse("accounts_api", kwargs={'username': self.user.username})
            )
            self.assertEqual(
                context['user_preferences_api_url'], reverse('preferences_api', kwargs={'username': self.user.username})
            )

            self.assertEqual(context['duplicate_provider'], 'facebook')
            self.assertEqual(context['auth']['providers'][0]['name'], 'Facebook')
            self.assertEqual(context['auth']['providers'][1]['name'], 'Google')

            self.assertEqual(context['sync_learner_profile_data'], False)
            self.assertEqual(context['edx_support_url'], settings.SUPPORT_SITE_LINK)
            self.assertEqual(context['enterprise_name'], None)
            self.assertEqual(
                context['enterprise_readonly_account_fields'], {'fields': settings.ENTERPRISE_READONLY_ACCOUNT_FIELDS}
            )
            expected_beta_language = {'code': 'lt-lt', 'name': settings.LANGUAGE_DICT.get('lt-lt')}
            self.assertEqual(context['beta_language'], expected_beta_language)
Esempio n. 14
0
    def get_context_data(self, **kwargs):
        """
        Add the context regarding social auth providers to the view
        """
        context = super(AccountView, self).get_context_data(**kwargs)

        user = self.request.user
        providers_context_data = self.get_social_oauth_providers_data()
        profile_image = get_profile_image_urls_for_user(user).get('full')

        context.update({
            'password_change_request':
            reverse('password_reset'),
            'account_delete_url':
            reverse('deactivate_logout'),
            'profile_image':
            profile_image,
            'is_user_under_age':
            user.profile.year_of_birth
            and user.profile.age < settings.PARENTAL_CONSENT_AGE_LIMIT,
            **providers_context_data,
            **account_settings_context(self.request)
        })
        return context
Esempio n. 15
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(
                register_user(strategy.request),
                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))
        # 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_to_dashboard_looks_correct(
            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)
Esempio n. 16
0
    def test_full_pipeline_succeeds_for_unlinking_testshib_account(
        self,
        mock_get_enterprise_customer_for_learner_settings_view,
        mock_get_enterprise_customer_for_learner,
        mock_enterprise_customer_for_request,
    ):

        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        self.provider = self._configure_testshib_provider()
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN,
            redirect_uri='social:complete')
        request.backend.auth_complete = MagicMock(
            return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        request.user = user

        # We're already logged in, so simulate that the cookie is set correctly
        self.set_logged_in_cookies(request)

        # linking a learner with enterprise customer.
        enterprise_customer = EnterpriseCustomerFactory()
        assert EnterpriseCustomerUser.objects.count(
        ) == 0, "Precondition check: no link records should exist"
        EnterpriseCustomerUser.objects.link_user(enterprise_customer,
                                                 user.email)
        self.assertTrue(
            EnterpriseCustomerUser.objects.filter(
                enterprise_customer=enterprise_customer,
                user_id=user.id).count() == 1)
        EnterpriseCustomerIdentityProvider.objects.get_or_create(
            enterprise_customer=enterprise_customer,
            provider_id=self.provider.provider_id)

        enterprise_customer_data = {
            'uuid': enterprise_customer.uuid,
            'name': enterprise_customer.name,
            'identity_provider': 'saml-default',
        }
        mock_enterprise_customer_for_request.return_value = enterprise_customer_data
        mock_get_enterprise_customer_for_learner.return_value = enterprise_customer_data
        mock_get_enterprise_customer_for_learner_settings_view.return_value = enterprise_customer_data

        # Instrument the pipeline to get to the dashboard with the full expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id,
                                   pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(
            request.backend,
            social_views._do_login,  # pylint: disable=protected-access
            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            login_user(strategy.request)
            actions.do_complete(
                request.backend,
                social_views._do_login,
                user=user,  # pylint: disable=protected-access
                request=request)

        # First we expect that we're in the linked state, with a backend entry.
        self.assert_account_settings_context_looks_correct(
            account_settings_context(request), linked=True)
        self.assert_social_auth_exists_for_user(request.user, strategy)

        FEATURES_WITH_ENTERPRISE_ENABLED = settings.FEATURES.copy()
        FEATURES_WITH_ENTERPRISE_ENABLED[
            'ENABLE_ENTERPRISE_INTEGRATION'] = True
        with patch.dict("django.conf.settings.FEATURES",
                        FEATURES_WITH_ENTERPRISE_ENABLED):
            # Fire off the disconnect pipeline without the user information.
            actions.do_disconnect(request.backend,
                                  None,
                                  None,
                                  redirect_field_name=auth.REDIRECT_FIELD_NAME,
                                  request=request)
            self.assertNotEqual(
                EnterpriseCustomerUser.objects.filter(
                    enterprise_customer=enterprise_customer,
                    user_id=user.id).count(), 0)

            # Fire off the disconnect pipeline to unlink.
            self.assert_redirect_after_pipeline_completes(
                actions.do_disconnect(
                    request.backend,
                    user,
                    None,
                    redirect_field_name=auth.REDIRECT_FIELD_NAME,
                    request=request))
            # Now we expect to be in the unlinked state, with no backend entry.
            self.assert_account_settings_context_looks_correct(
                account_settings_context(request), linked=False)
            self.assert_social_auth_does_not_exist_for_user(user, strategy)
            self.assertEqual(
                EnterpriseCustomerUser.objects.filter(
                    enterprise_customer=enterprise_customer,
                    user_id=user.id).count(), 0)
Esempio n. 17
0
    def test_full_pipeline_succeeds_for_unlinking_testshib_account(self):

        # First, create, the request and strategy that store pipeline state,
        # configure the backend, and mock out wire traffic.
        self.provider = self._configure_testshib_provider()
        request, strategy = self.get_request_and_strategy(
            auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
        request.backend.auth_complete = MagicMock(return_value=self.fake_auth_complete(strategy))
        user = self.create_user_models_for_existing_account(
            strategy, '*****@*****.**', 'password', self.get_username())
        self.assert_social_auth_exists_for_user(user, strategy)

        request.user = user

        # We're already logged in, so simulate that the cookie is set correctly
        self.set_logged_in_cookies(request)

        # linking a learner with enterprise customer.
        enterprise_customer = EnterpriseCustomerFactory()
        assert EnterpriseCustomerUser.objects.count() == 0, "Precondition check: no link records should exist"
        EnterpriseCustomerUser.objects.link_user(enterprise_customer, user.email)
        self.assertTrue(
            EnterpriseCustomerUser.objects.filter(enterprise_customer=enterprise_customer, user_id=user.id).count() == 1
        )
        EnterpriseCustomerIdentityProvider.objects.get_or_create(enterprise_customer=enterprise_customer,
                                                                 provider_id=self.provider.provider_id)

        # Instrument the pipeline to get to the dashboard with the full expected state.
        self.client.get(
            pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN))
        actions.do_complete(request.backend, social_views._do_login,  # pylint: disable=protected-access
                            request=request)

        with self._patch_edxmako_current_request(strategy.request):
            signin_user(strategy.request)
            login_user(strategy.request)
            actions.do_complete(request.backend, social_views._do_login, user=user,  # pylint: disable=protected-access
                                request=request)

        # First we expect that we're in the linked state, with a backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
        self.assert_social_auth_exists_for_user(request.user, strategy)

        # Fire off the disconnect pipeline without the user information.
        actions.do_disconnect(
            request.backend,
            None,
            None,
            redirect_field_name=auth.REDIRECT_FIELD_NAME,
            request=request
        )
        self.assertFalse(
            EnterpriseCustomerUser.objects.filter(enterprise_customer=enterprise_customer, user_id=user.id).count() == 0
        )

        # Fire off the disconnect pipeline to unlink.
        self.assert_redirect_to_dashboard_looks_correct(
            actions.do_disconnect(
                request.backend,
                user,
                None,
                redirect_field_name=auth.REDIRECT_FIELD_NAME,
                request=request
            )
        )
        # Now we expect to be in the unlinked state, with no backend entry.
        self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=False)
        self.assert_social_auth_does_not_exist_for_user(user, strategy)
        self.assertTrue(
            EnterpriseCustomerUser.objects.filter(enterprise_customer=enterprise_customer, user_id=user.id).count() == 0
        )
Esempio n. 18
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(
                register_user(strategy.request),
                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))
        # 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)