blob: 166f6978546a1e78ee9467b21ff1ec7e47309a6b [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <set>
#include <utility>
#include "base/notreached.h"
#include "chrome/browser/enterprise/connectors/connectors_manager.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/connectors/analysis/content_analysis_features.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
#include "chrome/browser/enterprise/connectors/connectors_service.h"
#include "chrome/browser/enterprise/connectors/reporting/browser_crash_event_router.h"
#include "chrome/browser/enterprise/connectors/reporting/extension_install_event_router.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/test/browser_task_environment.h"
#include "storage/browser/file_system/file_system_url.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/enterprise/connectors/analysis/source_destination_test_util.h"
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h" // nogncheck
#endif
namespace enterprise_connectors {
namespace {
constexpr AnalysisConnector kAllAnalysisConnectors[] = {
AnalysisConnector::FILE_DOWNLOADED, AnalysisConnector::FILE_ATTACHED,
AnalysisConnector::BULK_DATA_ENTRY, AnalysisConnector::PRINT};
constexpr ReportingConnector kAllReportingConnectors[] = {
ReportingConnector::SECURITY_EVENT};
constexpr char kEmptySettingsPref[] = "[]";
constexpr char kNormalCloudAnalysisSettingsPref[] = R"([
{
"service_provider": "google",
"enable": [
{"url_list": ["*"], "tags": ["dlp", "malware"]},
],
"disable": [
{"url_list": ["no.dlp.com", "no.dlp.or.malware.ca"], "tags": ["dlp"]},
{"url_list": ["no.malware.com", "no.dlp.or.malware.ca"],
"tags": ["malware"]},
],
"block_until_verdict": 1,
"block_password_protected": true,
"block_large_files": true,
"block_unsupported_file_types": true,
},
])";
constexpr char kNormalLocalAnalysisSettingsPref[] = R"([
{
"service_provider": "local_user_agent",
"enable": [
{"url_list": ["*"], "tags": ["dlp"]},
],
"disable": [
{"url_list": ["no.dlp.com", "no.dlp.or.malware.ca"], "tags": ["dlp"]},
],
"block_until_verdict": 1,
"block_password_protected": true,
"block_large_files": true,
"block_unsupported_file_types": true,
},
])";
constexpr char kNormalReportingSettingsPref[] = R"([
{
"service_provider": "google"
}
])";
constexpr char kDlpAndMalwareUrl[] = "https://foo.com";
constexpr char kOnlyDlpUrl[] = "https://no.malware.com";
constexpr char kOnlyMalwareUrl[] = "https://no.dlp.com";
constexpr char kNoTagsUrl[] = "https://no.dlp.or.malware.ca";
} // namespace
class ConnectorsManagerTest : public testing::Test {
public:
ConnectorsManagerTest()
: profile_manager_(TestingBrowserProcess::GetGlobal()) {
EXPECT_TRUE(profile_manager_.SetUp());
profile_ = profile_manager_.CreateTestingProfile("test-user");
}
PrefService* pref_service() { return profile_->GetPrefs(); }
void ValidateSettings(const AnalysisSettings& settings) {
ASSERT_EQ(settings.block_until_verdict, expected_block_until_verdict_);
ASSERT_EQ(settings.block_password_protected_files,
expected_block_password_protected_files_);
ASSERT_EQ(settings.block_large_files, expected_block_large_files_);
ASSERT_EQ(settings.block_unsupported_file_types,
expected_block_unsupported_file_types_);
for (const auto& expected_tag : expected_tags_) {
const std::string& tag = expected_tag.first;
ASSERT_TRUE(settings.tags.count(tag));
ASSERT_EQ(settings.tags.at(tag).requires_justification,
expected_tag.second.requires_justification);
ASSERT_EQ(settings.tags.at(tag).custom_message.message,
expected_tag.second.custom_message.message);
ASSERT_EQ(settings.tags.at(tag).custom_message.learn_more_url,
expected_tag.second.custom_message.learn_more_url);
}
}
void ValidateSettings(const ReportingSettings& settings) {
// For now, the URL is the same for both legacy and new policies, so
// checking the specific URL here. When service providers become
// configurable this will change.
ASSERT_EQ(GURL("https://chromereporting-pa.googleapis.com/v1/events"),
settings.reporting_url);
}
class ScopedConnectorPref {
public:
ScopedConnectorPref(PrefService* pref_service,
const char* pref,
const char* pref_value)
: pref_service_(pref_service), pref_(pref) {
auto maybe_pref_value =
base::JSONReader::Read(pref_value, base::JSON_ALLOW_TRAILING_COMMAS);
EXPECT_TRUE(maybe_pref_value.has_value());
if (maybe_pref_value.has_value()) {
pref_service_->Set(pref, maybe_pref_value.value());
}
}
void UpdateScopedConnectorPref(const char* pref_value) {
auto maybe_pref_value =
base::JSONReader::Read(pref_value, base::JSON_ALLOW_TRAILING_COMMAS);
EXPECT_TRUE(maybe_pref_value.has_value());
ASSERT_NE(pref_service_, nullptr);
ASSERT_NE(pref_, nullptr);
pref_service_->Set(pref_, maybe_pref_value.value());
}
~ScopedConnectorPref() { pref_service_->ClearPref(pref_); }
private:
raw_ptr<PrefService> pref_service_;
const char* pref_;
};
protected:
content::BrowserTaskEnvironment task_environment_;
base::test::ScopedFeatureList scoped_feature_list_;
TestingProfileManager profile_manager_;
raw_ptr<TestingProfile> profile_;
// Set to the default value of their legacy policy.
std::map<std::string, TagSettings> expected_tags_ = {};
BlockUntilVerdict expected_block_until_verdict_ = BlockUntilVerdict::kNoBlock;
bool expected_block_password_protected_files_ = false;
bool expected_block_large_files_ = false;
bool expected_block_unsupported_file_types_ = false;
std::set<std::string> expected_mime_types_;
};
// Platform policies should only act as a kill switch.
class ConnectorsManagerLocalAnalysisPolicyTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<
std::tuple<AnalysisConnector, bool, bool>> {
protected:
AnalysisConnector connector() const { return std::get<0>(GetParam()); }
bool enable_feature() const { return std::get<1>(GetParam()); }
bool set_policy() const { return std::get<2>(GetParam()); }
};
TEST_P(ConnectorsManagerLocalAnalysisPolicyTest, Test) {
if (enable_feature()) {
scoped_feature_list_.InitWithFeatures({kLocalContentAnalysisEnabled}, {});
} else {
scoped_feature_list_.InitWithFeatures({}, {kLocalContentAnalysisEnabled});
}
std::unique_ptr<ScopedConnectorPref> scoped_pref =
set_policy() ? std::make_unique<ScopedConnectorPref>(
pref_service(), ConnectorPref(connector()),
kNormalLocalAnalysisSettingsPref)
: nullptr;
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
EXPECT_EQ(enable_feature() && set_policy(),
manager.IsConnectorEnabled(connector()));
}
INSTANTIATE_TEST_SUITE_P(
ConnectorsManagerLocalAnalysisPolicyTest,
ConnectorsManagerLocalAnalysisPolicyTest,
testing::Combine(testing::ValuesIn(kAllAnalysisConnectors),
testing::Bool(),
testing::Bool()));
class ConnectorsManagerConnectorPoliciesTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<
std::tuple<AnalysisConnector, const char*, const char*>> {
public:
ConnectorsManagerConnectorPoliciesTest() = default;
AnalysisConnector connector() const { return std::get<0>(GetParam()); }
const char* url() const { return std::get<1>(GetParam()); }
const char* pref_value() const { return std::get<2>(GetParam()); }
const char* pref() const { return ConnectorPref(connector()); }
void SetUpExpectedAnalysisSettings(const char* pref) {
auto expected_settings = ExpectedAnalysisSettings(pref, url());
expect_settings_ = expected_settings.has_value();
if (expected_settings.has_value()) {
expected_tags_ = expected_settings.value().tags;
expected_block_until_verdict_ =
expected_settings.value().block_until_verdict;
expected_block_password_protected_files_ =
expected_settings.value().block_password_protected_files;
expected_block_unsupported_file_types_ =
expected_settings.value().block_unsupported_file_types;
expected_block_large_files_ = expected_settings.value().block_large_files;
}
}
protected:
absl::optional<AnalysisSettings> ExpectedAnalysisSettings(const char* pref,
const char* url) {
if (pref == kEmptySettingsPref || url == kNoTagsUrl)
return absl::nullopt;
AnalysisSettings settings;
settings.block_until_verdict = BlockUntilVerdict::kBlock;
settings.block_password_protected_files = true;
settings.block_large_files = true;
settings.block_unsupported_file_types = true;
if (url == kDlpAndMalwareUrl)
settings.tags = {{"dlp", TagSettings()}, {"malware", TagSettings()}};
else if (url == kOnlyDlpUrl)
settings.tags = {{"dlp", TagSettings()}};
else if (url == kOnlyMalwareUrl)
settings.tags = {{"malware", TagSettings()}};
// The "local_test" service provider doesn't support the "malware" tag, so
// remove it from expectations.
if (pref == kNormalLocalAnalysisSettingsPref)
settings.tags.erase("malware");
if (settings.tags.empty())
return absl::nullopt;
return settings;
}
bool expect_settings_;
};
TEST_P(ConnectorsManagerConnectorPoliciesTest, NormalPref) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
ScopedConnectorPref scoped_pref(pref_service(), pref(), pref_value());
SetUpExpectedAnalysisSettings(pref_value());
// Verify that the expected settings are returned normally.
auto settings_from_manager =
manager.GetAnalysisSettings(GURL(url()), connector());
ASSERT_EQ(expect_settings_, settings_from_manager.has_value());
if (settings_from_manager.has_value())
ValidateSettings(settings_from_manager.value());
// Verify that the expected settings are also returned by the cached settings.
const auto& cached_settings =
manager.GetAnalysisConnectorsSettingsForTesting();
ASSERT_EQ(1u, cached_settings.size());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
auto settings_from_cache =
cached_settings.at(connector()).at(0).GetAnalysisSettings(GURL(url()));
ASSERT_EQ(expect_settings_, settings_from_cache.has_value());
if (settings_from_cache.has_value())
ValidateSettings(settings_from_cache.value());
}
TEST_P(ConnectorsManagerConnectorPoliciesTest, EmptyPref) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
// If the connector's settings list is empty, no analysis settings are ever
// returned.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
ScopedConnectorPref scoped_pref(pref_service(), pref(), kEmptySettingsPref);
ASSERT_FALSE(
manager.GetAnalysisSettings(GURL(url()), connector()).has_value());
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
INSTANTIATE_TEST_SUITE_P(
ConnectorsManagerConnectorPoliciesTest,
ConnectorsManagerConnectorPoliciesTest,
testing::Combine(testing::ValuesIn(kAllAnalysisConnectors),
testing::Values(kDlpAndMalwareUrl,
kOnlyDlpUrl,
kOnlyMalwareUrl,
kNoTagsUrl),
testing::Values(kNormalCloudAnalysisSettingsPref,
kNormalLocalAnalysisSettingsPref)));
#if BUILDFLAG(IS_CHROMEOS_ASH)
using VolumeInfo = SourceDestinationTestingHelper::VolumeInfo;
namespace {
constexpr char kNormalCloudSourceDestinationSettingsPref[] = R"([{
"service_provider": "google",
"enable": [
{
"source_destination_list": [
{
"sources": [{
"file_system_type": "ANY"
}],
"destinations": [{
"file_system_type": "ANY"
}]
}
],
"tags": ["dlp", "malware"]
},
],
"disable": [
{
"source_destination_list": [
{
"sources": [{
"file_system_type": "REMOVABLE"
}],
"destinations": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
]
}
],
"tags": ["dlp"]
},
{
"source_destination_list": [
{
"sources": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
],
"destinations": [{
"file_system_type": "REMOVABLE"
}]
}
],
"tags": ["malware"]},
{
"source_destination_list": [
{
"sources": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
],
"destinations": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
]
}
],
"tags": ["dlp", "malware"]
},
],
"block_until_verdict": 1,
"block_password_protected": true,
"block_large_files": true,
"block_unsupported_file_types": true,
"minimum_data_size": 123,
}])";
constexpr char kNormalLocalSourceDestinationSettingsPref[] = R"([{
"service_provider": "local_user_agent",
"enable": [
{
"source_destination_list": [
{
"sources": [{
"file_system_type": "ANY"
}],
"destinations": [{
"file_system_type": "ANY"
}]
}
],
"tags": ["dlp", "malware"]
},
],
"disable": [
{
"source_destination_list": [
{
"sources": [{
"file_system_type": "REMOVABLE"
}],
"destinations": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
]
}
],
"tags": ["dlp"]
},
{
"source_destination_list": [
{
"sources": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
],
"destinations": [{
"file_system_type": "REMOVABLE"
}]
}
],
"tags": ["malware"]},
{
"source_destination_list": [
{
"sources": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
],
"destinations": [
{"file_system_type": "MY_FILES"},
{"file_system_type": "GOOGLE_DRIVE"}
]
}
],
"tags": ["dlp", "malware"]
},
],
"block_until_verdict": 1,
"block_password_protected": true,
"block_large_files": true,
"block_unsupported_file_types": true,
"minimum_data_size": 123,
}])";
constexpr VolumeInfo kRemovableVolumeInfo{
file_manager::VOLUME_TYPE_REMOVABLE_DISK_PARTITION, absl::nullopt,
"REMOVABLE"};
constexpr VolumeInfo kProvidedVolumeInfo{file_manager::VOLUME_TYPE_PROVIDED,
absl::nullopt, "PROVIDED"};
constexpr VolumeInfo kMyFilesVolumeInfo{
file_manager::VOLUME_TYPE_DOWNLOADS_DIRECTORY, absl::nullopt, "MY_FILES"};
constexpr VolumeInfo kDriveVolumeInfo{file_manager::VOLUME_TYPE_GOOGLE_DRIVE,
absl::nullopt, "GOOGLE_DRIVE"};
constexpr std::initializer_list<VolumeInfo> kVolumeInfos{
kRemovableVolumeInfo, kProvidedVolumeInfo, kMyFilesVolumeInfo,
kDriveVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kDlpMalwareVolumePair1 = {
kRemovableVolumeInfo, kProvidedVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kDlpMalwareVolumePair2 = {
kProvidedVolumeInfo, kRemovableVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kNoDlpNoMalwareVolumePair1 = {
kMyFilesVolumeInfo, kDriveVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kNoDlpNoMalwareVolumePair2 = {
kDriveVolumeInfo, kMyFilesVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kNoDlpMalwareVolumePair1 = {
kRemovableVolumeInfo, kMyFilesVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kNoDlpMalwareVolumePair2 = {
kRemovableVolumeInfo, kDriveVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kDlpNoMalwareVolumePair1 = {
kMyFilesVolumeInfo, kRemovableVolumeInfo};
constexpr std::pair<VolumeInfo, VolumeInfo> kDlpNoMalwareVolumePair2 = {
kDriveVolumeInfo, kRemovableVolumeInfo};
using SourceDestinationTestingTuple =
std::tuple<AnalysisConnector,
const std::pair<VolumeInfo, VolumeInfo>*,
const char*>;
static auto testingTupleToString = [](const auto& info) {
// Can use info.param here to generate the test suffix
std::string name;
auto [connector, volume_info_pair, pref] = info.param;
name += volume_info_pair->first.fs_config_string;
name += "_";
name += volume_info_pair->second.fs_config_string;
if (pref == kNormalCloudSourceDestinationSettingsPref) {
name += "_cloud";
} else if (pref == kNormalLocalSourceDestinationSettingsPref) {
name += "_local";
} else {
name += "_unknown";
}
return name;
};
} // namespace
class ConnectorsManagerConnectorPoliciesSourceDestinationTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<SourceDestinationTestingTuple> {
public:
ConnectorsManagerConnectorPoliciesSourceDestinationTest() {
source_destination_testing_helper_ =
std::make_unique<SourceDestinationTestingHelper>(profile_,
kVolumeInfos);
}
~ConnectorsManagerConnectorPoliciesSourceDestinationTest() override {
// The testing profile has to be deleted before
// source_destination_testing_helper_ is destroyed.
profile_manager_.DeleteAllTestingProfiles();
}
AnalysisConnector connector() const { return std::get<0>(GetParam()); }
storage::FileSystemURL source_volume_url() const {
return source_destination_testing_helper_->GetTestFileSystemURLForVolume(
std::get<1>(GetParam())->first);
}
storage::FileSystemURL destination_volume_url() const {
return source_destination_testing_helper_->GetTestFileSystemURLForVolume(
std::get<1>(GetParam())->second);
}
const char* pref_value() const { return std::get<2>(GetParam()); }
const char* pref() const { return ConnectorPref(connector()); }
void SetUpExpectedAnalysisSettings(const char* pref) {
auto expected_settings =
ExpectedAnalysisSettings(pref, std::get<1>(GetParam()));
expect_settings_ = expected_settings.has_value();
if (expected_settings.has_value()) {
expected_tags_ = expected_settings.value().tags;
expected_block_until_verdict_ =
expected_settings.value().block_until_verdict;
expected_block_password_protected_files_ =
expected_settings.value().block_password_protected_files;
expected_block_unsupported_file_types_ =
expected_settings.value().block_unsupported_file_types;
expected_block_large_files_ = expected_settings.value().block_large_files;
}
}
protected:
absl::optional<AnalysisSettings> ExpectedAnalysisSettings(
const char* pref,
const std::pair<VolumeInfo, VolumeInfo>* volume_pair) {
if (pref == kEmptySettingsPref ||
volume_pair == &kNoDlpNoMalwareVolumePair1 ||
volume_pair == &kNoDlpNoMalwareVolumePair2)
return absl::nullopt;
AnalysisSettings settings;
settings.block_until_verdict = BlockUntilVerdict::kBlock;
settings.block_password_protected_files = true;
settings.block_large_files = true;
settings.block_unsupported_file_types = true;
if (volume_pair == &kDlpMalwareVolumePair1 ||
volume_pair == &kDlpMalwareVolumePair2) {
settings.tags = {{"dlp", TagSettings()}, {"malware", TagSettings()}};
} else if (volume_pair == &kDlpNoMalwareVolumePair1 ||
volume_pair == &kDlpNoMalwareVolumePair2) {
settings.tags = {{"dlp", TagSettings()}};
} else if (volume_pair == &kNoDlpMalwareVolumePair1 ||
volume_pair == &kNoDlpMalwareVolumePair2) {
settings.tags = {{"malware", TagSettings()}};
} else {
NOTREACHED();
}
// The "local_user_agent" service provider doesn't support the "malware"
// tag, so remove it from expectations.
if (pref == kNormalLocalSourceDestinationSettingsPref)
settings.tags.erase("malware");
if (settings.tags.empty())
return absl::nullopt;
return settings;
}
std::unique_ptr<SourceDestinationTestingHelper>
source_destination_testing_helper_;
bool expect_settings_;
};
TEST_P(ConnectorsManagerConnectorPoliciesSourceDestinationTest, NormalPref) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
ScopedConnectorPref scoped_pref(pref_service(), pref(), pref_value());
SetUpExpectedAnalysisSettings(pref_value());
// Verify that the expected settings are returned normally.
auto settings_from_manager = manager.GetAnalysisSettings(
profile_, source_volume_url(), destination_volume_url(), connector());
ASSERT_EQ(expect_settings_, settings_from_manager.has_value());
if (settings_from_manager.has_value())
ValidateSettings(settings_from_manager.value());
// Verify that the expected settings are also returned by the cached settings.
const auto& cached_settings =
manager.GetAnalysisConnectorsSettingsForTesting();
ASSERT_EQ(1u, cached_settings.size());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
auto settings_from_cache =
cached_settings.at(connector())
.at(0)
.GetAnalysisSettings(profile_, source_volume_url(),
destination_volume_url());
ASSERT_EQ(expect_settings_, settings_from_cache.has_value());
if (settings_from_cache.has_value())
ValidateSettings(settings_from_cache.value());
}
TEST_P(ConnectorsManagerConnectorPoliciesSourceDestinationTest, EmptyPref) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
// If the connector's settings list is empty, no analysis settings are ever
// returned.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
ScopedConnectorPref scoped_pref(pref_service(), pref(), kEmptySettingsPref);
ASSERT_FALSE(manager
.GetAnalysisSettings(profile_, source_volume_url(),
destination_volume_url(), connector())
.has_value());
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
INSTANTIATE_TEST_SUITE_P(
,
ConnectorsManagerConnectorPoliciesSourceDestinationTest,
testing::Combine(
testing::Values(AnalysisConnector::FILE_TRANSFER),
testing::Values(&kDlpMalwareVolumePair1,
&kDlpMalwareVolumePair2,
&kNoDlpNoMalwareVolumePair1,
&kNoDlpNoMalwareVolumePair2,
&kNoDlpMalwareVolumePair1,
&kNoDlpMalwareVolumePair2,
&kDlpNoMalwareVolumePair1,
&kDlpNoMalwareVolumePair2),
testing::Values(kNormalCloudSourceDestinationSettingsPref)),
testingTupleToString);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
class ConnectorsManagerAnalysisConnectorsTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<
std::tuple<AnalysisConnector, const char*>> {
public:
AnalysisConnector connector() const { return std::get<0>(GetParam()); }
const char* pref_value() const { return std::get<1>(GetParam()); }
const char* pref() const { return ConnectorPref(connector()); }
};
TEST_P(ConnectorsManagerAnalysisConnectorsTest, DynamicPolicies) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
// The cache is initially empty.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
// Once the pref is updated, the settings should be cached, and analysis
// settings can be obtained.
{
ScopedConnectorPref scoped_pref(pref_service(), pref(), pref_value());
const auto& cached_settings =
manager.GetAnalysisConnectorsSettingsForTesting();
ASSERT_FALSE(cached_settings.empty());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
auto settings = cached_settings.at(connector())
.at(0)
.GetAnalysisSettings(GURL(kDlpAndMalwareUrl));
ASSERT_TRUE(settings.has_value());
expected_block_until_verdict_ = BlockUntilVerdict::kBlock;
expected_block_password_protected_files_ = true;
expected_block_large_files_ = true;
expected_block_unsupported_file_types_ = true;
// The "local_test" service provider doesn't support the "malware" tag, so
// remove it from expectations.
if (pref_value() == kNormalCloudAnalysisSettingsPref)
expected_tags_ = {{"dlp", TagSettings()}, {"malware", TagSettings()}};
else
expected_tags_ = {{"dlp", TagSettings()}};
ValidateSettings(settings.value());
}
// The cache should be empty again after the pref is reset.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
TEST_P(ConnectorsManagerAnalysisConnectorsTest, NamesAndConfigs) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
ScopedConnectorPref scoped_pref(pref_service(), pref(), pref_value());
auto names = manager.GetAnalysisServiceProviderNames(connector());
ASSERT_EQ(1u, names.size());
auto configs = manager.GetAnalysisServiceConfigs(connector());
ASSERT_EQ(1u, configs.size());
if (names[0] == "google") {
EXPECT_TRUE(configs[0]->url);
EXPECT_FALSE(configs[0]->local_path);
} else if (names[0] == "local_user_agent") {
EXPECT_FALSE(configs[0]->url);
EXPECT_TRUE(configs[0]->local_path);
} else {
NOTREACHED() << "Unexpected service provider name";
}
}
INSTANTIATE_TEST_SUITE_P(
ConnectorsManagerAnalysisConnectorsTest,
ConnectorsManagerAnalysisConnectorsTest,
testing::Combine(testing::ValuesIn(kAllAnalysisConnectors),
testing::Values(kNormalCloudAnalysisSettingsPref,
kNormalLocalAnalysisSettingsPref)));
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ConnectorsManagerAnalysisConnectorsSourceDestinationTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<
std::tuple<AnalysisConnector, const char*>> {
public:
ConnectorsManagerAnalysisConnectorsSourceDestinationTest() {
source_destination_testing_helper_ =
std::make_unique<SourceDestinationTestingHelper>(profile_,
kVolumeInfos);
}
~ConnectorsManagerAnalysisConnectorsSourceDestinationTest() override {
// The testing profile has to be deleted before
// source_destination_testing_helper_ is destroyed.
profile_manager_.DeleteAllTestingProfiles();
}
storage::FileSystemURL source_volume_url() const {
return source_destination_testing_helper_->GetTestFileSystemURLForVolume(
kDlpMalwareVolumePair1.first);
}
storage::FileSystemURL destination_volume_url() const {
return source_destination_testing_helper_->GetTestFileSystemURLForVolume(
kDlpMalwareVolumePair1.second);
}
AnalysisConnector connector() const { return std::get<0>(GetParam()); }
const char* pref_value() const { return std::get<1>(GetParam()); }
const char* pref() const { return ConnectorPref(connector()); }
protected:
std::unique_ptr<SourceDestinationTestingHelper>
source_destination_testing_helper_;
};
TEST_P(ConnectorsManagerAnalysisConnectorsSourceDestinationTest,
DynamicPolicies) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
// The cache is initially empty.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
// Once the pref is updated, the settings should be cached, and analysis
// settings can be obtained.
{
ScopedConnectorPref scoped_pref(pref_service(), pref(), pref_value());
const auto& cached_settings =
manager.GetAnalysisConnectorsSettingsForTesting();
ASSERT_FALSE(cached_settings.empty());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
auto settings = cached_settings.at(connector())
.at(0)
.GetAnalysisSettings(profile_, source_volume_url(),
destination_volume_url());
ASSERT_TRUE(settings.has_value());
expected_block_until_verdict_ = BlockUntilVerdict::kBlock;
expected_block_password_protected_files_ = true;
expected_block_large_files_ = true;
expected_block_unsupported_file_types_ = true;
// The "local_test" service provider doesn't support the "malware" tag, so
// remove it from expectations.
if (pref_value() == kNormalCloudSourceDestinationSettingsPref)
expected_tags_ = {{"dlp", TagSettings()}, {"malware", TagSettings()}};
else
expected_tags_ = {{"dlp", TagSettings()}};
ValidateSettings(settings.value());
}
// The cache should be empty again after the pref is reset.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
INSTANTIATE_TEST_SUITE_P(
ConnectorsManagerAnalysisConnectorsSourceDestinationTest,
ConnectorsManagerAnalysisConnectorsSourceDestinationTest,
testing::Combine(
testing::Values(AnalysisConnector::FILE_TRANSFER),
testing::Values(kNormalCloudSourceDestinationSettingsPref,
kNormalLocalSourceDestinationSettingsPref)));
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
class ConnectorsManagerReportingTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<ReportingConnector> {
public:
ReportingConnector connector() const { return GetParam(); }
const char* pref() const { return ConnectorPref(connector()); }
};
TEST_P(ConnectorsManagerReportingTest, DynamicPolicies) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
// The cache is initially empty.
ASSERT_TRUE(manager.GetReportingConnectorsSettingsForTesting().empty());
// Once the pref is updated, the settings should be cached, and reporting
// settings can be obtained.
{
ScopedConnectorPref scoped_pref(pref_service(), pref(),
kNormalReportingSettingsPref);
const auto& cached_settings =
manager.GetReportingConnectorsSettingsForTesting();
ASSERT_FALSE(cached_settings.empty());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
auto settings =
cached_settings.at(connector()).at(0).GetReportingSettings();
ASSERT_TRUE(settings.has_value());
ValidateSettings(settings.value());
}
// The cache should be empty again after the pref is reset.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
INSTANTIATE_TEST_SUITE_P(ConnectorsManagerReportingTest,
ConnectorsManagerReportingTest,
testing::ValuesIn(kAllReportingConnectors));
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
class ConnectorsManagerLocalAnalysisConnectorTest
: public ConnectorsManagerTest,
public testing::WithParamInterface<AnalysisConnector> {
public:
AnalysisConnector connector() const { return GetParam(); }
const char* pref() const { return ConnectorPref(connector()); }
};
TEST_P(ConnectorsManagerLocalAnalysisConnectorTest, DynamicPolicies) {
ConnectorsManager manager(
std::make_unique<BrowserCrashEventRouter>(profile_),
std::make_unique<ExtensionInstallEventRouter>(profile_), pref_service(),
GetServiceProviderConfig());
FakeContentAnalysisSdkManager content_analysis_sdk_manager;
// The cache is initially empty.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
// Once the pref is updated, the settings should be cached, and analysis
// settings can be obtained.
// Select local service provider first.
{
ScopedConnectorPref scoped_pref(pref_service(), pref(),
kNormalLocalAnalysisSettingsPref);
// Force create connection with local agent.
content_analysis::sdk::Client::Config config{"local_user_agent"};
content_analysis_sdk_manager.GetClient(config);
const auto& cached_settings =
manager.GetAnalysisConnectorsSettingsForTesting();
ASSERT_FALSE(cached_settings.empty());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
// Connection should be established.
ASSERT_FALSE(content_analysis_sdk_manager.NoConnectionEstablished());
auto settings = cached_settings.at(connector())
.at(0)
.GetAnalysisSettings(GURL(kDlpAndMalwareUrl));
ASSERT_TRUE(settings.has_value());
expected_block_until_verdict_ = BlockUntilVerdict::kBlock;
expected_block_password_protected_files_ = true;
expected_block_large_files_ = true;
expected_block_unsupported_file_types_ = true;
// The "local_test" service provider doesn't support the "malware" tag, so
// remove it from expectations.
expected_tags_ = {{"dlp", TagSettings()}};
ValidateSettings(settings.value());
// Change to cloud service provider.
scoped_pref.UpdateScopedConnectorPref(kNormalCloudAnalysisSettingsPref);
// Connection should be deleted.
ASSERT_TRUE(content_analysis_sdk_manager.NoConnectionEstablished());
ASSERT_FALSE(cached_settings.empty());
ASSERT_EQ(1u, cached_settings.count(connector()));
ASSERT_EQ(1u, cached_settings.at(connector()).size());
// Connection should be deleted.
ASSERT_TRUE(content_analysis_sdk_manager.NoConnectionEstablished());
settings = cached_settings.at(connector())
.at(0)
.GetAnalysisSettings(GURL(kDlpAndMalwareUrl));
ASSERT_TRUE(settings.has_value());
expected_block_until_verdict_ = BlockUntilVerdict::kBlock;
expected_block_password_protected_files_ = true;
expected_block_large_files_ = true;
expected_block_unsupported_file_types_ = true;
expected_tags_ = {{"dlp", TagSettings()}, {"malware", TagSettings()}};
ValidateSettings(settings.value());
}
// The cache should be empty again after the pref is reset.
ASSERT_TRUE(manager.GetAnalysisConnectorsSettingsForTesting().empty());
}
INSTANTIATE_TEST_SUITE_P(ConnectorsManagerLocalAnalysisConnectorTest,
ConnectorsManagerLocalAnalysisConnectorTest,
testing::ValuesIn(kAllAnalysisConnectors));
#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
} // namespace enterprise_connectors