blob: 0f2183a39467c47f1414e93ebabad2e79bd0d6f0 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/test/bind_test_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/browsing_data/browsing_data_api.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/scoped_account_consistency.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/signin_buildflags.h"
#include "content/public/browser/storage_partition.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "net/cookies/canonical_cookie.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "url/gurl.h"
using extension_function_test_utils::RunFunctionAndReturnSingleResult;
namespace {
class ExtensionBrowsingDataTest : public InProcessBrowserTest {};
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
const char kRemoveEverythingArguments[] =
R"([{"since": 1000}, {
"appcache": true, "cache": true, "cookies": true,
"downloads": true, "fileSystems": true, "formData": true,
"history": true, "indexedDB": true, "localStorage": true,
"serverBoundCertificates": true, "passwords": true,
"pluginData": true, "serviceWorkers": true, "cacheStorage": true,
"webSQL": true
}])";
// Sets the APISID Gaia cookie, which is monitored by the AccountReconcilor.
bool SetGaiaCookieForProfile(Profile* profile) {
GURL google_url = GaiaUrls::GetInstance()->google_url();
net::CanonicalCookie cookie("APISID", std::string(), "." + google_url.host(),
"/", base::Time(), base::Time(), base::Time(),
false, false, net::CookieSameSite::DEFAULT_MODE,
net::COOKIE_PRIORITY_DEFAULT);
bool success = false;
base::RunLoop loop;
base::OnceClosure loop_quit = loop.QuitClosure();
base::OnceCallback<void(bool)> callback =
base::BindLambdaForTesting([&success, &loop_quit](bool s) {
success = s;
std::move(loop_quit).Run();
});
network::mojom::CookieManager* cookie_manager =
content::BrowserContext::GetDefaultStoragePartition(profile)
->GetCookieManagerForBrowserProcess();
cookie_manager->SetCanonicalCookie(
cookie, true, true,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false));
loop.Run();
return success;
}
#endif
} // namespace
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
// Test that Sync is not paused when browsing data is cleared.
IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, Syncing) {
Profile* profile = browser()->profile();
// Set a Gaia cookie.
ASSERT_TRUE(SetGaiaCookieForProfile(profile));
// Set a Sync account and a secondary account.
const char kPrimaryAccountEmail[] = "primary@email.com";
const char kSecondaryAccountEmail[] = "secondary@email.com";
identity::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(profile);
AccountInfo primary_account_info = identity::MakePrimaryAccountAvailable(
identity_manager, kPrimaryAccountEmail);
AccountInfo secondary_account_info =
identity::MakeAccountAvailable(identity_manager, kSecondaryAccountEmail);
// Sync is running.
browser_sync::ProfileSyncService* sync_service =
ProfileSyncServiceFactory::GetForProfile(profile);
sync_service->GetUserSettings()->SetFirstSetupComplete();
ASSERT_EQ(sync_ui_util::SYNCED, sync_ui_util::GetStatus(profile));
// Clear browsing data.
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_EQ(NULL, RunFunctionAndReturnSingleResult(
function.get(), kRemoveEverythingArguments, browser()));
// Check that the Sync token was not revoked.
EXPECT_TRUE(identity_manager->HasAccountWithRefreshToken(
primary_account_info.account_id));
EXPECT_FALSE(
identity_manager->HasAccountWithRefreshTokenInPersistentErrorState(
primary_account_info.account_id));
// Check that the secondary token was revoked.
EXPECT_FALSE(identity_manager->HasAccountWithRefreshToken(
secondary_account_info.account_id));
}
// Test that Sync is paused when browsing data is cleared if Sync was in
// authentication error.
IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, SyncError) {
Profile* profile = browser()->profile();
// Set a Gaia cookie.
ASSERT_TRUE(SetGaiaCookieForProfile(profile));
// Set a Sync account with authentication error.
const char kAccountEmail[] = "account@email.com";
identity::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(profile);
AccountInfo account_info =
identity::MakePrimaryAccountAvailable(identity_manager, kAccountEmail);
identity::UpdatePersistentErrorOfRefreshTokenForAccount(
identity_manager, account_info.account_id,
GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_REJECTED_BY_SERVER));
// Sync is not running.
ASSERT_NE(sync_ui_util::SYNCED, sync_ui_util::GetStatus(profile));
// Clear browsing data.
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_EQ(NULL, RunFunctionAndReturnSingleResult(
function.get(), kRemoveEverythingArguments, browser()));
// Check that the account was not removed and Sync was paused.
EXPECT_TRUE(
identity_manager->HasAccountWithRefreshToken(account_info.account_id));
EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_REJECTED_BY_CLIENT,
identity_manager
->GetErrorStateOfRefreshTokenForAccount(account_info.account_id)
.GetInvalidGaiaCredentialsReason());
}
// Test that the tokens are revoked when browsing data is cleared when there is
// no primary account.
IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, NotSyncing) {
Profile* profile = browser()->profile();
// Set a Gaia cookie.
ASSERT_TRUE(SetGaiaCookieForProfile(profile));
// Set a non-Sync account.
const char kAccountEmail[] = "account@email.com";
auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
AccountInfo account_info =
identity::MakeAccountAvailable(identity_manager, kAccountEmail);
// Clear browsing data.
auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>();
EXPECT_EQ(NULL, RunFunctionAndReturnSingleResult(
function.get(), kRemoveEverythingArguments, browser()));
// Check that the account was removed.
EXPECT_FALSE(
identity_manager->HasAccountWithRefreshToken(account_info.account_id));
}
#endif