blob: 221f91f7aeda9eed8b7b40b23da94b0b487ed4e8 [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 "ash/constants/ash_features.h"
#include "base/callback_helpers.h"
#include "base/json/json_writer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/ash/policy/core/user_policy_test_helper.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_constants.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/dlp_rules_manager_test_utils.h"
#include "chrome/browser/chromeos/policy/dlp/mock_dlp_rules_manager.h"
#include "chrome/browser/chromeos/policy/login/login_policy_test_base.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/policy/messaging_layer/public/report_queue_impl.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/printing/print_view_manager_common.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/chrome_capture_mode_delegate.h"
#include "chrome/browser/ui/ash/screenshot_area.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/reporting/storage/test_storage_module.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/rect.h"
using testing::_;
namespace policy {
namespace {
const DlpContentRestrictionSet kEmptyRestrictionSet;
const DlpContentRestrictionSet kScreenshotRestricted(
DlpContentRestriction::kScreenshot,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kScreenshotReported(
DlpContentRestriction::kScreenshot,
DlpRulesManager::Level::kReport);
const DlpContentRestrictionSet kPrivacyScreenEnforced(
DlpContentRestriction::kPrivacyScreen,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kPrintAllowed(DlpContentRestriction::kPrint,
DlpRulesManager::Level::kAllow);
const DlpContentRestrictionSet kPrintRestricted(DlpContentRestriction::kPrint,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kPrintReported(DlpContentRestriction::kPrint,
DlpRulesManager::Level::kReport);
const DlpContentRestrictionSet kVideoCaptureRestricted(
DlpContentRestriction::kVideoCapture,
DlpRulesManager::Level::kBlock);
const DlpContentRestrictionSet kVideoCaptureReported(
DlpContentRestriction::kVideoCapture,
DlpRulesManager::Level::kReport);
const DlpContentRestrictionSet kScreenShareRestricted(
DlpContentRestriction::kScreenShare,
DlpRulesManager::Level::kBlock);
constexpr char kScreenCapturePausedNotificationId[] =
"screen_capture_dlp_paused-label";
constexpr char kScreenCaptureResumedNotificationId[] =
"screen_capture_dlp_resumed-label";
constexpr char kPrintBlockedNotificationId[] = "print_dlp_blocked";
constexpr char kExampleUrl[] = "https://example.com";
constexpr char kUrl1[] = "https://example1.com";
constexpr char kUrl2[] = "https://example2.com";
constexpr char kUrl3[] = "https://example3.com";
constexpr char kUrl4[] = "https://example4.com";
constexpr char kSrcPattern[] = "example.com";
} // namespace
class DlpContentManagerBrowserTest : public InProcessBrowserTest {
public:
DlpContentManagerBrowserTest() = default;
~DlpContentManagerBrowserTest() override = default;
// InProcessBrowserTest:
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(ash::features::kCaptureMode);
InProcessBrowserTest::SetUp();
}
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;
}
// Sets up mock rules manager.
void SetupDlpRulesManager() {
DlpRulesManagerFactory::GetInstance()->SetTestingFactory(
browser()->profile(),
base::BindRepeating(&DlpContentManagerBrowserTest::SetDlpRulesManager,
base::Unretained(this)));
ASSERT_TRUE(DlpRulesManagerFactory::GetForPrimaryProfile());
EXPECT_CALL(*mock_rules_manager_, GetSourceUrlPattern(_, _, _))
.WillRepeatedly(testing::Return(kSrcPattern));
EXPECT_CALL(*mock_rules_manager_, IsRestricted(_, _))
.WillRepeatedly(testing::Return(DlpRulesManager::Level::kAllow));
}
void SetupReporting() {
SetupDlpRulesManager();
// Set up mock report queue.
SetReportQueueForReportingManager(helper_.GetReportingManager(), events_);
}
void CheckEvents(DlpRulesManager::Restriction restriction,
DlpRulesManager::Level level,
size_t count) {
EXPECT_EQ(events_.size(), count);
for (int i = 0; i < count; ++i) {
EXPECT_THAT(events_[i], IsDlpPolicyEvent(CreateDlpPolicyEvent(
kSrcPattern, restriction, level)));
}
}
protected:
DlpContentManagerTestHelper helper_;
base::HistogramTester histogram_tester_;
MockDlpRulesManager* mock_rules_manager_;
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::vector<DlpPolicyEvent> events_;
};
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsRestricted) {
SetupReporting();
DlpContentManager* manager = helper_.GetContentManager();
ui_test_utils::NavigateToURL(browser(), GURL("https://example.com"));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
ScreenshotArea fullscreen = ScreenshotArea::CreateForAllRootWindows();
ScreenshotArea window =
ScreenshotArea::CreateForWindow(web_contents->GetNativeView());
const gfx::Rect web_contents_rect = web_contents->GetContainerBounds();
gfx::Rect out_rect(web_contents_rect);
out_rect.Offset(web_contents_rect.width(), web_contents_rect.height());
gfx::Rect in_rect(web_contents_rect);
in_rect.Offset(web_contents_rect.width() / 2, web_contents_rect.height() / 2);
ScreenshotArea partial_out =
ScreenshotArea::CreateForPartialWindow(root_window, out_rect);
ScreenshotArea partial_in =
ScreenshotArea::CreateForPartialWindow(root_window, in_rect);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 0);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 4);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 0u);
helper_.ChangeConfidentiality(web_contents, kScreenshotRestricted);
EXPECT_TRUE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_TRUE(manager->IsScreenshotRestricted(window));
EXPECT_TRUE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 3);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 5);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 3u);
web_contents->WasHidden();
helper_.ChangeVisibility(web_contents);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_TRUE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 4);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 8);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 4u);
web_contents->WasShown();
helper_.ChangeVisibility(web_contents);
EXPECT_TRUE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_TRUE(manager->IsScreenshotRestricted(window));
EXPECT_TRUE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 7);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 9);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 7u);
helper_.DestroyWebContents(web_contents);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 7);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 12);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 7u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsReported) {
SetupReporting();
DlpContentManager* manager = helper_.GetContentManager();
ui_test_utils::NavigateToURL(browser(), GURL("https://example.com"));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
ScreenshotArea fullscreen = ScreenshotArea::CreateForAllRootWindows();
ScreenshotArea window =
ScreenshotArea::CreateForWindow(web_contents->GetNativeView());
const gfx::Rect web_contents_rect = web_contents->GetContainerBounds();
gfx::Rect out_rect(web_contents_rect);
out_rect.Offset(web_contents_rect.width(), web_contents_rect.height());
gfx::Rect in_rect(web_contents_rect);
in_rect.Offset(web_contents_rect.width() / 2, web_contents_rect.height() / 2);
ScreenshotArea partial_out =
ScreenshotArea::CreateForPartialWindow(root_window, out_rect);
ScreenshotArea partial_in =
ScreenshotArea::CreateForPartialWindow(root_window, in_rect);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 0u);
helper_.ChangeConfidentiality(web_contents, kScreenshotReported);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 3u);
web_contents->WasHidden();
helper_.ChangeVisibility(web_contents);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 4u);
web_contents->WasShown();
helper_.ChangeVisibility(web_contents);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(window));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 7u);
helper_.DestroyWebContents(web_contents);
EXPECT_FALSE(manager->IsScreenshotRestricted(fullscreen));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_in));
EXPECT_FALSE(manager->IsScreenshotRestricted(partial_out));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, true, 0);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenshotBlockedUMA, false, 19);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 7u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
VideoCaptureStoppedWhenConfidentialWindowResized) {
SetupReporting();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
// Open first browser window.
Browser* browser1 = browser();
chrome::NewTab(browser1);
ui_test_utils::NavigateToURL(browser1, GURL("https://example.com"));
content::WebContents* web_contents1 =
browser1->tab_strip_model()->GetActiveWebContents();
// Open second browser window.
Browser* browser2 =
Browser::Create(Browser::CreateParams(browser()->profile(), true));
chrome::NewTab(browser2);
ui_test_utils::NavigateToURL(browser2, GURL("https://google.com"));
// Resize browsers so that second window covers the first one.
// Browser window can't have width less than 500.
browser1->window()->SetBounds(gfx::Rect(100, 100, 500, 500));
browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
// Make first window content as confidential.
helper_.ChangeConfidentiality(web_contents1, kVideoCaptureRestricted);
// Start capture of the whole screen.
base::RunLoop run_loop;
auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get();
capture_mode_delegate->StartObservingRestrictedContent(
root_window, root_window->bounds(), run_loop.QuitClosure());
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 0u);
// Move first window with confidential content to make it visible.
browser1->window()->SetBounds(gfx::Rect(100, 100, 700, 700));
// Check that capture was requested to be stopped via callback.
run_loop.Run();
capture_mode_delegate->StopObservingRestrictedContent();
browser2->window()->Close();
histogram_tester_.ExpectUniqueSample(
GetDlpHistogramPrefix() + dlp::kVideoCaptureInterruptedUMA, true, 1);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 1u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, VideoCaptureReported) {
SetupReporting();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
// Open first browser window.
Browser* browser1 = browser();
chrome::NewTab(browser1);
ui_test_utils::NavigateToURL(browser1, GURL("https://example.com"));
content::WebContents* web_contents1 =
browser1->tab_strip_model()->GetActiveWebContents();
// Open second browser window.
Browser* browser2 =
Browser::Create(Browser::CreateParams(browser()->profile(), true));
chrome::NewTab(browser2);
ui_test_utils::NavigateToURL(browser2, GURL("https://google.com"));
// Resize browsers so that second window covers the first one.
// Browser window can't have width less than 500.
browser1->window()->SetBounds(gfx::Rect(100, 100, 500, 500));
browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
// Make first window content as confidential.
helper_.ChangeConfidentiality(web_contents1, kVideoCaptureReported);
// Start capture of the whole screen.
base::RunLoop run_loop;
auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get();
capture_mode_delegate->StartObservingRestrictedContent(
root_window, root_window->bounds(), base::BindOnce([] {
FAIL() << "Video capture stop callback shouldn't be called";
}));
// Move first window with confidential content to make it visible.
browser1->window()->SetBounds(gfx::Rect(100, 100, 700, 700));
// Check that capture was not requested to be stopped via callback.
run_loop.RunUntilIdle();
capture_mode_delegate->StopObservingRestrictedContent();
browser2->window()->Close();
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kVideoCaptureInterruptedUMA, true, 0);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kReport, 1u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
VideoCaptureStoppedWhenNonConfidentialWindowResized) {
SetupReporting();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
// Open first browser window.
Browser* browser1 = browser();
chrome::NewTab(browser1);
ui_test_utils::NavigateToURL(browser1, GURL("https://example.com"));
content::WebContents* web_contents1 =
browser1->tab_strip_model()->GetActiveWebContents();
// Open second browser window.
Browser* browser2 =
Browser::Create(Browser::CreateParams(browser()->profile(), true));
chrome::NewTab(browser2);
ui_test_utils::NavigateToURL(browser2, GURL("https://google.com"));
// Resize browsers so that second window covers the first one.
// Browser window can't have width less than 500.
browser1->window()->SetBounds(gfx::Rect(100, 100, 500, 500));
browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
// Make first window content as confidential.
helper_.ChangeConfidentiality(web_contents1, kVideoCaptureRestricted);
// Start capture of the whole screen.
base::RunLoop run_loop;
auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get();
capture_mode_delegate->StartObservingRestrictedContent(
root_window, root_window->bounds(), run_loop.QuitClosure());
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 0u);
// Move second window to make first window with confidential content visible.
browser2->window()->SetBounds(gfx::Rect(150, 150, 700, 700));
// Check that capture was requested to be stopped via callback.
run_loop.Run();
capture_mode_delegate->StopObservingRestrictedContent();
browser2->window()->Close();
histogram_tester_.ExpectUniqueSample(
GetDlpHistogramPrefix() + dlp::kVideoCaptureInterruptedUMA, true, 1);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 1u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
VideoCaptureNotStoppedWhenConfidentialWindowHidden) {
SetupReporting();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
// Open first browser window.
Browser* browser1 = browser();
chrome::NewTab(browser1);
ui_test_utils::NavigateToURL(browser1, GURL("https://example.com"));
content::WebContents* web_contents1 =
browser1->tab_strip_model()->GetActiveWebContents();
// Open second browser window.
Browser* browser2 =
Browser::Create(Browser::CreateParams(browser()->profile(), true));
chrome::NewTab(browser2);
ui_test_utils::NavigateToURL(browser2, GURL("https://google.com"));
// Resize browsers so that second window covers the first one.
// Browser window can't have width less than 500.
browser1->window()->SetBounds(gfx::Rect(100, 100, 500, 500));
browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
// Make first window content as confidential.
helper_.ChangeConfidentiality(web_contents1, kVideoCaptureRestricted);
// Start capture of the whole screen.
base::RunLoop run_loop;
auto* capture_mode_delegate = ChromeCaptureModeDelegate::Get();
capture_mode_delegate->StartObservingRestrictedContent(
root_window, root_window->bounds(), base::BindOnce([] {
FAIL() << "Video capture stop callback shouldn't be called";
}));
// Move first window, but keep confidential content hidden.
browser1->window()->SetBounds(gfx::Rect(150, 150, 500, 500));
// Check that capture was not requested to be stopped via callback.
run_loop.RunUntilIdle();
capture_mode_delegate->StopObservingRestrictedContent();
browser2->window()->Close();
histogram_tester_.ExpectTotalCount(
GetDlpHistogramPrefix() + dlp::kVideoCaptureInterruptedUMA, 0);
CheckEvents(DlpRulesManager::Restriction::kScreenshot,
DlpRulesManager::Level::kBlock, 0u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest,
ScreenCaptureNotification) {
SetupReporting();
NotificationDisplayServiceTester display_service_tester(browser()->profile());
DlpContentManager* manager = helper_.GetContentManager();
ui_test_utils::NavigateToURL(browser(), GURL("https://example.com"));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
aura::Window* root_window =
browser()->window()->GetNativeWindow()->GetRootWindow();
const auto media_id = content::DesktopMediaID::RegisterNativeWindow(
content::DesktopMediaID::TYPE_SCREEN, root_window);
manager->OnScreenCaptureStarted("label", {media_id}, u"example.com",
base::DoNothing());
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, true, 0);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 0);
helper_.ChangeConfidentiality(web_contents, kScreenShareRestricted);
CheckEvents(DlpRulesManager::Restriction::kScreenShare,
DlpRulesManager::Level::kBlock, 1u);
EXPECT_TRUE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 0);
helper_.ChangeConfidentiality(web_contents, kEmptyRestrictionSet);
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_TRUE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 1);
manager->OnScreenCaptureStopped("label", media_id);
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCapturePausedNotificationId));
EXPECT_FALSE(display_service_tester.GetNotification(
kScreenCaptureResumedNotificationId));
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, true, 1);
histogram_tester_.ExpectBucketCount(
GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 1);
CheckEvents(DlpRulesManager::Restriction::kScreenShare,
DlpRulesManager::Level::kBlock, 1u);
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, PrintingNotRestricted) {
// Set up mock report queue and mock rules manager.
SetupReporting();
ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
NotificationDisplayServiceTester display_service_tester(browser()->profile());
EXPECT_FALSE(helper_.GetContentManager()->IsPrintingRestricted(web_contents));
// Start printing and check that there is no notification when printing is not
// restricted.
printing::StartPrint(web_contents,
/*print_renderer=*/mojo::NullAssociatedRemote(),
/*print_preview_disabled=*/false,
/*print_only_selection=*/false);
EXPECT_FALSE(
display_service_tester.GetNotification(kPrintBlockedNotificationId));
CheckEvents(DlpRulesManager::Restriction::kPrinting,
DlpRulesManager::Level::kBlock, 0u);
}
class DlpContentManagerReportingBrowserTest
: public DlpContentManagerBrowserTest {
public:
// Sets up real report queue together with TestStorageModule
void SetupReportQueue() {
const std::string dm_token_ = "FAKE_DM_TOKEN";
const reporting::Destination destination_ =
reporting::Destination::UPLOAD_EVENTS;
storage_module_ =
base::MakeRefCounted<reporting::test::TestStorageModule>();
policy_check_callback_ =
base::BindRepeating(&testing::MockFunction<reporting::Status()>::Call,
base::Unretained(&mocked_policy_check_));
ON_CALL(mocked_policy_check_, Call())
.WillByDefault(testing::Return(reporting::Status::StatusOK()));
reporting::StatusOr<std::unique_ptr<reporting::ReportQueueConfiguration>>
config_result = reporting::ReportQueueConfiguration::Create(
dm_token_, destination_, policy_check_callback_);
ASSERT_TRUE(config_result.ok());
reporting::StatusOr<std::unique_ptr<reporting::ReportQueue>>
report_queue_result = reporting::ReportQueueImpl::Create(
std::move(config_result.ValueOrDie()), storage_module_);
ASSERT_TRUE(report_queue_result.ok());
helper_.GetReportingManager()->GetReportQueueSetter().Run(
std::move(report_queue_result.ValueOrDie()));
}
reporting::test::TestStorageModule* test_storage_module() const {
reporting::test::TestStorageModule* test_storage_module =
google::protobuf::down_cast<reporting::test::TestStorageModule*>(
storage_module_.get());
DCHECK(test_storage_module);
return test_storage_module;
}
void CheckRecord(DlpRulesManager::Restriction restriction,
DlpRulesManager::Level level,
reporting::Record record) {
DlpPolicyEvent event;
EXPECT_TRUE(event.ParseFromString(record.data()));
EXPECT_EQ(event.source().url(), kSrcPattern);
EXPECT_THAT(event, IsDlpPolicyEvent(CreateDlpPolicyEvent(
kSrcPattern, restriction, level)));
}
// Sets an action to execute when an event arrives to the report queue storage
// module.
void SetAddRecordCheck(DlpRulesManager::Restriction restriction,
DlpRulesManager::Level level,
int times) {
// TODO(jkopanski): Change to [=, this] when chrome code base is updated to
// C++20.
EXPECT_CALL(*test_storage_module(), AddRecord)
.Times(times)
.WillRepeatedly(testing::WithArgs<1, 2>(testing::Invoke(
[=](reporting::Record record,
base::OnceCallback<void(reporting::Status)> callback) {
CheckRecord(restriction, level, std::move(record));
std::move(callback).Run(reporting::Status::StatusOK());
})));
}
protected:
scoped_refptr<reporting::StorageModuleInterface> storage_module_;
testing::NiceMock<testing::MockFunction<reporting::Status()>>
mocked_policy_check_;
reporting::ReportQueueConfiguration::PolicyCheckCallback
policy_check_callback_;
};
IN_PROC_BROWSER_TEST_F(DlpContentManagerReportingBrowserTest,
PrintingRestricted) {
// Set up mock rules manager.
SetupDlpRulesManager();
// Set up real report queue.
SetupReportQueue();
// Sets an action to execute when an event arrives to a storage module.
SetAddRecordCheck(DlpRulesManager::Restriction::kPrinting,
DlpRulesManager::Level::kBlock, /*times=*/2);
ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
NotificationDisplayServiceTester display_service_tester(browser()->profile());
// No event should be emitted when there is no restriction.
EXPECT_FALSE(helper_.GetContentManager()->IsPrintingRestricted(web_contents));
// Set up printing restriction.
helper_.ChangeConfidentiality(web_contents, kPrintRestricted);
// Check that IsPrintingRestricted emitted an event.
EXPECT_TRUE(helper_.GetContentManager()->IsPrintingRestricted(web_contents));
printing::StartPrint(web_contents,
/*print_renderer=*/mojo::NullAssociatedRemote(),
/*print_preview_disabled=*/false,
/*print_only_selection=*/false);
// Check for notification about printing restriction.
EXPECT_TRUE(
display_service_tester.GetNotification(kPrintBlockedNotificationId));
}
IN_PROC_BROWSER_TEST_F(DlpContentManagerReportingBrowserTest,
PrintingReported) {
SetupDlpRulesManager();
SetupReportQueue();
SetAddRecordCheck(DlpRulesManager::Restriction::kPrinting,
DlpRulesManager::Level::kReport, /*times=*/2);
ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl));
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
NotificationDisplayServiceTester display_service_tester(browser()->profile());
// Set up printing restriction.
helper_.ChangeConfidentiality(web_contents, kPrintReported);
EXPECT_FALSE(helper_.GetContentManager()->IsPrintingRestricted(web_contents));
printing::StartPrint(web_contents,
/*print_renderer=*/mojo::NullAssociatedRemote(),
/*print_preview_disabled=*/false,
/*print_only_selection=*/false);
EXPECT_FALSE(
display_service_tester.GetNotification(kPrintBlockedNotificationId));
// TODO(crbug/1213872, jkopanski): A hack to make this test working on
// linux-chromeos-rel. For some reason, gtest calls RequestPrintPreview after
// the test fixture, which triggers a DLP reporting event. This happens only
// for linux-chromeos-rel build and in this PrintingReported test, does not
// occur in PrintingRestricted test.
helper_.ChangeConfidentiality(web_contents, kPrintAllowed);
}
class DlpContentManagerPolicyBrowserTest : public LoginPolicyTestBase {
public:
DlpContentManagerPolicyBrowserTest() = default;
void SetDlpRulesPolicy(const base::Value& rules) {
std::string json;
base::JSONWriter::Write(rules, &json);
base::DictionaryValue policy;
policy.SetKey(key::kDataLeakPreventionRulesList, base::Value(json));
user_policy_helper()->SetPolicyAndWait(
policy, /*recommended=*/base::DictionaryValue(),
ProfileManager::GetActiveUserProfile());
}
protected:
DlpContentManagerTestHelper helper_;
};
IN_PROC_BROWSER_TEST_F(DlpContentManagerPolicyBrowserTest,
GetRestrictionSetForURL) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
base::Value rules(base::Value::Type::LIST);
base::Value src_urls1(base::Value::Type::LIST);
src_urls1.Append(kUrl1);
base::Value restrictions1(base::Value::Type::LIST);
restrictions1.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kScreenshotRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #1", "Block", std::move(src_urls1),
/*dst_urls=*/base::Value(base::Value::Type::LIST),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions1)));
base::Value src_urls2(base::Value::Type::LIST);
src_urls2.Append(kUrl2);
base::Value restrictions2(base::Value::Type::LIST);
restrictions2.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kPrivacyScreenRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #2", "Block", std::move(src_urls2),
/*dst_urls=*/base::Value(base::Value::Type::LIST),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions2)));
base::Value src_urls3(base::Value::Type::LIST);
src_urls3.Append(kUrl3);
base::Value restrictions3(base::Value::Type::LIST);
restrictions3.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kPrintingRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #3", "Block", std::move(src_urls3),
/*dst_urls=*/base::Value(base::Value::Type::LIST),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions3)));
base::Value src_urls4(base::Value::Type::LIST);
src_urls4.Append(kUrl4);
base::Value restrictions4(base::Value::Type::LIST);
restrictions4.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kScreenShareRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #4", "Block", std::move(src_urls4),
/*dst_urls=*/base::Value(base::Value::Type::LIST),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions4)));
SetDlpRulesPolicy(rules);
DlpContentRestrictionSet screenshot_and_videocapture(kScreenshotRestricted);
screenshot_and_videocapture.SetRestriction(
DlpContentRestriction::kVideoCapture, DlpRulesManager::Level::kBlock,
GURL());
EXPECT_EQ(screenshot_and_videocapture,
helper_.GetRestrictionSetForURL(GURL(kUrl1)));
EXPECT_EQ(kPrivacyScreenEnforced,
helper_.GetRestrictionSetForURL(GURL(kUrl2)));
EXPECT_EQ(kPrintRestricted, helper_.GetRestrictionSetForURL(GURL(kUrl3)));
EXPECT_EQ(kScreenShareRestricted,
helper_.GetRestrictionSetForURL(GURL(kUrl4)));
EXPECT_EQ(DlpContentRestrictionSet(),
helper_.GetRestrictionSetForURL(GURL(kExampleUrl)));
}
} // namespace policy