blob: 4a0ca9b44ca90559f64f5e41e44828caa89c5326 [file] [log] [blame]
// 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_content_manager.h"
#include <memory>
#include "ash/public/cpp/privacy_screen_dlp_helper.h"
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_content_manager_test_helper.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_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/chromeos/policy/dlp/mock_dlp_rules_manager.h"
#include "chrome/test/base/testing_profile.h"
#include "components/reporting/client/mock_report_queue.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
using ::testing::_;
using ::testing::Mock;
namespace policy {
namespace {
constexpr char kEmailId[] = "test@example.com";
constexpr char kGaiaId[] = "12345";
const DlpContentRestrictionSet kEmptyRestrictionSet;
const DlpContentRestrictionSet kScreenshotRestricted(
DlpContentRestriction::kScreenshot,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kNonEmptyRestrictionSet = kScreenshotRestricted;
const DlpContentRestrictionSet kPrivacyScreenEnforced(
DlpContentRestriction::kPrivacyScreen,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kPrivacyScreenReported(
DlpContentRestriction::kPrivacyScreen,
DlpRulesManager::Level::kReport);
const DlpContentRestrictionSet kPrintingRestricted(
DlpContentRestriction::kPrint,
DlpRulesManager::Level::kBlock);
class MockPrivacyScreenHelper : public ash::PrivacyScreenDlpHelper {
public:
MOCK_METHOD1(SetEnforced, void(bool));
};
} // namespace
class DlpContentManagerTest : public testing::Test {
public:
std::unique_ptr<KeyedService> SetDlpRulesManager(
content::BrowserContext* context) {
auto dlp_rules_manager = std::make_unique<MockDlpRulesManager>();
mock_rules_manager_ = dlp_rules_manager.get();
return dlp_rules_manager;
}
protected:
DlpContentManagerTest()
: profile_(std::make_unique<TestingProfile>()),
user_manager_(new ash::FakeChromeUserManager()),
scoped_user_manager_(base::WrapUnique(user_manager_)) {}
DlpContentManagerTest(const DlpContentManagerTest&) = delete;
DlpContentManagerTest& operator=(const DlpContentManagerTest&) = delete;
~DlpContentManagerTest() override = default;
std::unique_ptr<content::WebContents> CreateWebContents() {
return content::WebContentsTester::CreateTestWebContents(profile_.get(),
nullptr);
}
void SetReportQueueForReportingManager() {
auto report_queue = std::make_unique<reporting::MockReportQueue>();
EXPECT_CALL(*report_queue.get(), AddRecord)
.WillRepeatedly(
[this](base::StringPiece record, reporting::Priority priority,
reporting::ReportQueue::EnqueueCallback callback) {
DlpPolicyEvent event;
event.ParseFromString(std::string(record));
// Don't use this code in a multithreaded env as it can course
// concurrency issues with the events in the vector.
events_.push_back(event);
});
helper_.GetReportingManager()->GetReportQueueSetter().Run(
std::move(report_queue));
}
void SetupDlpRulesManager() {
DlpRulesManagerFactory::GetInstance()->SetTestingFactory(
profile(),
base::BindRepeating(&DlpContentManagerTest::SetDlpRulesManager,
base::Unretained(this)));
ASSERT_TRUE(DlpRulesManagerFactory::GetForPrimaryProfile());
}
void LoginFakeUser() {
AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
profile_->SetIsNewProfile(true);
user_manager::User* user =
user_manager_->AddUserWithAffiliationAndTypeAndProfile(
account_id, false /*is_affiliated*/,
user_manager::USER_TYPE_REGULAR, profile());
user_manager_->UserLoggedIn(account_id, user->username_hash(),
false /* browser_restart */,
false /* is_child */);
}
DlpContentManager* GetManager() { return helper_.GetContentManager(); }
TestingProfile* profile() { return profile_.get(); }
DlpContentManagerTestHelper helper_;
content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
base::HistogramTester histogram_tester_;
std::vector<DlpPolicyEvent> events_;
MockDlpRulesManager* mock_rules_manager_ = nullptr;
private:
content::RenderViewHostTestEnabler rvh_test_enabler_;
const std::unique_ptr<TestingProfile> profile_;
ash::FakeChromeUserManager* user_manager_;
user_manager::ScopedUserManager scoped_user_manager_;
};
TEST_F(DlpContentManagerTest, NoConfidentialDataShown) {
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
}
TEST_F(DlpContentManagerTest, ConfidentialDataShown) {
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
helper_.ChangeConfidentiality(web_contents.get(), kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
helper_.DestroyWebContents(web_contents.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
}
TEST_F(DlpContentManagerTest, ConfidentialDataVisibilityChanged) {
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
helper_.ChangeConfidentiality(web_contents.get(), kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
web_contents->WasHidden();
helper_.ChangeVisibility(web_contents.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
web_contents->WasShown();
helper_.ChangeVisibility(web_contents.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
helper_.DestroyWebContents(web_contents.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
}
TEST_F(DlpContentManagerTest,
TwoWebContentsVisibilityAndConfidentialityChanged) {
std::unique_ptr<content::WebContents> web_contents1 = CreateWebContents();
std::unique_ptr<content::WebContents> web_contents2 = CreateWebContents();
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
// WebContents 1 becomes confidential.
helper_.ChangeConfidentiality(web_contents1.get(), kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
web_contents2->WasHidden();
helper_.ChangeVisibility(web_contents2.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
// WebContents 1 becomes non-confidential.
helper_.ChangeConfidentiality(web_contents1.get(), kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
// WebContents 2 becomes confidential.
helper_.ChangeConfidentiality(web_contents2.get(), kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
web_contents2->WasShown();
helper_.ChangeVisibility(web_contents2.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kNonEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kNonEmptyRestrictionSet);
helper_.DestroyWebContents(web_contents1.get());
helper_.DestroyWebContents(web_contents2.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents1.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents2.get()),
kEmptyRestrictionSet);
EXPECT_EQ(GetManager()->GetOnScreenPresentRestrictions(),
kEmptyRestrictionSet);
}
TEST_F(DlpContentManagerTest, PrivacyScreenEnforcement) {
LoginFakeUser();
SetReportQueueForReportingManager();
SetupDlpRulesManager();
const std::string src_pattern("example.com");
EXPECT_CALL(*mock_rules_manager_, GetSourceUrlPattern(_, _, _))
.WillRepeatedly(::testing::Return(src_pattern));
MockPrivacyScreenHelper mock_privacy_screen_helper;
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(testing::_)).Times(0);
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
testing::Mock::VerifyAndClearExpectations(&mock_privacy_screen_helper);
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(true)).Times(1);
helper_.ChangeConfidentiality(web_contents.get(), kPrivacyScreenEnforced);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, false, 0);
EXPECT_EQ(events_.size(), 1u);
EXPECT_THAT(events_[0],
IsDlpPolicyEvent(CreateDlpPolicyEvent(
src_pattern, DlpRulesManager::Restriction::kPrivacyScreen,
DlpRulesManager::Level::kBlock)));
testing::Mock::VerifyAndClearExpectations(&mock_privacy_screen_helper);
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(false)).Times(1);
web_contents->WasHidden();
helper_.ChangeVisibility(web_contents.get());
task_environment_.FastForwardBy(helper_.GetPrivacyScreenOffDelay());
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, false, 1);
EXPECT_EQ(events_.size(), 1u);
testing::Mock::VerifyAndClearExpectations(&mock_privacy_screen_helper);
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(true)).Times(1);
web_contents->WasShown();
helper_.ChangeVisibility(web_contents.get());
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, true, 2);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, false, 1);
EXPECT_EQ(events_.size(), 2u);
EXPECT_THAT(events_[1],
IsDlpPolicyEvent(CreateDlpPolicyEvent(
src_pattern, DlpRulesManager::Restriction::kPrivacyScreen,
DlpRulesManager::Level::kBlock)));
testing::Mock::VerifyAndClearExpectations(&mock_privacy_screen_helper);
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(false)).Times(1);
helper_.DestroyWebContents(web_contents.get());
task_environment_.FastForwardBy(helper_.GetPrivacyScreenOffDelay());
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, true, 2);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, false, 2);
EXPECT_EQ(events_.size(), 2u);
}
TEST_F(DlpContentManagerTest, PrivacyScreenReported) {
LoginFakeUser();
SetReportQueueForReportingManager();
SetupDlpRulesManager();
const std::string src_pattern("example.com");
EXPECT_CALL(*mock_rules_manager_, GetSourceUrlPattern(_, _, _))
.WillRepeatedly(::testing::Return(src_pattern));
// Privacy screen should never be enforced.
MockPrivacyScreenHelper mock_privacy_screen_helper;
EXPECT_CALL(mock_privacy_screen_helper, SetEnforced(testing::_)).Times(0);
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
helper_.ChangeConfidentiality(web_contents.get(), kPrivacyScreenReported);
EXPECT_EQ(events_.size(), 1u);
EXPECT_THAT(events_[0],
IsDlpPolicyEvent(CreateDlpPolicyEvent(
src_pattern, DlpRulesManager::Restriction::kPrivacyScreen,
DlpRulesManager::Level::kReport)));
web_contents->WasHidden();
helper_.ChangeVisibility(web_contents.get());
task_environment_.FastForwardBy(helper_.GetPrivacyScreenOffDelay());
EXPECT_EQ(events_.size(), 1u);
web_contents->WasShown();
helper_.ChangeVisibility(web_contents.get());
EXPECT_EQ(events_.size(), 2u);
EXPECT_THAT(events_[1],
IsDlpPolicyEvent(CreateDlpPolicyEvent(
src_pattern, DlpRulesManager::Restriction::kPrivacyScreen,
DlpRulesManager::Level::kReport)));
helper_.DestroyWebContents(web_contents.get());
task_environment_.FastForwardBy(helper_.GetPrivacyScreenOffDelay());
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, true, 0);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrivacyScreenEnforcedUMA, false, 0);
EXPECT_EQ(events_.size(), 2u);
}
TEST_F(DlpContentManagerTest, PrintingRestricted) {
LoginFakeUser();
std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_FALSE(GetManager()->IsPrintingRestricted(web_contents.get()));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, true, 0);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, false, 1);
SetReportQueueForReportingManager();
SetupDlpRulesManager();
const std::string src_pattern("example.com");
EXPECT_CALL(*mock_rules_manager_, GetSourceUrlPattern(_, _, _))
.Times(1)
.WillOnce(::testing::Return(src_pattern));
helper_.ChangeConfidentiality(web_contents.get(), kPrintingRestricted);
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kPrintingRestricted);
EXPECT_TRUE(GetManager()->IsPrintingRestricted(web_contents.get()));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, false, 1);
EXPECT_EQ(events_.size(), 1u);
EXPECT_THAT(events_[0],
IsDlpPolicyEvent(CreateDlpPolicyEvent(
src_pattern, DlpRulesManager::Restriction::kPrinting,
DlpRulesManager::Level::kBlock)));
helper_.DestroyWebContents(web_contents.get());
EXPECT_EQ(GetManager()->GetConfidentialRestrictions(web_contents.get()),
kEmptyRestrictionSet);
EXPECT_FALSE(GetManager()->IsPrintingRestricted(web_contents.get()));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kPrintingBlockedUMA, false, 2);
}
} // namespace policy