| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <memory> |
| #include <string> |
| |
| #include "chrome/browser/signin/identity_manager_factory.h" |
| #include "chrome/browser/sync/test/integration/encryption_helper.h" |
| #include "chrome/browser/sync/test/integration/sync_service_impl_harness.h" |
| #include "chrome/browser/sync/test/integration/sync_test.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/unified_consent/unified_consent_service_factory.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| #include "components/signin/public/identity_manager/identity_test_utils.h" |
| #include "components/sync/base/features.h" |
| #include "components/sync/service/sync_service.h" |
| #include "components/sync/service/sync_user_settings.h" |
| #include "components/sync/test/fake_server_nigori_helper.h" |
| #include "components/sync/test/nigori_test_utils.h" |
| #include "components/unified_consent/unified_consent_service.h" |
| #include "components/unified_consent/url_keyed_data_collection_consent_helper.h" |
| #include "content/public/test/browser_test.h" |
| |
| namespace unified_consent { |
| namespace { |
| |
| class UnifiedConsentSyncToSigninBrowserTest : public SyncTest { |
| public: |
| UnifiedConsentSyncToSigninBrowserTest() : SyncTest(SINGLE_CLIENT) { |
| features_.InitAndEnableFeature(syncer::kReplaceSyncPromosWithSignInPromos); |
| } |
| |
| UnifiedConsentSyncToSigninBrowserTest( |
| const UnifiedConsentSyncToSigninBrowserTest&) = delete; |
| UnifiedConsentSyncToSigninBrowserTest& operator=( |
| const UnifiedConsentSyncToSigninBrowserTest&) = delete; |
| |
| ~UnifiedConsentSyncToSigninBrowserTest() override = default; |
| |
| syncer::SyncServiceImpl* GetSyncService() { |
| return SyncTest::GetSyncService(0); |
| } |
| |
| UnifiedConsentService* GetUnifiedConsentService() { |
| return UnifiedConsentServiceFactory::GetForProfile(GetProfile(0)); |
| } |
| |
| bool IsAnonymizedDataCollectionEnabled() const { |
| auto helper = UrlKeyedDataCollectionConsentHelper:: |
| NewAnonymizedDataCollectionConsentHelper(GetProfile(0)->GetPrefs()); |
| return helper->IsEnabled(); |
| } |
| |
| void SignIn() { |
| signin::IdentityManager* identity_manager = |
| IdentityManagerFactory::GetForProfile(GetProfile(0)); |
| signin::MakePrimaryAccountAvailable(identity_manager, "user@gmail.com", |
| signin::ConsentLevel::kSignin); |
| } |
| |
| void SignOut() { |
| signin::IdentityManager* identity_manager = |
| IdentityManagerFactory::GetForProfile(GetProfile(0)); |
| signin::ClearPrimaryAccount(identity_manager); |
| } |
| |
| bool WaitForPassphraseRequired() { |
| return PassphraseRequiredChecker(GetSyncService()).Wait(); |
| } |
| |
| bool WaitForPassphraseAccepted() { |
| return PassphraseAcceptedChecker(GetSyncService()).Wait(); |
| } |
| |
| bool WaitForNigoriOnServer(syncer::PassphraseType expected_passphrase_type) { |
| return ServerPassphraseTypeChecker(expected_passphrase_type).Wait(); |
| } |
| |
| private: |
| base::test::ScopedFeatureList features_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| EnablesAnonymizedDataCollectionOnSignInWithHistory) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // During a previous signin, the user had opted in to history. |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| SignOut(); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // Now the user signs in again. |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| // AnonymizedDataCollection should have gotten enabled, because history is on |
| // (and there's no custom passphrase). |
| EXPECT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| EnablesAnonymizedDataCollectionOnHistoryOptIn) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| // AnonymizedDataCollection did NOT get enabled yet, because there is no |
| // history opt-in. |
| ASSERT_FALSE(GetSyncService()->GetUserSettings()->GetSelectedTypes().Has( |
| syncer ::UserSelectableType::kHistory)); |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // Opt in to history. |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| // AnonymizedDataCollection should've gotten enabled with the history opt-in. |
| EXPECT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| DisablesAnonymizedDataCollectionOnSignOut) { |
| ASSERT_TRUE(SetupClients()); |
| |
| // The user signs in and opts in to history. |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| // AnonymizedDataCollection got enabled with the history opt-in. |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The user signs out again. |
| SignOut(); |
| |
| // AnonymizedDataCollection should've gotten disabled again. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DoesNotEnableAnonymizedDataCollectionOnSignInWithHistoryAndCustomPassphrase) { |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // During a previous signin, the user had opted in to history. |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| SignOut(); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| |
| ASSERT_TRUE(WaitForPassphraseRequired()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->SetDecryptionPassphrase( |
| kKeyParams.password)); |
| ASSERT_TRUE(WaitForPassphraseAccepted()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->IsUsingExplicitPassphrase()); |
| |
| // AnonymizedDataCollection should NOT have gotten enabled, even though |
| // history is on, because there's a custom passphrase. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DoesNotEnableAnonymizedDataCollectionOnHistoryOptInWithCustomPassphrase) { |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| // AnonymizedDataCollection did NOT get enabled yet, because there is no |
| // history opt-in. |
| ASSERT_FALSE(GetSyncService()->GetUserSettings()->GetSelectedTypes().Has( |
| syncer ::UserSelectableType::kHistory)); |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // Opt in to history. |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| // AnonymizedDataCollection should NOT have gotten enabled, because there's |
| // a custom passphrase. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DisablesAnonymizedDataCollectionWhenCustomPassphraseSetOnThisDevice) { |
| ASSERT_TRUE(SetupClients()); |
| |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The user sets up a custom passphrase. |
| GetSyncService()->GetUserSettings()->SetEncryptionPassphrase("hunter2"); |
| ASSERT_TRUE(WaitForNigoriOnServer(syncer::PassphraseType::kCustomPassphrase)); |
| ASSERT_TRUE(WaitForPassphraseAccepted()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->IsUsingExplicitPassphrase()); |
| |
| // AnonymizedDataCollection should have gotten disabled. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DisablesAnonymizedDataCollectionWhenCustomPassphraseSetOnOtherDevice) { |
| ASSERT_TRUE(SetupClients()); |
| |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The user sets up a custom passphrase on a different device. |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| ASSERT_TRUE(WaitForPassphraseRequired()); |
| |
| // AnonymizedDataCollection should have gotten disabled. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| PRE_DisablesAnonymizedDataCollectionWhenCustomPassphraseSetOnOtherDeviceWhileNotRunning) { |
| ASSERT_TRUE(SetupClients()); |
| |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DisablesAnonymizedDataCollectionWhenCustomPassphraseSetOnOtherDeviceWhileNotRunning) { |
| // The user sets up a custom passphrase on a different device, while this |
| // instance of the browser isn't running. |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| // Now this browser starts up, and detects that there's a new passphrase. |
| ASSERT_TRUE(SetupClients()); |
| ASSERT_TRUE(WaitForPassphraseRequired()); |
| |
| // AnonymizedDataCollection should have gotten disabled. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| PRE_PreservesUsersOptOutAfterRestart) { |
| ASSERT_TRUE(SetupClients()); |
| |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| // AnonymizedDataCollection got enabled automatically, because history is on |
| // and there's no custom passphrase. |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The user explicitly chooses to disable AnonymizedDataCollection. |
| GetUnifiedConsentService()->SetUrlKeyedAnonymizedDataCollectionEnabled(false); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| PreservesUsersOptOutAfterRestart) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| |
| // AnonymizedDataCollection should still be disabled (even though history is |
| // on and there's no custom passphrase) since that was the user's choice. |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| PRE_PreservesUsersOptInAfterRestartWithCustomPassphrase) { |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| SignIn(); |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| ASSERT_TRUE(WaitForPassphraseRequired()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->SetDecryptionPassphrase( |
| kKeyParams.password)); |
| ASSERT_TRUE(WaitForPassphraseAccepted()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->IsUsingExplicitPassphrase()); |
| |
| // AnonymizedDataCollection did NOT get enabled, even though history is on, |
| // because there's a custom passphrase. |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The user explicitly chooses to enable AnonymizedDataCollection. |
| GetUnifiedConsentService()->SetUrlKeyedAnonymizedDataCollectionEnabled(true); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| PreservesUsersOptInAfterRestartWithCustomPassphrase) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->IsUsingExplicitPassphrase()); |
| |
| // AnonymizedDataCollection should still be enabled (even though there's a |
| // custom passphrase) since that was the user's choice. |
| EXPECT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(UnifiedConsentSyncToSigninBrowserTest, |
| EnablesAnonymizedDataCollectionOnSignInWhileOffline) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| |
| // Make the server return an error, so that the engine can't get initialized. |
| // This is similar to being offline at the moment of sign-in. |
| GetFakeServer()->SetHttpError(net::HTTP_INTERNAL_SERVER_ERROR); |
| |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| |
| base::RunLoop().RunUntilIdle(); |
| ASSERT_EQ(syncer::SyncService::TransportState::INITIALIZING, |
| GetSyncService()->GetTransportState()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| ASSERT_FALSE( |
| GetSyncService()->GetUserSettings()->GetPassphraseType().has_value()); |
| |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| // AnonymizedDataCollection should have been (optimistically) enabled, even |
| // though the passphrase type isn't known yet. |
| EXPECT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| PRE_DisablesAnonymizedDataCollectionAfterSignInWhileOfflineWithCustomPassphrase) { |
| const syncer::KeyParamsForTesting kKeyParams = |
| syncer::Pbkdf2PassphraseKeyParamsForTesting("hunter2"); |
| SetNigoriInFakeServer(BuildCustomPassphraseNigoriSpecifics(kKeyParams), |
| GetFakeServer()); |
| |
| ASSERT_TRUE(SetupClients()); |
| |
| // Make the server return an error, so that the engine can't get initialized. |
| // This is similar to being offline at the moment of sign-in. |
| GetFakeServer()->SetHttpError(net::HTTP_INTERNAL_SERVER_ERROR); |
| |
| SignIn(); |
| ASSERT_FALSE(GetSyncService()->IsSyncFeatureEnabled()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| |
| base::RunLoop().RunUntilIdle(); |
| ASSERT_EQ(syncer::SyncService::TransportState::INITIALIZING, |
| GetSyncService()->GetTransportState()); |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| ASSERT_FALSE( |
| GetSyncService()->GetUserSettings()->GetPassphraseType().has_value()); |
| |
| GetSyncService()->GetUserSettings()->SetSelectedType( |
| syncer::UserSelectableType::kHistory, true); |
| |
| // At this point, AnonymizedDataCollection is (optimistically) enabled, since |
| // though the passphrase type isn't known yet. |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // Before the engine finishes initialization, the user restarts the browser. |
| ASSERT_FALSE(GetSyncService()->IsEngineInitialized()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F( |
| UnifiedConsentSyncToSigninBrowserTest, |
| DisablesAnonymizedDataCollectionAfterSignInWhileOfflineWithCustomPassphrase) { |
| ASSERT_TRUE(SetupClients()); |
| |
| ASSERT_TRUE(IsAnonymizedDataCollectionEnabled()); |
| |
| // The previous server/connection error has been resolved, so the engine can |
| // initialize now. |
| ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); |
| ASSERT_TRUE(GetSyncService()->GetUserSettings()->IsUsingExplicitPassphrase()); |
| |
| // AnonymizedDataCollection should've been disabled, since there's a custom |
| // passphrase. (Note that it's not necessary for the user ot actually enter |
| // the passphrase.) |
| EXPECT_FALSE(IsAnonymizedDataCollectionEnabled()); |
| } |
| |
| } // namespace |
| } // namespace unified_consent |