Commit c784ca1a authored by Nikita Podguzov's avatar Nikita Podguzov Committed by Chromium LUCI CQ

DLP: Refactor DlpRulesManager

* Move DlpRulesManagerFactory to separate file.
* Separate DlpRulesManager interface and implementation.
* Add missed method to MockDlpRulesManager.
* Remove DlpRulesManagerFactory::OverrideManagerForTesting() and replace
it with direct dependency DataTransferDlpController from
DlpRulesManager.
* Move policy constants to separate file.

TBR=achuith@chromium.org,gab@chromium.org

Bug: 1153146
Change-Id: Ic498947d9bcb41908c9433117a065e19d7afcbcf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2581930
Commit-Queue: Nikita Podguzov <nikitapodguzov@chromium.org>
Reviewed-by: default avatarAya Elsayed <ayaelattar@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836589}
parent 15a99f6d
......@@ -2247,8 +2247,12 @@ source_set("chromeos") {
"policy/dlp/dlp_content_tab_helper.h",
"policy/dlp/dlp_notification_helper.cc",
"policy/dlp/dlp_notification_helper.h",
"policy/dlp/dlp_rules_manager.cc",
"policy/dlp/dlp_policy_constants.h",
"policy/dlp/dlp_rules_manager.h",
"policy/dlp/dlp_rules_manager_factory.cc",
"policy/dlp/dlp_rules_manager_factory.h",
"policy/dlp/dlp_rules_manager_impl.cc",
"policy/dlp/dlp_rules_manager_impl.h",
"policy/dlp/dlp_window_observer.cc",
"policy/dlp/dlp_window_observer.h",
"policy/dm_token_storage.cc",
......@@ -3753,9 +3757,9 @@ source_set("unit_tests") {
"policy/dlp/data_transfer_dlp_controller_unittest.cc",
"policy/dlp/dlp_content_manager_unittest.cc",
"policy/dlp/dlp_content_tab_helper_unittest.cc",
"policy/dlp/dlp_rules_manager_impl_unittest.cc",
"policy/dlp/dlp_rules_manager_test_utils.cc",
"policy/dlp/dlp_rules_manager_test_utils.h",
"policy/dlp/dlp_rules_manager_unittest.cc",
"policy/dlp/mock_dlp_content_manager.cc",
"policy/dlp/mock_dlp_content_manager.h",
"policy/dm_token_storage_unittest.cc",
......
......@@ -30,7 +30,7 @@
#include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_factory.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/user_private_token_kpm_service_factory.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_engagement_metrics_service.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_factory.h"
#include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h"
......
......@@ -4,10 +4,9 @@
#include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
#include <vector>
#include "base/notreached.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "extensions/common/constants.h"
#include "ui/base/clipboard/clipboard.h"
......@@ -23,44 +22,12 @@ bool IsFilesApp(const GURL& url) {
url.has_host() && url.host() == extension_misc::kFilesManagerAppId;
}
DlpRulesManager::Level IsDstRestricted(const GURL& src, const GURL& dst) {
// Safe to not check for nullptr as DataTransferDlpController is owned by
// DlpRulesManager.
return DlpRulesManagerFactory::GetForPrimaryProfile()
->IsRestrictedDestination(src, dst,
DlpRulesManager::Restriction::kClipboard);
}
DlpRulesManager::Level IsCrostiniRestricted(const GURL& src) {
// Safe to not check for nullptr as DataTransferDlpController is owned by
// DlpRulesManager.
return DlpRulesManagerFactory::GetForPrimaryProfile()->IsRestrictedComponent(
src, DlpRulesManager::Component::kCrostini,
DlpRulesManager::Restriction::kClipboard);
}
DlpRulesManager::Level IsPluginVmRestricted(const GURL& src) {
// Safe to not check for nullptr as DataTransferDlpController is owned by
// DlpRulesManager.
return DlpRulesManagerFactory::GetForPrimaryProfile()->IsRestrictedComponent(
src, DlpRulesManager::Component::kPluginVm,
DlpRulesManager::Restriction::kClipboard);
}
DlpRulesManager::Level IsArcRestricted(const GURL& src) {
// Safe to not check for nullptr as DataTransferDlpController is owned by
// DlpRulesManager.
return DlpRulesManagerFactory::GetForPrimaryProfile()->IsRestrictedComponent(
src, DlpRulesManager::Component::kArc,
DlpRulesManager::Restriction::kClipboard);
}
} // namespace
// static
void DataTransferDlpController::Init() {
void DataTransferDlpController::Init(const DlpRulesManager& dlp_rules_manager) {
if (!HasInstance())
new DataTransferDlpController();
new DataTransferDlpController(dlp_rules_manager);
}
bool DataTransferDlpController::IsDataReadAllowed(
......@@ -79,15 +46,18 @@ bool DataTransferDlpController::IsDataReadAllowed(
switch (dst_type) {
case ui::EndpointType::kDefault:
case ui::EndpointType::kUnknownVm:
case ui::EndpointType::kBorealis:
case ui::EndpointType::kBorealis: {
// Passing empty URL will return restricted if there's a rule restricting
// the src against any dst (*), otherwise it will return ALLOW.
level = IsDstRestricted(src_url, GURL());
level = dlp_rules_manager_.IsRestrictedDestination(
src_url, GURL(), DlpRulesManager::Restriction::kClipboard);
break;
}
case ui::EndpointType::kUrl: {
GURL dst_url = data_dst->origin()->GetURL();
level = IsDstRestricted(src_url, dst_url);
level = dlp_rules_manager_.IsRestrictedDestination(
src_url, dst_url, DlpRulesManager::Restriction::kClipboard);
// Files Apps continously reads the clipboard data which triggers a lot of
// notifications while the user isn't actually initiating any copy/paste.
// TODO(crbug.com/1152475): Find a better way to handle File app.
......@@ -96,23 +66,33 @@ bool DataTransferDlpController::IsDataReadAllowed(
break;
}
case ui::EndpointType::kCrostini:
level = IsCrostiniRestricted(src_url);
case ui::EndpointType::kCrostini: {
level = dlp_rules_manager_.IsRestrictedComponent(
src_url, DlpRulesManager::Component::kCrostini,
DlpRulesManager::Restriction::kClipboard);
break;
}
case ui::EndpointType::kPluginVm:
level = IsPluginVmRestricted(src_url);
case ui::EndpointType::kPluginVm: {
level = dlp_rules_manager_.IsRestrictedComponent(
src_url, DlpRulesManager::Component::kPluginVm,
DlpRulesManager::Restriction::kClipboard);
break;
}
case ui::EndpointType::kArc:
level = IsArcRestricted(src_url);
case ui::EndpointType::kArc: {
level = dlp_rules_manager_.IsRestrictedComponent(
src_url, DlpRulesManager::Component::kArc,
DlpRulesManager::Restriction::kClipboard);
break;
}
case ui::EndpointType::kClipboardHistory:
case ui::EndpointType::kClipboardHistory: {
// When ClipboardHistory tries to read the clipboard we should allow it
// silently.
notify_on_paste = false;
break;
}
default:
NOTREACHED();
......@@ -125,7 +105,9 @@ bool DataTransferDlpController::IsDataReadAllowed(
return level == DlpRulesManager::Level::kAllow;
}
DataTransferDlpController::DataTransferDlpController() = default;
DataTransferDlpController::DataTransferDlpController(
const DlpRulesManager& dlp_rules_manager)
: dlp_rules_manager_(dlp_rules_manager) {}
DataTransferDlpController::~DataTransferDlpController() = default;
......
......@@ -15,6 +15,8 @@ class DataTransferEndpoint;
namespace policy {
class DlpRulesManager;
// DataTransferDlpController is responsible for preventing leaks of confidential
// data through clipboard data read or drag-and-drop by controlling read
// operations according to the rules of the Data leak prevention policy set by
......@@ -23,11 +25,14 @@ class DataTransferDlpController : public ui::DataTransferPolicyController {
public:
// Creates an instance of the class.
// Indicates that restricting clipboard content and drag-n-drop is required.
static void Init();
// It's guaranteed that `dlp_rules_manager` controls the lifetime of
// DataTransferDlpController and outlives it.
static void Init(const DlpRulesManager& dlp_rules_manager);
DataTransferDlpController(const DataTransferDlpController&) = delete;
void operator=(const DataTransferDlpController&) = delete;
// ui::DataTransferPolicyController:
// nullptr can be passed instead of `data_src` or `data_dst`. If data read is
// not allowed, this function will show a notification to the user.
bool IsDataReadAllowed(
......@@ -35,7 +40,7 @@ class DataTransferDlpController : public ui::DataTransferPolicyController {
const ui::DataTransferEndpoint* const data_dst) override;
protected:
DataTransferDlpController();
DataTransferDlpController(const DlpRulesManager& dlp_rules_manager);
~DataTransferDlpController() override;
private:
......@@ -43,6 +48,7 @@ class DataTransferDlpController : public ui::DataTransferPolicyController {
const ui::DataTransferEndpoint* const data_src,
const ui::DataTransferEndpoint* const data_dst);
const DlpRulesManager& dlp_rules_manager_;
DlpClipboardNotificationHelper helper_;
};
......
......@@ -11,7 +11,7 @@
#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/crostini/fake_crostini_features.h"
#include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/browser/chromeos/policy/login_policy_test_base.h"
#include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
......
......@@ -4,9 +4,15 @@
#include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/account_id/account_id.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -22,10 +28,12 @@ constexpr char kYoutubeUrl[] = "https://www.youtube.com";
class MockDlpRulesManager : public DlpRulesManager {
public:
explicit MockDlpRulesManager(PrefService* local_state)
: DlpRulesManager(local_state) {}
MockDlpRulesManager() = default;
~MockDlpRulesManager() override = default;
MOCK_CONST_METHOD2(IsRestricted,
Level(const GURL& source, Restriction restriction));
MOCK_CONST_METHOD3(IsRestrictedDestination,
Level(const GURL& source,
const GURL& destination,
......@@ -44,24 +52,30 @@ class MockDlpRulesManager : public DlpRulesManager {
class MockDlpController : public DataTransferDlpController {
public:
MockDlpController(const DlpRulesManager& dlp_rules_manager)
: DataTransferDlpController(dlp_rules_manager) {}
MOCK_METHOD2(DoNotifyBlockedPaste,
void(const ui::DataTransferEndpoint* const data_src,
const ui::DataTransferEndpoint* const data_dst));
};
// Creates a new MockDlpRulesManager for the given |context|.
std::unique_ptr<KeyedService> BuildDlpRulesManager(
content::BrowserContext* context) {
return std::make_unique<::testing::StrictMock<MockDlpRulesManager>>();
}
} // namespace
class DataTransferDlpControllerTest : public testing::Test {
protected:
DataTransferDlpControllerTest()
: scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
rules_manager_(scoped_testing_local_state_.Get()) {
DlpRulesManagerFactory::OverrideManagerForTesting(&rules_manager_);
}
: rules_manager_(), dlp_controller_(rules_manager_) {}
~DataTransferDlpControllerTest() override = default;
ScopedTestingLocalState scoped_testing_local_state_;
content::BrowserTaskEnvironment task_environment_;
::testing::StrictMock<MockDlpRulesManager> rules_manager_;
::testing::StrictMock<MockDlpController> dlp_controller_;
};
......
......@@ -14,6 +14,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_notification_helper.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h"
#include "content/public/browser/visibility.h"
#include "content/public/browser/web_contents.h"
......
......@@ -8,7 +8,7 @@
#include "base/json/json_writer.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/browser/chromeos/policy/login_policy_test_base.h"
#include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
......
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_POLICY_CONSTANTS_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_POLICY_CONSTANTS_H_
namespace policy {
// The following const strings are used to parse the
// DataLeakPreventionRules policy pref value.
namespace dlp {
constexpr char kClipboardRestriction[] = "CLIPBOARD";
constexpr char kScreenshotRestriction[] = "SCREENSHOT";
constexpr char kPrintingRestriction[] = "PRINTING";
constexpr char kPrivacyScreenRestriction[] = "PRIVACY_SCREEN";
constexpr char kScreenShareRestriction[] = "SCREEN_SHARE";
constexpr char kArc[] = "ARC";
constexpr char kCrostini[] = "CROSTINI";
constexpr char kPluginVm[] = "PLUGIN_VM";
constexpr char kAllowLevel[] = "ALLOW";
constexpr char kBlockLevel[] = "BLOCK";
} // namespace dlp
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_POLICY_CONSTANTS_H_
......@@ -5,39 +5,12 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_H_
#include <map>
#include <memory>
#include <set>
#include "base/no_destructor.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/url_matcher/url_matcher.h"
class GURL;
class PrefRegistrySimple;
namespace policy {
// The following const strings are used to parse the policy pref value.
namespace dlp {
extern const char kClipboardRestriction[];
extern const char kScreenshotRestriction[];
extern const char kPrintingRestriction[];
extern const char kPrivacyScreenRestriction[];
extern const char kScreenShareRestriction[];
extern const char kArc[];
extern const char kCrostini[];
extern const char kPluginVm[];
extern const char kAllowLevel[];
extern const char kBlockLevel[];
} // namespace dlp
// DlpRulesManager parses the rules set by DataLeakPreventionRulesList policy
// and serves as an available service which can be queried anytime about the
// restrictions set by the policy.
......@@ -78,19 +51,14 @@ class DlpRulesManager : public KeyedService {
kMaxValue = kAllow
};
using RuleId = int;
using UrlConditionId = url_matcher::URLMatcherConditionSet::ID;
~DlpRulesManager() override;
// Registers the policy pref.
static void RegisterPrefs(PrefRegistrySimple* registry);
~DlpRulesManager() override = default;
// Returns the enforcement level for `restriction` given that data comes
// from `source`. ALLOW is returned if no restrictions should be applied.
// Requires `restriction` to be one of the following: screenshot, printing,
// privacy screen, screenshare.
virtual Level IsRestricted(const GURL& source, Restriction restriction) const;
virtual Level IsRestricted(const GURL& source,
Restriction restriction) const = 0;
// Returns the enforcement level for `restriction` given that data comes
// from `source` and requested to be shared to `destination`. ALLOW is
......@@ -98,7 +66,7 @@ class DlpRulesManager : public KeyedService {
// clipboard.
virtual Level IsRestrictedDestination(const GURL& source,
const GURL& destination,
Restriction restriction) const;
Restriction restriction) const = 0;
// Returns the enforcement level for `restriction` given that data comes
// from `source` and requested to be shared to `destination`. ALLOW is
......@@ -106,76 +74,7 @@ class DlpRulesManager : public KeyedService {
// clipboard.
virtual Level IsRestrictedComponent(const GURL& source,
const Component& destination,
Restriction restriction) const;
protected:
friend class DlpRulesManagerFactory;
friend class DlpRulesManagerTest;
explicit DlpRulesManager(PrefService* local_state);
private:
void OnPolicyUpdate();
// Returns the maximum level of the rules of given `restriction` joined with
// the `selected_rules`.
Level GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& selected_rules) const;
// Returns the maximum level of the rules of given `restriction` joined with
// the `source_rules` and `destination_rules`.
Level GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& source_rules,
const std::set<RuleId>& destination_rules) const;
// Used to track kDlpRulesList local state pref.
PrefChangeRegistrar pref_change_registrar_;
// Used to match the URLs of the sources.
std::unique_ptr<url_matcher::URLMatcher> src_url_matcher_;
// Used to match the URLs of the destinations.
std::unique_ptr<url_matcher::URLMatcher> dst_url_matcher_;
// Map from the components to their configured rules IDs.
std::map<Component, std::set<RuleId>> components_rules_;
// Map from the restrictions to their configured rules IDs and levels.
std::map<Restriction, std::map<RuleId, Level>> restrictions_map_;
// Map from the URL matching conditions IDs of the sources to their configured
// rules IDs.
std::map<UrlConditionId, RuleId> src_url_rules_mapping_;
// Map from the URL matching conditions IDs of the destinations to their
// configured rules IDs.
std::map<UrlConditionId, RuleId> dst_url_rules_mapping_;
};
// Initializes an instance of DlpRulesManager when a primary managed profile is
// being created, e.g. when managed user sign in.
class DlpRulesManagerFactory : public BrowserContextKeyedServiceFactory {
public:
static DlpRulesManagerFactory* GetInstance();
// Returns nullptr if there is no primary profile, e.g. the session is not
// started.
static DlpRulesManager* GetForPrimaryProfile();
// TODO(crbug/1153146): Use TestingFactory instead.
static void OverrideManagerForTesting(DlpRulesManager* testing_manager);
private:
friend class base::NoDestructor<DlpRulesManagerFactory>;
DlpRulesManagerFactory();
~DlpRulesManagerFactory() override = default;
// BrowserStateKeyedServiceFactory overrides:
bool ServiceIsCreatedWithBrowserContext() const override;
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
Restriction restriction) const = 0;
};
} // namespace policy
......
// Copyright 2020 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 "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
#include "base/no_destructor.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
namespace policy {
// static
DlpRulesManagerFactory* DlpRulesManagerFactory::GetInstance() {
static base::NoDestructor<DlpRulesManagerFactory> factory;
return factory.get();
}
// static
DlpRulesManager* DlpRulesManagerFactory::GetForPrimaryProfile() {
Profile* profile = ProfileManager::GetPrimaryUserProfile();
if (!profile)
return nullptr;
return static_cast<DlpRulesManager*>(
DlpRulesManagerFactory::GetInstance()->GetServiceForBrowserContext(
profile, /*create=*/true));
}
DlpRulesManagerFactory::DlpRulesManagerFactory()
: BrowserContextKeyedServiceFactory(
"DlpRulesManager",
BrowserContextDependencyManager::GetInstance()) {}
bool DlpRulesManagerFactory::ServiceIsCreatedWithBrowserContext() const {
// We have to create the instance immediately because it's responsible for
// instantiation of DataTransferDlpController. Otherwise even if the policy is
// present, DataTransferDlpController won't be instantiated and therefore no
// policy will be applied.
return true;
}
KeyedService* DlpRulesManagerFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
Profile* profile = Profile::FromBrowserContext(context);
// UserManager might be not available in tests.
if (!user_manager::UserManager::IsInitialized() || !profile ||
!chromeos::ProfileHelper::IsPrimaryProfile(profile) ||
!profile->GetProfilePolicyConnector()->IsManaged()) {
return nullptr;
}
PrefService* local_state = g_browser_process->local_state();
// Might be not available in tests.
if (!local_state)
return nullptr;
return new DlpRulesManagerImpl(local_state);
}
} // namespace policy
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_FACTORY_H_
#include "base/no_destructor.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace policy {
// Initializes an instance of DlpRulesManager when a primary managed profile is
// being created, e.g. when managed user signs in.
class DlpRulesManagerFactory : public BrowserContextKeyedServiceFactory {
public:
static DlpRulesManagerFactory* GetInstance();
// Returns nullptr if there is no primary profile, e.g. the session is not
// started.
static DlpRulesManager* GetForPrimaryProfile();
private:
friend class base::NoDestructor<DlpRulesManagerFactory>;
DlpRulesManagerFactory();
~DlpRulesManagerFactory() override = default;
// BrowserStateKeyedServiceFactory overrides:
bool ServiceIsCreatedWithBrowserContext() const override;
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_FACTORY_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
#include <algorithm>
#include <iterator>
......@@ -16,39 +16,17 @@
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
#include "chrome/common/chrome_features.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/browser/url_util.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace policy {
namespace dlp {
constexpr char kClipboardRestriction[] = "CLIPBOARD";
constexpr char kScreenshotRestriction[] = "SCREENSHOT";
constexpr char kPrintingRestriction[] = "PRINTING";
constexpr char kPrivacyScreenRestriction[] = "PRIVACY_SCREEN";
constexpr char kScreenShareRestriction[] = "SCREEN_SHARE";
constexpr char kArc[] = "ARC";
constexpr char kCrostini[] = "CROSTINI";
constexpr char kPluginVm[] = "PLUGIN_VM";
constexpr char kAllowLevel[] = "ALLOW";
constexpr char kBlockLevel[] = "BLOCK";
} // namespace dlp
namespace {
DlpRulesManager::Restriction GetClassMapping(const std::string& restriction) {
......@@ -108,18 +86,13 @@ DlpRulesManager::Level GetMaxLevel(const DlpRulesManager::Level& level_1,
: level_2;
}
DlpRulesManager::Level GetMinLevel(const DlpRulesManager::Level& level_1,
const DlpRulesManager::Level& level_2) {
return GetPriorityMapping(level_1) < GetPriorityMapping(level_2) ? level_1
: level_2;
}
// Inserts a mapping between URLs conditions IDs range to `rule_id` in `map`.
void InsertUrlsRulesMapping(
DlpRulesManager::UrlConditionId url_condition_id_start,
DlpRulesManager::UrlConditionId url_condition_id_end,
DlpRulesManager::RuleId rule_id,
std::map<DlpRulesManager::UrlConditionId, DlpRulesManager::RuleId>& map) {
DlpRulesManagerImpl::UrlConditionId url_condition_id_start,
DlpRulesManagerImpl::UrlConditionId url_condition_id_end,
DlpRulesManagerImpl::RuleId rule_id,
std::map<DlpRulesManagerImpl::UrlConditionId, DlpRulesManagerImpl::RuleId>&
map) {
for (auto url_condition_id = url_condition_id_start;
url_condition_id <= url_condition_id_end; ++url_condition_id) {
map[url_condition_id] = rule_id;
......@@ -128,33 +101,34 @@ void InsertUrlsRulesMapping(
// Matches `url` against `url_matcher` patterns and returns the rules IDs
// configured with the matched patterns.
std::set<DlpRulesManager::RuleId> MatchUrlAndGetRulesMapping(
std::set<DlpRulesManagerImpl::RuleId> MatchUrlAndGetRulesMapping(
const GURL& url,
const url_matcher::URLMatcher* url_matcher,
const std::map<DlpRulesManager::UrlConditionId, DlpRulesManager::RuleId>&
rules_map) {
const std::map<DlpRulesManagerImpl::UrlConditionId,
DlpRulesManagerImpl::RuleId>& rules_map) {
DCHECK(url_matcher);
const std::set<DlpRulesManager::UrlConditionId> url_conditions_ids =
const std::set<DlpRulesManagerImpl::UrlConditionId> url_conditions_ids =
url_matcher->MatchURL(url);
std::set<DlpRulesManager::RuleId> rule_ids;
std::set<DlpRulesManagerImpl::RuleId> rule_ids;
for (const auto& id : url_conditions_ids) {
rule_ids.insert(rules_map.at(id));
}
return rule_ids;
}
// A singleton instance of DlpRulesManager for testing.
static DlpRulesManager* g_dlp_rules_manager_for_testing = nullptr;
} // namespace
DlpRulesManagerImpl::~DlpRulesManagerImpl() {
DataTransferDlpController::DeleteInstance();
}
// static
void DlpRulesManager::RegisterPrefs(PrefRegistrySimple* registry) {
void DlpRulesManagerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterListPref(policy_prefs::kDlpRulesList);
}
DlpRulesManager::Level DlpRulesManager::IsRestricted(
DlpRulesManager::Level DlpRulesManagerImpl::IsRestricted(
const GURL& source,
Restriction restriction) const {
DCHECK(src_url_matcher_);
......@@ -169,7 +143,7 @@ DlpRulesManager::Level DlpRulesManager::IsRestricted(
return GetMaxJoinRestrictionLevel(restriction, source_rules_ids);
}
DlpRulesManager::Level DlpRulesManager::IsRestrictedDestination(
DlpRulesManager::Level DlpRulesManagerImpl::IsRestrictedDestination(
const GURL& source,
const GURL& destination,
Restriction restriction) const {
......@@ -192,7 +166,7 @@ DlpRulesManager::Level DlpRulesManager::IsRestrictedDestination(
destination_rules_ids);
}
DlpRulesManager::Level DlpRulesManager::IsRestrictedComponent(
DlpRulesManager::Level DlpRulesManagerImpl::IsRestrictedComponent(
const GURL& source,
const Component& destination,
Restriction restriction) const {
......@@ -212,18 +186,16 @@ DlpRulesManager::Level DlpRulesManager::IsRestrictedComponent(
components_rules_ids);
}
DlpRulesManager::DlpRulesManager(PrefService* local_state) {
DlpRulesManagerImpl::DlpRulesManagerImpl(PrefService* local_state) {
pref_change_registrar_.Init(local_state);
pref_change_registrar_.Add(
policy_prefs::kDlpRulesList,
base::BindRepeating(&DlpRulesManager::OnPolicyUpdate,
base::BindRepeating(&DlpRulesManagerImpl::OnPolicyUpdate,
base::Unretained(this)));
OnPolicyUpdate();
}
DlpRulesManager::~DlpRulesManager() = default;
void DlpRulesManager::OnPolicyUpdate() {
void DlpRulesManagerImpl::OnPolicyUpdate() {
components_rules_.clear();
restrictions_map_.clear();
src_url_rules_mapping_.clear();
......@@ -307,13 +279,13 @@ void DlpRulesManager::OnPolicyUpdate() {
}
if (base::Contains(restrictions_map_, Restriction::kClipboard)) {
DataTransferDlpController::Init();
DataTransferDlpController::Init(*this);
} else {
DataTransferDlpController::DeleteInstance();
}
}
DlpRulesManager::Level DlpRulesManager::GetMaxJoinRestrictionLevel(
DlpRulesManager::Level DlpRulesManagerImpl::GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& selected_rules) const {
auto restriction_it = restrictions_map_.find(restriction);
......@@ -336,7 +308,7 @@ DlpRulesManager::Level DlpRulesManager::GetMaxJoinRestrictionLevel(
return max_level;
}
DlpRulesManager::Level DlpRulesManager::GetMaxJoinRestrictionLevel(
DlpRulesManager::Level DlpRulesManagerImpl::GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& source_rules,
const std::set<RuleId>& destination_rules) const {
......@@ -347,56 +319,4 @@ DlpRulesManager::Level DlpRulesManager::GetMaxJoinRestrictionLevel(
return GetMaxJoinRestrictionLevel(restriction, intersection);
}
// static
DlpRulesManagerFactory* DlpRulesManagerFactory::GetInstance() {
static base::NoDestructor<DlpRulesManagerFactory> factory;
return factory.get();
}
// static
DlpRulesManager* DlpRulesManagerFactory::GetForPrimaryProfile() {
if (g_dlp_rules_manager_for_testing)
return g_dlp_rules_manager_for_testing;
Profile* profile = ProfileManager::GetPrimaryUserProfile();
if (!profile)
return nullptr;
return static_cast<DlpRulesManager*>(
DlpRulesManagerFactory::GetInstance()->GetServiceForBrowserContext(
profile, /*create=*/false));
}
// static
void DlpRulesManagerFactory::OverrideManagerForTesting(
DlpRulesManager* manager) {
g_dlp_rules_manager_for_testing = manager;
}
DlpRulesManagerFactory::DlpRulesManagerFactory()
: BrowserContextKeyedServiceFactory(
"DlpRulesManager",
BrowserContextDependencyManager::GetInstance()) {}
bool DlpRulesManagerFactory::ServiceIsCreatedWithBrowserContext() const {
return true;
}
KeyedService* DlpRulesManagerFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
Profile* profile = Profile::FromBrowserContext(context);
// UserManager might be not available in tests.
if (!user_manager::UserManager::IsInitialized() || !profile ||
!chromeos::ProfileHelper::IsPrimaryProfile(profile) ||
!profile->GetProfilePolicyConnector()->IsManaged()) {
return nullptr;
}
PrefService* local_state = g_browser_process->local_state();
// Might be not available in tests.
if (!local_state)
return nullptr;
return new DlpRulesManager(local_state);
}
} // namespace policy
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_IMPL_H_
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include <map>
#include <memory>
#include <set>
#include "components/prefs/pref_change_registrar.h"
#include "components/url_matcher/url_matcher.h"
class GURL;
class PrefRegistrySimple;
namespace policy {
class DlpRulesManagerImpl : public DlpRulesManager {
public:
using RuleId = int;
using UrlConditionId = url_matcher::URLMatcherConditionSet::ID;
~DlpRulesManagerImpl() override;
// Registers the policy pref.
static void RegisterPrefs(PrefRegistrySimple* registry);
// DlpRulesManager:
Level IsRestricted(const GURL& source,
Restriction restriction) const override;
Level IsRestrictedDestination(const GURL& source,
const GURL& destination,
Restriction restriction) const override;
Level IsRestrictedComponent(const GURL& source,
const Component& destination,
Restriction restriction) const override;
protected:
friend class DlpRulesManagerFactory;
friend class DlpRulesManagerImplTest;
explicit DlpRulesManagerImpl(PrefService* local_state);
private:
void OnPolicyUpdate();
// Returns the maximum level of the rules of given `restriction` joined with
// the `selected_rules`.
Level GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& selected_rules) const;
// Returns the maximum level of the rules of given `restriction` joined with
// the `source_rules` and `destination_rules`.
Level GetMaxJoinRestrictionLevel(
const Restriction restriction,
const std::set<RuleId>& source_rules,
const std::set<RuleId>& destination_rules) const;
// Used to track kDlpRulesList local state pref.
PrefChangeRegistrar pref_change_registrar_;
// Used to match the URLs of the sources.
std::unique_ptr<url_matcher::URLMatcher> src_url_matcher_;
// Used to match the URLs of the destinations.
std::unique_ptr<url_matcher::URLMatcher> dst_url_matcher_;
// Map from the components to their configured rules IDs.
std::map<Component, std::set<RuleId>> components_rules_;
// Map from the restrictions to their configured rules IDs and levels.
std::map<Restriction, std::map<RuleId, Level>> restrictions_map_;
// Map from the URL matching conditions IDs of the sources to their configured
// rules IDs.
std::map<UrlConditionId, RuleId> src_url_rules_mapping_;
// Map from the URL matching conditions IDs of the destinations to their
// configured rules IDs.
std::map<UrlConditionId, RuleId> dst_url_rules_mapping_;
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_RULES_MANAGER_IMPL_H_
......@@ -4,7 +4,8 @@
#include "base/json/json_writer.h"
#include "base/values.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/browser/chromeos/policy/login_policy_test_base.h"
#include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
......
......@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
#include <string>
#include <vector>
#include "base/strings/strcat.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/scoped_testing_local_state.h"
......@@ -57,9 +57,9 @@ base::Value GenerateClipboardCopyDisallowedRule() {
} // namespace
class DlpRulesManagerTest : public testing::Test {
class DlpRulesManagerImplTest : public testing::Test {
protected:
DlpRulesManagerTest()
DlpRulesManagerImplTest()
: testing_local_state_(TestingBrowserProcess::GetGlobal()),
dlp_rules_manager_(testing_local_state_.Get()) {}
......@@ -70,10 +70,10 @@ class DlpRulesManagerTest : public testing::Test {
}
ScopedTestingLocalState testing_local_state_;
DlpRulesManager dlp_rules_manager_;
DlpRulesManagerImpl dlp_rules_manager_;
};
TEST_F(DlpRulesManagerTest, EmptyPref) {
TEST_F(DlpRulesManagerImplTest, EmptyPref) {
UpdatePolicyPref(base::Value(base::Value::Type::LIST));
EXPECT_EQ(DlpRulesManager::Level::kAllow,
......@@ -85,7 +85,7 @@ TEST_F(DlpRulesManagerTest, EmptyPref) {
DlpRulesManager::Restriction::kClipboard));
}
TEST_F(DlpRulesManagerTest, IsRestricted_LevelPrecedence) {
TEST_F(DlpRulesManagerImplTest, IsRestricted_LevelPrecedence) {
base::Value rules(base::Value::Type::LIST);
// First Rule
......@@ -156,7 +156,7 @@ TEST_F(DlpRulesManagerTest, IsRestricted_LevelPrecedence) {
GURL(kUrlStr1), DlpRulesManager::Restriction::kScreenshot));
}
TEST_F(DlpRulesManagerTest, UpdatePref) {
TEST_F(DlpRulesManagerImplTest, UpdatePref) {
// First DLP rule
base::Value rules_1(base::Value::Type::LIST);
......@@ -203,7 +203,7 @@ TEST_F(DlpRulesManagerTest, UpdatePref) {
GURL(kUrlStr2), DlpRulesManager::Restriction::kScreenshot));
}
TEST_F(DlpRulesManagerTest, IsRestrictedComponent_Clipboard) {
TEST_F(DlpRulesManagerImplTest, IsRestrictedComponent_Clipboard) {
base::Value rules(base::Value::Type::LIST);
base::Value src_urls(base::Value::Type::LIST);
......@@ -232,7 +232,7 @@ TEST_F(DlpRulesManagerTest, IsRestrictedComponent_Clipboard) {
DlpRulesManager::Restriction::kClipboard));
}
TEST_F(DlpRulesManagerTest, SameSrcDst_Clipboard) {
TEST_F(DlpRulesManagerImplTest, SameSrcDst_Clipboard) {
base::Value rules = GenerateClipboardCopyDisallowedRule();
UpdatePolicyPref(std::move(rules));
......@@ -243,7 +243,7 @@ TEST_F(DlpRulesManagerTest, SameSrcDst_Clipboard) {
DlpRulesManager::Restriction::kClipboard));
}
TEST_F(DlpRulesManagerTest, EmptyUrl_Clipboard) {
TEST_F(DlpRulesManagerImplTest, EmptyUrl_Clipboard) {
base::Value rules = GenerateClipboardCopyDisallowedRule();
// Second Rule
......@@ -274,7 +274,7 @@ TEST_F(DlpRulesManagerTest, EmptyUrl_Clipboard) {
GURL(kUrlStr4), GURL(), DlpRulesManager::Restriction::kClipboard));
}
TEST_F(DlpRulesManagerTest, IsRestricted_MultipleURLs) {
TEST_F(DlpRulesManagerImplTest, IsRestricted_MultipleURLs) {
base::Value rules(base::Value::Type::LIST);
base::Value src_urls_1(base::Value::Type::LIST);
......@@ -352,7 +352,7 @@ TEST_F(DlpRulesManagerTest, IsRestricted_MultipleURLs) {
GURL(kUrlStr1), DlpRulesManager::Restriction::kClipboard));
}
TEST_F(DlpRulesManagerTest, DisabledByFeature) {
TEST_F(DlpRulesManagerImplTest, DisabledByFeature) {
base::Value rules = GenerateClipboardCopyDisallowedRule();
UpdatePolicyPref(std::move(rules));
......
......@@ -305,7 +305,7 @@
#include "chrome/browser/chromeos/policy/auto_enrollment_client_impl.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
#include "chrome/browser/chromeos/policy/dm_token_storage.h"
#include "chrome/browser/chromeos/policy/enrollment_requisition_manager.h"
#include "chrome/browser/chromeos/policy/extension_install_event_log_manager_wrapper.h"
......@@ -762,7 +762,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs(registry);
policy::DeviceStatusCollector::RegisterPrefs(registry);
policy::DeviceWallpaperImageExternalDataHandler::RegisterPrefs(registry);
policy::DlpRulesManager::RegisterPrefs(registry);
policy::DlpRulesManagerImpl::RegisterPrefs(registry);
policy::DMTokenStorage::RegisterPrefs(registry);
policy::EnrollmentRequisitionManager::RegisterPrefs(registry);
policy::MinimumVersionPolicyHandler::RegisterPrefs(registry);
......
......@@ -2688,7 +2688,7 @@ if (!is_android) {
"../browser/chromeos/policy/display_rotation_default_handler_browsertest.cc",
"../browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc",
"../browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc",
"../browser/chromeos/policy/dlp/dlp_rules_manager_browsertest.cc",
"../browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc",
"../browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc",
"../browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h",
"../browser/chromeos/policy/dlp/mock_dlp_content_manager.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment