Commit 9eb09ede authored by Sergey Poromov's avatar Sergey Poromov Committed by Commit Bot

DLP: Enforce screenshot restrictions in extensions API.

"tabs.captureVisibleTab" extensions API should respect the current Data Leak Prevention content restrictions on Chrome OS.

Bug: 1109723
Change-Id: I7d4fc2f3bcac466db3fbc0fc0f7fb35be25e8188
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2323357
Commit-Queue: Sergey Poromov <poromov@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796230}
parent d91344f9
......@@ -1698,12 +1698,13 @@ TabsCaptureVisibleTabFunction::TabsCaptureVisibleTabFunction()
: chrome_details_(this) {
}
bool TabsCaptureVisibleTabFunction::IsScreenshotEnabled() const {
bool TabsCaptureVisibleTabFunction::IsScreenshotEnabled(
content::WebContents* web_contents) const {
PrefService* service = chrome_details_.GetProfile()->GetPrefs();
if (service->GetBoolean(prefs::kDisableScreenshots)) {
return false;
}
return true;
return !tabs_util::IsScreenshotRestricted(web_contents);
}
bool TabsCaptureVisibleTabFunction::ClientAllowsTransparency() {
......
......@@ -236,7 +236,7 @@ class TabsCaptureVisibleTabFunction
content::WebContents* GetWebContentsForID(int window_id, std::string* error);
// extensions::WebContentsCaptureClient:
bool IsScreenshotEnabled() const override;
bool IsScreenshotEnabled(content::WebContents* web_contents) const override;
bool ClientAllowsTransparency() override;
void OnCaptureSuccess(const SkBitmap& bitmap) override;
void OnCaptureFailure(CaptureResult result) override;
......
......@@ -30,6 +30,7 @@
#if defined(OS_CHROMEOS)
#include "ash/public/cpp/window_pin_type.h"
#include "ash/public/cpp/window_properties.h"
#include "chrome/browser/chromeos/policy/dlp/mock_dlp_content_manager.h"
#endif
namespace extensions {
......@@ -601,6 +602,44 @@ TEST_F(TabsApiUnitTest, DontCreateTabsInLockedFullscreenMode) {
extension_function_test_utils::RunFunctionAndReturnError(
function.get(), "[{}]", browser(), api_test_utils::NONE));
}
// Ensure tabs.captureVisibleTab respects any Data Leak Prevention restrictions.
TEST_F(TabsApiUnitTest, ScreenshotsRestricted) {
// Setup the function and extension.
scoped_refptr<const Extension> extension = ExtensionBuilder("Screenshot")
.AddPermission("tabs")
.AddPermission("<all_urls>")
.Build();
auto function = base::MakeRefCounted<TabsCaptureVisibleTabFunction>();
function->set_extension(extension.get());
// Add a visible tab.
std::unique_ptr<content::WebContents> web_contents =
content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
content::WebContentsTester* web_contents_tester =
content::WebContentsTester::For(web_contents.get());
const GURL kGoogle("http://www.google.com");
web_contents_tester->NavigateAndCommit(kGoogle);
browser()->tab_strip_model()->AppendWebContents(std::move(web_contents),
/*foreground=*/true);
// Setup Data Leak Prevention restriction.
policy::MockDlpContentManager mock_dlp_content_manager;
policy::DlpContentManager::SetDlpContentManagerForTesting(
&mock_dlp_content_manager);
EXPECT_CALL(mock_dlp_content_manager, IsScreenshotRestricted(testing::_))
.Times(1)
.WillOnce(testing::Return(true));
// Run the function and check result.
std::string error = extension_function_test_utils::RunFunctionAndReturnError(
function.get(), "[{}]", browser(), api_test_utils::NONE);
EXPECT_EQ(tabs_constants::kScreenshotsDisabled, error);
// Clean up.
browser()->tab_strip_model()->CloseAllTabs();
policy::DlpContentManager::ResetDlpContentManagerForTesting();
}
#endif // defined(OS_CHROMEOS)
} // namespace extensions
......@@ -9,5 +9,9 @@ namespace tabs_util {
void SetLockedFullscreenState(Browser* browser, bool locked) {}
bool IsScreenshotRestricted(content::WebContents* web_contents) {
return false;
}
} // namespace tabs_util
} // namespace extensions
......@@ -11,6 +11,10 @@
class Browser;
namespace content {
class WebContents;
}
namespace extensions {
namespace tabs_util {
......@@ -18,6 +22,10 @@ namespace tabs_util {
// necessary adjustments.
void SetLockedFullscreenState(Browser* browser, bool locked);
// Checks whether screenshot of |web_contents| is restricted due to Data Leak
// Prevention policy.
bool IsScreenshotRestricted(content::WebContents* web_contents);
} // namespace tabs_util
} // namespace extensions
......
......@@ -12,11 +12,13 @@
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
#include "chrome/browser/chromeos/assistant/assistant_util.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_window.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "ui/aura/window.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_buffer.h"
......@@ -66,5 +68,10 @@ void SetLockedFullscreenState(Browser* browser, bool locked) {
}
}
bool IsScreenshotRestricted(content::WebContents* web_contents) {
return policy::DlpContentManager::Get()->IsScreenshotRestricted(
ScreenshotArea::CreateForWindow(web_contents->GetNativeView()));
}
} // namespace tabs_util
} // namespace extensions
......@@ -21,6 +21,7 @@
#include "chrome/browser/extensions/api/chrome_extensions_api_client.h"
#include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
#include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h"
#include "chrome/browser/extensions/api/tabs/tabs_util.h"
#include "chrome/browser/extensions/chrome_component_extension_resource_manager.h"
#include "chrome/browser/extensions/chrome_extension_host_delegate.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
......@@ -590,6 +591,11 @@ bool ChromeExtensionsBrowserClient::HasIsolatedStorage(
return extensions::util::HasIsolatedStorage(extension_id, context);
}
bool ChromeExtensionsBrowserClient::IsScreenshotRestricted(
content::WebContents* web_contents) const {
return tabs_util::IsScreenshotRestricted(web_contents);
}
// static
void ChromeExtensionsBrowserClient::SetMediaRouterAccessLoggerForTesting(
MediaRouterExtensionAccessLogger* media_router_access_logger) {
......
......@@ -158,6 +158,8 @@ class ChromeExtensionsBrowserClient : public ExtensionsBrowserClient {
const override;
bool HasIsolatedStorage(const std::string& extension_id,
content::BrowserContext* context) override;
bool IsScreenshotRestricted(
content::WebContents* web_contents) const override;
static void set_did_chrome_update_for_testing(bool did_update);
......
......@@ -21,6 +21,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/stop_find_action.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/guest_view/web_view/web_view_constants.h"
#include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h"
#include "extensions/common/api/web_view_internal.h"
......@@ -314,9 +315,9 @@ WebViewInternalCaptureVisibleRegionFunction::Run() {
return RespondNow(Error(GetErrorMessage(capture_result)));
}
bool WebViewInternalCaptureVisibleRegionFunction::IsScreenshotEnabled() const {
// TODO(wjmaclean): Is it ok to always return true here?
return true;
bool WebViewInternalCaptureVisibleRegionFunction::IsScreenshotEnabled(
content::WebContents* web_contents) const {
return !ExtensionsBrowserClient::Get()->IsScreenshotRestricted(web_contents);
}
bool WebViewInternalCaptureVisibleRegionFunction::ClientAllowsTransparency() {
......@@ -353,8 +354,7 @@ std::string WebViewInternalCaptureVisibleRegionFunction::GetErrorMessage(
reason_description = "view is invisible";
break;
case FAILURE_REASON_SCREEN_SHOTS_DISABLED:
NOTREACHED() << "WebViewInternalCaptureVisibleRegionFunction always have "
"screenshots enabled";
reason_description = "screenshot has been disabled";
break;
case OK:
NOTREACHED()
......
......@@ -14,6 +14,10 @@
#include "extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
namespace content {
class WebContents;
}
// WARNING: WebViewInternal could be loaded in an unblessed context, thus any
// new APIs must extend WebViewInternalExtensionFunction or
// WebViewInternalExecuteCodeFunction which do a process ID check to prevent
......@@ -47,7 +51,7 @@ class WebViewInternalCaptureVisibleRegionFunction
private:
// extensions::WebContentsCaptureClient:
bool IsScreenshotEnabled() const override;
bool IsScreenshotEnabled(content::WebContents* web_contents) const override;
bool ClientAllowsTransparency() override;
void OnCaptureSuccess(const SkBitmap& bitmap) override;
void OnCaptureFailure(CaptureResult result) override;
......
......@@ -34,7 +34,7 @@ WebContentsCaptureClient::CaptureResult WebContentsCaptureClient::CaptureAsync(
if (!view)
return FAILURE_REASON_VIEW_INVISIBLE;
if (!IsScreenshotEnabled())
if (!IsScreenshotEnabled(web_contents))
return FAILURE_REASON_SCREEN_SHOTS_DISABLED;
// The default format and quality setting used when encoding jpegs.
......
......@@ -26,7 +26,8 @@ class WebContentsCaptureClient {
protected:
virtual ~WebContentsCaptureClient() {}
virtual bool IsScreenshotEnabled() const = 0;
virtual bool IsScreenshotEnabled(
content::WebContents* web_contents) const = 0;
virtual bool ClientAllowsTransparency() = 0;
enum CaptureResult {
......
......@@ -124,4 +124,9 @@ bool ExtensionsBrowserClient::HasIsolatedStorage(
return false;
}
bool ExtensionsBrowserClient::IsScreenshotRestricted(
content::WebContents* web_contents) const {
return false;
}
} // namespace extensions
......@@ -364,6 +364,10 @@ class ExtensionsBrowserClient {
virtual bool HasIsolatedStorage(const std::string& extension_id,
content::BrowserContext* context);
// Returns whether screenshot of |web_contents| is restricted due to Data Leak
// Protection policy.
virtual bool IsScreenshotRestricted(content::WebContents* web_contents) const;
private:
std::vector<std::unique_ptr<ExtensionsBrowserAPIProvider>> providers_;
......
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