blob: f1af63bfa6f941b3d100f6ef804e5af4389efca3 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/net/cookie_encryption_provider_impl.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_launcher.h"
#include "net/cookies/canonical_cookie.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <optional>
#include <string>
#include <vector>
namespace {
enum TestConfiguration {
// Network Service is using Sync os_crypt API.
kOSCryptSync,
// Network Service is using Async API, i.e. cookie_encryption_provider is
// being supplied to the profile network context params. The DPAPI key
// provider is not being used in this test configuration.
kOSCryptAsync,
// The DPAPI key provider is being used to provide the key used for OSCrypt
// Async operation. This also means that OSCrypt Async is enabled by the test.
kOSCryptAsyncWithDPAPIProvider,
};
struct TestCase {
std::string name;
TestConfiguration before;
TestConfiguration after;
};
} // namespace
class CookieEncryptionProviderBrowserTest
: public InProcessBrowserTest,
public testing::WithParamInterface<TestCase> {
public:
void SetUp() override {
auto configuration =
content::IsPreTest() ? GetParam().before : GetParam().after;
std::vector<base::test::FeatureRef> enabled_features;
std::vector<base::test::FeatureRef> disabled_features;
switch (configuration) {
case kOSCryptSync:
disabled_features.push_back(
features::kUseOsCryptAsyncForCookieEncryption);
break;
case kOSCryptAsync:
enabled_features.push_back(
features::kUseOsCryptAsyncForCookieEncryption);
disabled_features.push_back(features::kEnableDPAPIEncryptionProvider);
break;
case kOSCryptAsyncWithDPAPIProvider:
enabled_features.push_back(
features::kUseOsCryptAsyncForCookieEncryption);
enabled_features.push_back(features::kEnableDPAPIEncryptionProvider);
maybe_histogram_tester_.emplace();
}
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
InProcessBrowserTest::SetUp();
}
void TearDown() override {
if (maybe_histogram_tester_) {
maybe_histogram_tester_->ExpectBucketCount("OSCrypt.DPAPIProvider.Status",
/*success*/ 0, 1);
}
InProcessBrowserTest::TearDown();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::optional<base::HistogramTester> maybe_histogram_tester_;
};
IN_PROC_BROWSER_TEST_P(CookieEncryptionProviderBrowserTest, PRE_CookieStorage) {
ASSERT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/setcookie.html")));
}
IN_PROC_BROWSER_TEST_P(CookieEncryptionProviderBrowserTest, CookieStorage) {
mojo::Remote<network::mojom::CookieManager> cookie_manager;
browser()
->profile()
->GetDefaultStoragePartition()
->GetNetworkContext()
->GetCookieManager(cookie_manager.BindNewPipeAndPassReceiver());
base::test::TestFuture<const net::CookieList&> future;
cookie_manager->GetAllCookies(future.GetCallback());
auto cookies = future.Take();
ASSERT_EQ(cookies.size(), 1u);
EXPECT_EQ(cookies[0].Name(), "name");
EXPECT_EQ(cookies[0].Value(), "Good");
}
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
CookieEncryptionProviderBrowserTest,
testing::ValuesIn<TestCase>({
{.name = "sync", .before = kOSCryptSync, .after = kOSCryptSync},
{.name = "async", .before = kOSCryptAsync, .after = kOSCryptAsync},
{.name = "asyncwithdpapi",
.before = kOSCryptAsyncWithDPAPIProvider,
.after = kOSCryptAsyncWithDPAPIProvider},
{.name = "migration_sync_to_async",
.before = kOSCryptSync,
.after = kOSCryptAsync},
{.name = "migration_sync_to_async_with_dpapi",
.before = kOSCryptSync,
.after = kOSCryptAsyncWithDPAPIProvider},
{.name = "migration_async_to_async_with_dpapi",
.before = kOSCryptAsync,
.after = kOSCryptAsyncWithDPAPIProvider},
{.name = "rollback_async_to_sync",
.before = kOSCryptAsync,
.after = kOSCryptSync},
{.name = "rollback_async_with_dpapi_to_async",
.before = kOSCryptAsyncWithDPAPIProvider,
.after = kOSCryptAsync},
{.name = "rollback_async_with_dpapi_to_sync",
.before = kOSCryptAsyncWithDPAPIProvider,
.after = kOSCryptSync},
}),
[](const auto& info) { return info.param.name; });