blob: f33a2a9b701bd8e7f70636abed1028b2ab0a6cd3 [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 <memory>
#include <string>
#include "ash/shell.h"
#include "base/json/json_writer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/ash/crostini/crostini_manager.h"
#include "chrome/browser/ash/crostini/crostini_util.h"
#include "chrome/browser/ash/crostini/fake_crostini_features.h"
#include "chrome/browser/ash/policy/core/user_policy_test_helper.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_policy_constants.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_impl.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h"
#include "chrome/browser/chromeos/policy/login/login_policy_test_base.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
#include "url/origin.h"
namespace policy {
namespace {
constexpr char kClipboardText1[] = "Hello World";
constexpr char16_t kClipboardText116[] = u"Hello World";
constexpr char16_t kClipboardText2[] = u"abcdef";
constexpr char kMailUrl[] = "https://mail.google.com";
constexpr char kDocsUrl[] = "https://docs.google.com";
constexpr char kExampleUrl[] = "https://example.com";
class FakeClipboardNotifier : public DlpClipboardNotifier {
public:
views::Widget* GetWidget() { return widget_.get(); }
void ProceedPressed(const ui::DataTransferEndpoint& data_dst) {
DlpClipboardNotifier::ProceedPressed(data_dst, GetWidget());
}
void BlinkProceedPressed(const ui::DataTransferEndpoint& data_dst) {
DlpClipboardNotifier::BlinkProceedPressed(data_dst, GetWidget());
}
void CancelWarningPressed(const ui::DataTransferEndpoint& data_dst) {
DlpClipboardNotifier::CancelWarningPressed(data_dst, GetWidget());
}
};
class FakeDlpController : public DataTransferDlpController,
public views::WidgetObserver {
public:
FakeDlpController(const DlpRulesManager& dlp_rules_manager,
FakeClipboardNotifier* helper)
: DataTransferDlpController(dlp_rules_manager), helper_(helper) {
DCHECK(helper);
}
~FakeDlpController() {
if (widget_ && widget_->HasObserver(this)) {
widget_->RemoveObserver(this);
}
}
void NotifyBlockedPaste(
const ui::DataTransferEndpoint* const data_src,
const ui::DataTransferEndpoint* const data_dst) override {
helper_->NotifyBlockedAction(data_src, data_dst);
}
void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
const ui::DataTransferEndpoint* const data_dst) override {
helper_->WarnOnPaste(data_src, data_dst);
}
void SetBlinkQuitCallback(base::RepeatingClosure cb) {
blink_quit_cb_ = std::move(cb);
}
void WarnOnBlinkPaste(const ui::DataTransferEndpoint* const data_src,
const ui::DataTransferEndpoint* const data_dst,
content::WebContents* web_contents,
base::OnceCallback<void(bool)> paste_cb) override {
blink_data_dst_.emplace(*data_dst);
helper_->WarnOnBlinkPaste(data_src, data_dst, web_contents,
std::move(paste_cb));
std::move(blink_quit_cb_).Run();
}
bool ShouldPasteOnWarn(
const ui::DataTransferEndpoint* const data_dst) override {
return helper_->DidUserApproveDst(data_dst);
}
bool ObserveWidget() {
widget_ = helper_->GetWidget();
if (widget_ && !widget_->HasObserver(this)) {
widget_->AddObserver(this);
return true;
}
return false;
}
MOCK_METHOD1(OnWidgetClosing, void(views::Widget* widget));
views::Widget* widget_ = nullptr;
FakeClipboardNotifier* helper_ = nullptr;
absl::optional<ui::DataTransferEndpoint> blink_data_dst_;
base::RepeatingClosure blink_quit_cb_ = base::DoNothing();
};
class MockDlpRulesManager : public DlpRulesManagerImpl {
public:
explicit MockDlpRulesManager(PrefService* local_state)
: DlpRulesManagerImpl(local_state) {}
~MockDlpRulesManager() override = default;
};
void SetClipboardText(std::u16string text,
std::unique_ptr<ui::DataTransferEndpoint> source) {
ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste,
source ? std::move(source) : nullptr);
writer.WriteText(text);
}
// On Widget Closing, a task for NativeWidgetAura::CloseNow() gets posted. This
// task runs after the widget is destroyed which leads to a crash, that's why
// we need to flush the message loop.
void FlushMessageLoop() {
base::RunLoop run_loop;
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
run_loop.QuitClosure());
run_loop.Run();
}
} // namespace
class DataTransferDlpBrowserTest : public LoginPolicyTestBase {
public:
DataTransferDlpBrowserTest() = 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());
}
void SetupCrostini() {
crostini::FakeCrostiniFeatures crostini_features;
crostini_features.set_is_allowed_now(true);
crostini_features.set_enabled(true);
// Setup CrostiniManager for testing.
crostini::CrostiniManager* crostini_manager =
crostini::CrostiniManager::GetForProfile(GetProfileForActiveUser());
crostini_manager->set_skip_restart_for_testing();
crostini_manager->AddRunningVmForTesting(crostini::kCrostiniDefaultVmName);
crostini_manager->AddRunningContainerForTesting(
crostini::kCrostiniDefaultVmName,
crostini::ContainerInfo(crostini::kCrostiniDefaultContainerName,
"testuser", "/home/testuser",
"PLACEHOLDER_IP"));
}
void SetupTextfield() {
// Create a widget containing a single, focusable textfield.
widget_ = std::make_unique<views::Widget>();
views::Widget::InitParams params;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
widget_->Init(std::move(params));
textfield_ = widget_->SetContentsView(std::make_unique<views::Textfield>());
textfield_->SetAccessibleName(u"Textfield");
textfield_->SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
// Show the widget.
widget_->SetBounds(gfx::Rect(0, 0, 100, 100));
widget_->Show();
ASSERT_TRUE(widget_->IsActive());
// Focus the textfield and confirm initial state.
textfield_->RequestFocus();
ASSERT_TRUE(textfield_->HasFocus());
ASSERT_TRUE(textfield_->GetText().empty());
event_generator_ = std::make_unique<ui::test::EventGenerator>(
ash::Shell::GetPrimaryRootWindow());
}
std::unique_ptr<ui::test::EventGenerator> event_generator_;
std::unique_ptr<views::Widget> widget_;
views::Textfield* textfield_ = nullptr;
};
// Flaky on MSan bots: http://crbug.com/1178328
#if defined(MEMORY_SANITIZER)
#define MAYBE_EmptyPolicy DISABLED_EmptyPolicy
#else
#define MAYBE_EmptyPolicy EmptyPolicy
#endif
IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, MAYBE_EmptyPolicy) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
SetClipboardText(kClipboardText116, nullptr);
ui::DataTransferEndpoint data_dst(
url::Origin::Create(GURL("https://google.com")));
std::u16string result;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst, &result);
EXPECT_EQ(kClipboardText116, result);
}
IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, BlockDestination) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
FakeClipboardNotifier helper;
FakeDlpController dlp_controller(
*DlpRulesManagerFactory::GetForPrimaryProfile(), &helper);
base::Value rules(base::Value::Type::LIST);
base::Value src_urls1(base::Value::Type::LIST);
src_urls1.Append(kMailUrl);
base::Value dst_urls1(base::Value::Type::LIST);
dst_urls1.Append("*");
base::Value restrictions1(base::Value::Type::LIST);
restrictions1.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kClipboardRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #1", "Block Gmail", std::move(src_urls1), std::move(dst_urls1),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions1)));
base::Value src_urls2(base::Value::Type::LIST);
src_urls2.Append(kMailUrl);
base::Value dst_urls2(base::Value::Type::LIST);
dst_urls2.Append(kDocsUrl);
base::Value restrictions2(base::Value::Type::LIST);
restrictions2.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kClipboardRestriction, dlp::kAllowLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #2", "Allow Gmail for work purposes", std::move(src_urls2),
std::move(dst_urls2),
/*dst_components=*/base::Value(base::Value::Type::LIST),
std::move(restrictions2)));
SetDlpRulesPolicy(std::move(rules));
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
ui::DataTransferEndpoint data_dst1(url::Origin::Create(GURL(kMailUrl)));
std::u16string result1;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst1, &result1);
EXPECT_EQ(kClipboardText116, result1);
ui::DataTransferEndpoint data_dst2(url::Origin::Create(GURL(kDocsUrl)));
std::u16string result2;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst2, &result2);
EXPECT_EQ(kClipboardText116, result2);
ui::DataTransferEndpoint data_dst3(url::Origin::Create(GURL(kExampleUrl)));
std::u16string result3;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst3, &result3);
EXPECT_EQ(std::u16string(), result3);
ASSERT_TRUE(dlp_controller.ObserveWidget());
EXPECT_CALL(dlp_controller, OnWidgetClosing);
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kExampleUrl))));
testing::Mock::VerifyAndClearExpectations(&helper);
ui::DataTransferEndpoint data_dst4(url::Origin::Create(GURL(kMailUrl)));
std::u16string result4;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst1, &result4);
EXPECT_EQ(kClipboardText116, result4);
FlushMessageLoop();
}
// Flaky on MSan bots: http://crbug.com/1178328
#if defined(MEMORY_SANITIZER)
#define MAYBE_BlockComponent DISABLED_BlockComponent
#else
#define MAYBE_BlockComponent BlockComponent
#endif
IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, MAYBE_BlockComponent) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
SetupCrostini();
base::Value rules(base::Value::Type::LIST);
base::Value src_urls(base::Value::Type::LIST);
src_urls.Append(kMailUrl);
base::Value dst_components(base::Value::Type::LIST);
dst_components.Append(dlp::kArc);
dst_components.Append(dlp::kCrostini);
base::Value restrictions(base::Value::Type::LIST);
restrictions.Append(dlp_test_util::CreateRestrictionWithLevel(
dlp::kClipboardRestriction, dlp::kBlockLevel));
rules.Append(dlp_test_util::CreateRule(
"rule #1", "Block Gmail", std::move(src_urls),
/*dst_urls=*/base::Value(base::Value::Type::LIST),
std::move(dst_components), std::move(restrictions)));
SetDlpRulesPolicy(rules);
{
ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
writer.WriteText(kClipboardText116);
}
ui::DataTransferEndpoint data_dst1(ui::EndpointType::kDefault);
std::u16string result1;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst1, &result1);
EXPECT_EQ(kClipboardText116, result1);
ui::DataTransferEndpoint data_dst2(ui::EndpointType::kArc);
std::u16string result2;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst2, &result2);
EXPECT_EQ(std::u16string(), result2);
ui::DataTransferEndpoint data_dst3(ui::EndpointType::kCrostini);
std::u16string result3;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &data_dst3, &result3);
EXPECT_EQ(std::u16string(), result3);
}
// Flaky on MSan bots: http://crbug.com/1178328
#if defined(MEMORY_SANITIZER)
#define MAYBE_WarnDestination DISABLED_WarnDestination
#else
#define MAYBE_WarnDestination WarnDestination
#endif
IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, MAYBE_WarnDestination) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
FakeClipboardNotifier helper;
FakeDlpController dlp_controller(
*DlpRulesManagerFactory::GetForPrimaryProfile(), &helper);
{
ListPrefUpdate update(g_browser_process->local_state(),
policy_prefs::kDlpRulesList);
base::Value rule(base::Value::Type::DICTIONARY);
base::Value src_urls(base::Value::Type::DICTIONARY);
base::Value src_urls_list(base::Value::Type::LIST);
src_urls_list.Append(base::Value(kMailUrl));
src_urls.SetKey("urls", std::move(src_urls_list));
rule.SetKey("sources", std::move(src_urls));
base::Value dst_urls(base::Value::Type::DICTIONARY);
base::Value dst_urls_list(base::Value::Type::LIST);
dst_urls_list.Append(base::Value("*"));
dst_urls.SetKey("urls", std::move(dst_urls_list));
rule.SetKey("destinations", std::move(dst_urls));
base::Value restrictions(base::Value::Type::DICTIONARY);
base::Value restrictions_list(base::Value::Type::LIST);
base::Value class_level_dict(base::Value::Type::DICTIONARY);
class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
class_level_dict.SetKey("level", base::Value("WARN"));
restrictions_list.Append(std::move(class_level_dict));
rule.SetKey("restrictions", std::move(restrictions_list));
update->Append(std::move(rule));
}
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
SetupTextfield();
// Initiate a paste on textfield_.
event_generator_->PressKey(ui::VKEY_V, ui::EF_CONTROL_DOWN);
event_generator_->ReleaseKey(ui::VKEY_V, ui::EF_CONTROL_DOWN);
EXPECT_EQ("", base::UTF16ToUTF8(textfield_->GetText()));
ASSERT_TRUE(dlp_controller.ObserveWidget());
// Accept warning.
EXPECT_CALL(dlp_controller, OnWidgetClosing);
ui::DataTransferEndpoint default_endpoint(ui::EndpointType::kDefault);
helper.ProceedPressed(default_endpoint);
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
EXPECT_EQ(kClipboardText116, textfield_->GetText());
SetClipboardText(kClipboardText2, std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
// Initiate a paste on textfield_.
textfield_->SetText(std::u16string());
textfield_->RequestFocus();
event_generator_->PressKey(ui::VKEY_V, ui::EF_CONTROL_DOWN);
event_generator_->ReleaseKey(ui::VKEY_V, ui::EF_CONTROL_DOWN);
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
EXPECT_EQ("", base::UTF16ToUTF8(textfield_->GetText()));
ASSERT_TRUE(dlp_controller.ObserveWidget());
// Initiate a paste on nullptr data_dst.
std::u16string result;
EXPECT_CALL(dlp_controller, OnWidgetClosing);
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, nullptr, &result);
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
EXPECT_EQ(std::u16string(), result);
ASSERT_TRUE(dlp_controller.ObserveWidget());
EXPECT_CALL(dlp_controller, OnWidgetClosing);
SetClipboardText(kClipboardText2, std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kDocsUrl))));
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
FlushMessageLoop();
}
// Flaky on MSan bots: http://crbug.com/1178328
#if defined(MEMORY_SANITIZER)
#define MAYBE_WarnComponent DISABLED_WarnComponent
#else
#define MAYBE_WarnComponent WarnComponent
#endif
IN_PROC_BROWSER_TEST_F(DataTransferDlpBrowserTest, MAYBE_WarnComponent) {
SkipToLoginScreen();
LogIn(kAccountId, kAccountPassword, kEmptyServices);
SetupCrostini();
{
ListPrefUpdate update(g_browser_process->local_state(),
policy_prefs::kDlpRulesList);
base::Value rule(base::Value::Type::DICTIONARY);
base::Value src_urls(base::Value::Type::DICTIONARY);
base::Value src_urls_list(base::Value::Type::LIST);
src_urls_list.Append(base::Value(kMailUrl));
src_urls.SetKey("urls", std::move(src_urls_list));
rule.SetKey("sources", std::move(src_urls));
base::Value dst_components(base::Value::Type::DICTIONARY);
base::Value dst_components_list(base::Value::Type::LIST);
dst_components_list.Append(base::Value("ARC"));
dst_components_list.Append(base::Value("CROSTINI"));
dst_components_list.Append(base::Value("PLUGIN_VM"));
dst_components.SetKey("components", std::move(dst_components_list));
rule.SetKey("destinations", std::move(dst_components));
base::Value restrictions(base::Value::Type::DICTIONARY);
base::Value restrictions_list(base::Value::Type::LIST);
base::Value class_level_dict(base::Value::Type::DICTIONARY);
class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
class_level_dict.SetKey("level", base::Value("WARN"));
restrictions_list.Append(std::move(class_level_dict));
rule.SetKey("restrictions", std::move(restrictions_list));
update->Append(std::move(rule));
}
{
ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
writer.WriteText(kClipboardText116);
}
ui::DataTransferEndpoint arc_endpoint(ui::EndpointType::kArc);
std::u16string result;
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &arc_endpoint, &result);
EXPECT_EQ(kClipboardText116, result);
ui::DataTransferEndpoint crostini_endpoint(ui::EndpointType::kCrostini);
result.clear();
ui::Clipboard::GetForCurrentThread()->ReadText(
ui::ClipboardBuffer::kCopyPaste, &crostini_endpoint, &result);
EXPECT_EQ(kClipboardText116, result);
}
class DataTransferDlpBlinkBrowserTest : public InProcessBrowserTest {
public:
DataTransferDlpBlinkBrowserTest() = default;
DataTransferDlpBlinkBrowserTest(const DataTransferDlpBlinkBrowserTest&) =
delete;
DataTransferDlpBlinkBrowserTest& operator=(
const DataTransferDlpBlinkBrowserTest&) = delete;
~DataTransferDlpBlinkBrowserTest() override = default;
protected:
content::WebContents* GetActiveWebContents() {
return browser()->tab_strip_model()->GetActiveWebContents();
}
::testing::AssertionResult ExecJs(content::WebContents* web_contents,
const std::string& code) {
return content::ExecJs(web_contents, code,
content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
/*world_id=*/1);
}
content::EvalJsResult EvalJs(content::WebContents* web_contents,
const std::string& code) {
return content::EvalJs(web_contents, code,
content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
/*world_id=*/1);
}
};
// Disabled due to flakiness: crbug.com/1220328
IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest,
DISABLED_ProceedOnWarn) {
ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/title1.html")));
MockDlpRulesManager rules_manager(g_browser_process->local_state());
FakeClipboardNotifier helper;
FakeDlpController dlp_controller(rules_manager, &helper);
{
ListPrefUpdate update(g_browser_process->local_state(),
policy_prefs::kDlpRulesList);
base::Value rule(base::Value::Type::DICTIONARY);
base::Value src_urls(base::Value::Type::DICTIONARY);
base::Value src_urls_list(base::Value::Type::LIST);
src_urls_list.Append(base::Value(kMailUrl));
src_urls.SetKey("urls", std::move(src_urls_list));
rule.SetKey("sources", std::move(src_urls));
base::Value dst_urls(base::Value::Type::DICTIONARY);
base::Value dst_urls_list(base::Value::Type::LIST);
dst_urls_list.Append(base::Value("*"));
dst_urls.SetKey("urls", std::move(dst_urls_list));
rule.SetKey("destinations", std::move(dst_urls));
base::Value restrictions(base::Value::Type::DICTIONARY);
base::Value restrictions_list(base::Value::Type::LIST);
base::Value class_level_dict(base::Value::Type::DICTIONARY);
class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
class_level_dict.SetKey("level", base::Value("WARN"));
restrictions_list.Append(std::move(class_level_dict));
rule.SetKey("restrictions", std::move(restrictions_list));
update->Append(std::move(rule));
}
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
EXPECT_TRUE(
ExecJs(GetActiveWebContents(),
"var p = new Promise((resolve, reject) => {"
" window.document.onpaste = async (event) => {"
" if (event.clipboardData.items.length !== 1) {"
" reject('There were ' + event.clipboardData.items.length +"
" ' clipboard items. Expected 1.');"
" }"
" if (event.clipboardData.items[0].kind != 'string') {"
" reject('The clipboard item was of kind: ' +"
" event.clipboardData.items[0].kind + '. Expected ' +"
" 'string.');"
" }"
" const clipboardDataItem = event.clipboardData.items[0];"
" clipboardDataItem.getAsString((clipboardDataText)=> {"
" resolve(clipboardDataText);});"
" };"
"});"));
content::UpdateUserActivationStateInterceptor user_activation_interceptor;
user_activation_interceptor.Init(GetActiveWebContents()->GetMainFrame());
user_activation_interceptor.UpdateUserActivationState(
blink::mojom::UserActivationUpdateType::kNotifyActivation,
blink::mojom::UserActivationNotificationType::kTest);
// Send paste event and wait till the notification is displayed.
base::RunLoop run_loop;
dlp_controller.SetBlinkQuitCallback(run_loop.QuitClosure());
GetActiveWebContents()->Paste();
run_loop.Run();
ASSERT_TRUE(dlp_controller.ObserveWidget());
EXPECT_CALL(dlp_controller, OnWidgetClosing);
helper.BlinkProceedPressed(dlp_controller.blink_data_dst_.value());
EXPECT_EQ(kClipboardText1, EvalJs(GetActiveWebContents(), "p"));
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
}
// Disabled due to flakiness: crbug.com/1220328
IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest, DISABLED_CancelWarn) {
ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/title1.html")));
MockDlpRulesManager rules_manager(g_browser_process->local_state());
FakeClipboardNotifier helper;
FakeDlpController dlp_controller(rules_manager, &helper);
{
ListPrefUpdate update(g_browser_process->local_state(),
policy_prefs::kDlpRulesList);
base::Value rule(base::Value::Type::DICTIONARY);
base::Value src_urls(base::Value::Type::DICTIONARY);
base::Value src_urls_list(base::Value::Type::LIST);
src_urls_list.Append(base::Value(kMailUrl));
src_urls.SetKey("urls", std::move(src_urls_list));
rule.SetKey("sources", std::move(src_urls));
base::Value dst_urls(base::Value::Type::DICTIONARY);
base::Value dst_urls_list(base::Value::Type::LIST);
dst_urls_list.Append(base::Value("*"));
dst_urls.SetKey("urls", std::move(dst_urls_list));
rule.SetKey("destinations", std::move(dst_urls));
base::Value restrictions(base::Value::Type::DICTIONARY);
base::Value restrictions_list(base::Value::Type::LIST);
base::Value class_level_dict(base::Value::Type::DICTIONARY);
class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
class_level_dict.SetKey("level", base::Value("WARN"));
restrictions_list.Append(std::move(class_level_dict));
rule.SetKey("restrictions", std::move(restrictions_list));
update->Append(std::move(rule));
}
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
EXPECT_TRUE(
ExecJs(GetActiveWebContents(),
"var p = new Promise((resolve, reject) => {"
" window.document.onpaste = async (event) => {"
" if (event.clipboardData.items.length !== 1) {"
" reject('There were ' + event.clipboardData.items.length +"
" ' clipboard items. Expected 1.');"
" }"
" if (event.clipboardData.items[0].kind != 'string') {"
" reject('The clipboard item was of kind: ' +"
" event.clipboardData.items[0].kind + '. Expected ' +"
" 'string.');"
" }"
" const clipboardDataItem = event.clipboardData.items[0];"
" clipboardDataItem.getAsString((clipboardDataText)=> {"
" resolve(clipboardDataText);});"
" };"
"});"));
content::UpdateUserActivationStateInterceptor user_activation_interceptor;
user_activation_interceptor.Init(GetActiveWebContents()->GetMainFrame());
user_activation_interceptor.UpdateUserActivationState(
blink::mojom::UserActivationUpdateType::kNotifyActivation,
blink::mojom::UserActivationNotificationType::kTest);
// Send paste event and wait till the notification is displayed.
base::RunLoop run_loop;
dlp_controller.SetBlinkQuitCallback(run_loop.QuitClosure());
GetActiveWebContents()->Paste();
run_loop.Run();
ASSERT_TRUE(dlp_controller.ObserveWidget());
ASSERT_TRUE(dlp_controller.blink_data_dst_.has_value());
EXPECT_CALL(dlp_controller, OnWidgetClosing);
helper.CancelWarningPressed(dlp_controller.blink_data_dst_.value());
EXPECT_EQ("", EvalJs(GetActiveWebContents(), "p"));
testing::Mock::VerifyAndClearExpectations(&dlp_controller);
}
// Test case for crbug.com/1213143
// Disabled due to flakiness: crbug.com/1219981
IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest, DISABLED_Reporting) {
ASSERT_TRUE(embedded_test_server()->Start());
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/title1.html")));
MockDlpRulesManager rules_manager(g_browser_process->local_state());
FakeClipboardNotifier helper;
FakeDlpController dlp_controller(rules_manager, &helper);
{
ListPrefUpdate update(g_browser_process->local_state(),
policy_prefs::kDlpRulesList);
base::Value rule(base::Value::Type::DICTIONARY);
base::Value src_urls(base::Value::Type::DICTIONARY);
base::Value src_urls_list(base::Value::Type::LIST);
src_urls_list.Append(base::Value(kMailUrl));
src_urls.SetKey("urls", std::move(src_urls_list));
rule.SetKey("sources", std::move(src_urls));
base::Value dst_urls(base::Value::Type::DICTIONARY);
base::Value dst_urls_list(base::Value::Type::LIST);
dst_urls_list.Append(base::Value("*"));
dst_urls.SetKey("urls", std::move(dst_urls_list));
rule.SetKey("destinations", std::move(dst_urls));
base::Value restrictions(base::Value::Type::DICTIONARY);
base::Value restrictions_list(base::Value::Type::LIST);
base::Value class_level_dict(base::Value::Type::DICTIONARY);
class_level_dict.SetKey("class", base::Value("CLIPBOARD"));
class_level_dict.SetKey("level", base::Value("REPORT"));
restrictions_list.Append(std::move(class_level_dict));
rule.SetKey("restrictions", std::move(restrictions_list));
update->Append(std::move(rule));
}
SetClipboardText(kClipboardText116,
std::make_unique<ui::DataTransferEndpoint>(
url::Origin::Create(GURL(kMailUrl))));
EXPECT_TRUE(
ExecJs(GetActiveWebContents(),
"var p = new Promise((resolve, reject) => {"
" window.document.onpaste = async (event) => {"
" if (event.clipboardData.items.length !== 1) {"
" reject('There were ' + event.clipboardData.items.length +"
" ' clipboard items. Expected 1.');"
" }"
" if (event.clipboardData.items[0].kind != 'string') {"
" reject('The clipboard item was of kind: ' +"
" event.clipboardData.items[0].kind + '. Expected ' +"
" 'string.');"
" }"
" const clipboardDataItem = event.clipboardData.items[0];"
" clipboardDataItem.getAsString((clipboardDataText)=> {"
" resolve(clipboardDataText);});"
" };"
"});"));
content::UpdateUserActivationStateInterceptor user_activation_interceptor;
user_activation_interceptor.Init(GetActiveWebContents()->GetMainFrame());
user_activation_interceptor.UpdateUserActivationState(
blink::mojom::UserActivationUpdateType::kNotifyActivation,
blink::mojom::UserActivationNotificationType::kTest);
GetActiveWebContents()->Paste();
EXPECT_FALSE(dlp_controller.ObserveWidget());
EXPECT_EQ(kClipboardText1, EvalJs(GetActiveWebContents(), "p"));
}
} // namespace policy