Commit d9732ad0 authored by Ramin Halavati's avatar Ramin Halavati Committed by Commit Bot

Update ContentSettingsService access to incognito profile.

ContentSettingsService handles incognito mode requests internally, so
a flag is set to redirect incognito mode requests to the original
profile.
Also, in Set Content Settings API, incorrect use of include_incognito()
function instead of IsIncognitoEnabled() is corrected.
Two tests are added to check that all settings written in incognito
are applied and do not affect regular mode, and incognito settings
cannot be modified from regular mode.

Bug: 832697
Bug: 845845
Change-Id: I6d65f824e3e3ca2fbd218ed0bf5af1ddc15c87ef
Reviewed-on: https://chromium-review.googlesource.com/1061853
Commit-Queue: Ramin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#561811}
Reviewed-on: https://chromium-review.googlesource.com/1074651
Cr-Commit-Position: refs/heads/master@{#562817}
parent 74d5bcb4
......@@ -35,6 +35,7 @@
#include "content/public/browser/plugin_service.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/browser/extension_prefs_scope.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/error_utils.h"
using content::BrowserThread;
......@@ -252,9 +253,13 @@ ContentSettingsContentSettingSetFunction::Run() {
}
if (incognito) {
// Regular profiles can't access incognito unless include_incognito is true.
if (!browser_context()->IsOffTheRecord() && !include_incognito())
// Regular profiles can't access incognito unless the extension is allowed
// to run in incognito contexts.
if (!browser_context()->IsOffTheRecord() &&
!extensions::util::IsIncognitoEnabled(extension_id(),
browser_context())) {
return RespondNow(Error(pref_keys::kIncognitoErrorMessage));
}
} else {
// Incognito profiles can't access regular mode ever, they only exist in
// split mode.
......
......@@ -62,6 +62,9 @@ class ExtensionContentSettingsApiTest : public ExtensionApiTest {
ExtensionApiTest::TearDownOnMainThread();
}
// Override to let the test normally run on Windows Debug.
bool ExtensionSubtestsAreSkipped() override { return false; }
protected:
void CheckContentSettingsSet() {
HostContentSettingsMap* map =
......@@ -217,6 +220,43 @@ class ExtensionContentSettingsApiTest : public ExtensionApiTest {
url, url, CONTENT_SETTINGS_TYPE_AUTOPLAY, std::string()));
}
// Returns a snapshot of content settings for a given URL.
std::vector<int> GetContentSettingsSnapshot(const GURL& url) {
std::vector<int> content_settings;
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile_);
content_settings::CookieSettings* cookie_settings =
CookieSettingsFactory::GetForProfile(profile_).get();
content_settings.push_back(
cookie_settings->IsCookieAccessAllowed(url, url));
content_settings.push_back(cookie_settings->IsCookieSessionOnly(url));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_IMAGES, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_POPUPS, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_PPAPI_BROKER, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, std::string()));
content_settings.push_back(map->GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_AUTOPLAY, std::string()));
return content_settings;
}
private:
Profile* profile_;
std::unique_ptr<ScopedKeepAlive> keep_alive_;
......@@ -285,4 +325,41 @@ IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest,
EXPECT_TRUE(RunExtensionSubtest(kExtensionPath, "test.html")) << message_;
}
// Tests if changing permissions in incognito mode keeps the previous state of
// regular mode.
IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest, IncognitoIsolation) {
GURL url("http://www.example.com");
// Record previous state of content settings.
std::vector<int> content_settings_before = GetContentSettingsSnapshot(url);
// Run extension, set all permissions to allow, and check if they are changed.
EXPECT_TRUE(RunExtensionSubtest("content_settings/incognitoisolation",
"test.html?allow",
kFlagUseIncognito | kFlagEnableIncognito))
<< message_;
// Get content settings after running extension to ensure nothing is changed.
std::vector<int> content_settings_after = GetContentSettingsSnapshot(url);
EXPECT_EQ(content_settings_before, content_settings_after);
// Run extension, set all permissions to block, and check if they are changed.
EXPECT_TRUE(RunExtensionSubtest("content_settings/incognitoisolation",
"test.html?block",
kFlagUseIncognito | kFlagEnableIncognito))
<< message_;
// Get content settings after running extension to ensure nothing is changed.
content_settings_after = GetContentSettingsSnapshot(url);
EXPECT_EQ(content_settings_before, content_settings_after);
}
// Tests if changing incognito mode permissions in regular profile are rejected.
IN_PROC_BROWSER_TEST_F(ExtensionContentSettingsApiTest,
IncognitoNotAllowedInRegular) {
EXPECT_FALSE(RunExtensionSubtest("content_settings/incognitoisolation",
"test.html?allow"))
<< message_;
}
} // namespace extensions
......@@ -48,6 +48,7 @@ class ContentSettingsService : public BrowserContextKeyedAPI,
friend class BrowserContextKeyedAPIFactory<ContentSettingsService>;
// BrowserContextKeyedAPI implementation.
static const bool kServiceRedirectedInIncognito = true;
static const char* service_name() { return "ContentSettingsService"; }
scoped_refptr<ContentSettingsStore> content_settings_store_;
......
......@@ -111,7 +111,7 @@ class ExtensionApiTest : public ExtensionBrowserTest {
// RunExtensionSubtest, you may. For example, if a test calls
// RunExtensionSubtest then asserts that the Extension was installed, it will
// fail on win debug builds.
bool ExtensionSubtestsAreSkipped();
virtual bool ExtensionSubtestsAreSkipped();
// If not empty, Load |extension_name|, load |page_url| and wait for pass /
// fail notification from the extension API on the page. Note that if
......
{
"name" : "Content Settings API Test Extension",
"version" : "0.1",
"manifest_version": 2,
"description" : "Sets and checks content settings permissions for incognito.",
"incognito": "split",
"permissions": [ "contentSettings" ]
}
<!--
* Copyright 2018 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.
-->
<script src="test.js"></script>
\ No newline at end of file
// Copyright 2018 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.
// Content settings API test.
// Run with browser_tests:
// --gtest_filter=ExtensionContentSettingsApiTest.Incognito*
//
// Arguments: [Permission]
// Example Arguments: "?allow"
'use strict';
var cs = chrome.contentSettings;
var queryString = window.location.search;
var givenPermission = queryString[0] === '?' ? queryString.substr(1)
: queryString;
var settings = [
'cookies',
'images',
'javascript',
'plugins',
'popups',
'location',
'notifications',
'microphone',
'camera',
'unsandboxedPlugins',
'automaticDownloads'
];
function expect(expected, message) {
return chrome.test.callbackPass(function(value) {
chrome.test.assertEq(expected, value, message);
});
}
chrome.test.runTests([
function setContentSettings() {
settings.forEach(function(type) {
cs[type].set({
'primaryPattern': 'http://*.example.com/*',
'secondaryPattern': 'http://*.example.com/*',
'setting': givenPermission,
'scope': 'incognito_session_only'
}, chrome.test.callbackPass());
});
},
function getContentSettings() {
settings.forEach(function(type) {
var message = 'Setting for ' + type + ' should be ' + givenPermission;
cs[type].get({
'primaryUrl': 'http://www.example.com',
'secondaryUrl': 'http://www.example.com'
}, expect({'setting':givenPermission}, message));
});
},
]);
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