Commit 66382a92 authored by mad@chromium.org's avatar mad@chromium.org

Add extension permissions for new settings override API.

Needed to create new class, mimicking SimpleAPIPermission, as opposed to inheriting from SetDisjunctionPermission, since we just needed to construct strings dynamically with extension properties.

BUG=306128

Review URL: https://codereview.chromium.org/55533003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233394 0039d316-1c4b-4281-b951-d872f2087c98
parent aab94691
...@@ -4394,7 +4394,7 @@ Make sure you do not expose any sensitive information. ...@@ -4394,7 +4394,7 @@ Make sure you do not expose any sensitive information.
Change your search settings to: <ph name="SEARCH_HOST">$1<ex>url.search.com</ex></ph> Change your search settings to: <ph name="SEARCH_HOST">$1<ex>url.search.com</ex></ph>
</message> </message>
<message name="IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE" desc="Permission string for home page override."> <message name="IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE" desc="Permission string for home page override.">
Change your home page to: <ph name="START_PAGE">$1<ex>home.page.com/home.html</ex></ph> Change your home page to: <ph name="HOME_PAGE">$1<ex>home.page.com/home.html</ex></ph>
</message> </message>
<message name="IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE" desc="Permission string for start page override."> <message name="IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE" desc="Permission string for start page override.">
Change your start page to: <ph name="START_PAGE">$1<ex>start.page.com/start.html</ex></ph> Change your start page to: <ph name="START_PAGE">$1<ex>start.page.com/start.html</ex></ph>
......
...@@ -256,6 +256,8 @@ ...@@ -256,6 +256,8 @@
'common/extensions/permissions/permissions_data.cc', 'common/extensions/permissions/permissions_data.cc',
'common/extensions/permissions/permissions_data.h', 'common/extensions/permissions/permissions_data.h',
'common/extensions/permissions/set_disjunction_permission.h', 'common/extensions/permissions/set_disjunction_permission.h',
'common/extensions/permissions/settings_override_permission.cc',
'common/extensions/permissions/settings_override_permission.h',
'common/extensions/permissions/socket_permission.cc', 'common/extensions/permissions/socket_permission.cc',
'common/extensions/permissions/socket_permission.h', 'common/extensions/permissions/socket_permission.h',
'common/extensions/permissions/socket_permission_data.cc', 'common/extensions/permissions/socket_permission_data.cc',
......
...@@ -1832,6 +1832,7 @@ ...@@ -1832,6 +1832,7 @@
'common/extensions/permissions/media_galleries_permission_unittest.cc', 'common/extensions/permissions/media_galleries_permission_unittest.cc',
'common/extensions/permissions/permission_set_unittest.cc', 'common/extensions/permissions/permission_set_unittest.cc',
'common/extensions/permissions/permissions_data_unittest.cc', 'common/extensions/permissions/permissions_data_unittest.cc',
'common/extensions/permissions/settings_override_permission_unittest.cc',
'common/extensions/permissions/socket_permission_unittest.cc', 'common/extensions/permissions/socket_permission_unittest.cc',
'common/extensions/permissions/usb_device_permission_unittest.cc', 'common/extensions/permissions/usb_device_permission_unittest.cc',
'common/extensions/sync_type_unittest.cc', 'common/extensions/sync_type_unittest.cc',
...@@ -2132,6 +2133,8 @@ ...@@ -2132,6 +2133,8 @@
['exclude', '^common/extensions/api/'], ['exclude', '^common/extensions/api/'],
['exclude', '^common/extensions/manifest_handlers/'], ['exclude', '^common/extensions/manifest_handlers/'],
['exclude', '^common/extensions/manifest_tests/'], ['exclude', '^common/extensions/manifest_tests/'],
# This test depends on manifest_tests.
['exclude', '^common/extensions/permissions/settings_override_permission_unittest.cc'],
], ],
'sources!': [ 'sources!': [
'browser/extensions/extension_context_menu_model_unittest.cc', 'browser/extensions/extension_context_menu_model_unittest.cc',
......
...@@ -4,15 +4,23 @@ ...@@ -4,15 +4,23 @@
#include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h" #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/extensions/permissions/settings_override_permission.h"
#include "extensions/common/error_utils.h" #include "extensions/common/error_utils.h"
#include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/api_permission_set.h"
#include "extensions/common/permissions/permissions_info.h"
#include "url/gurl.h"
using extensions::api::manifest_types::ChromeSettingsOverrides; using extensions::api::manifest_types::ChromeSettingsOverrides;
namespace extensions { namespace extensions {
namespace { namespace {
const char* kWwwPrefix = "www.";
scoped_ptr<GURL> CreateManifestURL(const std::string& url) { scoped_ptr<GURL> CreateManifestURL(const std::string& url) {
scoped_ptr<GURL> manifest_url(new GURL(url)); scoped_ptr<GURL> manifest_url(new GURL(url));
if (!manifest_url->is_valid() || if (!manifest_url->is_valid() ||
...@@ -54,6 +62,14 @@ std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides, ...@@ -54,6 +62,14 @@ std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides,
return urls; return urls;
} }
// A www. prefix is not informative and thus not worth the limited real estate
// in the permissions UI.
std::string RemoveWwwPrefix(const std::string& url) {
if (StartsWithASCII(url, kWwwPrefix, false))
return url.substr(strlen(kWwwPrefix));
return url;
}
} // namespace } // namespace
SettingsOverrides::SettingsOverrides() {} SettingsOverrides::SettingsOverrides() {}
...@@ -86,6 +102,27 @@ bool SettingsOverridesHandler::Parse(Extension* extension, string16* error) { ...@@ -86,6 +102,27 @@ bool SettingsOverridesHandler::Parse(Extension* extension, string16* error) {
*error = ASCIIToUTF16(manifest_errors::kInvalidEmptySettingsOverrides); *error = ASCIIToUTF16(manifest_errors::kInvalidEmptySettingsOverrides);
return false; return false;
} }
APIPermissionSet* permission_set =
PermissionsData::GetInitialAPIPermissions(extension);
DCHECK(permission_set);
if (info->search_engine) {
permission_set->insert(new SettingsOverrideAPIPermission(
PermissionsInfo::GetInstance()->GetByID(APIPermission::kSearchProvider),
RemoveWwwPrefix(CreateManifestURL(info->search_engine->search_url)->
GetOrigin().host())));
}
if (!info->startup_pages.empty()) {
permission_set->insert(new SettingsOverrideAPIPermission(
PermissionsInfo::GetInstance()->GetByID(APIPermission::kStartupPages),
// We only support one startup page even though the type of the manifest
// property is a list, only the first one is used.
RemoveWwwPrefix(info->startup_pages[0].GetContent())));
}
if (info->homepage) {
permission_set->insert(new SettingsOverrideAPIPermission(
PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage),
RemoveWwwPrefix(info->homepage.get()->GetContent())));
}
extension->SetManifestData(manifest_keys::kSettingsOverride, extension->SetManifestData(manifest_keys::kSettingsOverride,
info.release()); info.release());
return true; return true;
......
...@@ -347,6 +347,23 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() ...@@ -347,6 +347,23 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions()
{ APIPermission::kFullscreen, "fullscreen" }, { APIPermission::kFullscreen, "fullscreen" },
{ APIPermission::kAudio, "audio" }, { APIPermission::kAudio, "audio" },
{ APIPermission::kWebRtc, "webrtc" }, { APIPermission::kWebRtc, "webrtc" },
// Settings override permissions.
{ APIPermission::kHomepage, "homepage",
APIPermissionInfo::kFlagCannotBeOptional |
APIPermissionInfo::kFlagInternal,
IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE,
PermissionMessage::kHomepage },
{ APIPermission::kSearchProvider, "searchProvider",
APIPermissionInfo::kFlagCannotBeOptional |
APIPermissionInfo::kFlagInternal,
IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE,
PermissionMessage::kSearchProvider },
{ APIPermission::kStartupPages, "startupPages",
APIPermissionInfo::kFlagCannotBeOptional |
APIPermissionInfo::kFlagInternal,
IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE,
PermissionMessage::kStartupPages },
}; };
std::vector<APIPermissionInfo*> permissions; std::vector<APIPermissionInfo*> permissions;
......
// Copyright 2013 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/common/extensions/permissions/settings_override_permission.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
namespace extensions {
SettingsOverrideAPIPermission::SettingsOverrideAPIPermission(
const APIPermissionInfo* permission, const std::string& setting_value)
: APIPermission(permission),
setting_value_(setting_value) {
}
SettingsOverrideAPIPermission::~SettingsOverrideAPIPermission() {
}
bool SettingsOverrideAPIPermission::HasMessages() const {
return info()->message_id() > PermissionMessage::kNone;
}
PermissionMessages SettingsOverrideAPIPermission::GetMessages() const {
DCHECK(HasMessages());
int string_id = -1;
switch (id()) {
case kHomepage: {
string_id = IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE;
break;
}
case kStartupPages: {
string_id = IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE;
break;
}
case kSearchProvider: {
string_id = IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE;
break;
}
default:
NOTREACHED();
}
PermissionMessages result;
result.push_back(PermissionMessage(
info()->message_id(),
l10n_util::GetStringFUTF16(string_id, UTF8ToUTF16(setting_value_))));
return result;
}
bool SettingsOverrideAPIPermission::Check(
const APIPermission::CheckParam* param) const {
return !param;
}
bool SettingsOverrideAPIPermission::Contains(const APIPermission* rhs) const {
CHECK(info() == rhs->info());
return true;
}
bool SettingsOverrideAPIPermission::Equal(const APIPermission* rhs) const {
if (this == rhs)
return true;
CHECK(info() == rhs->info());
return true;
}
bool SettingsOverrideAPIPermission::FromValue(const base::Value* value) {
if (value)
return false;
return true;
}
scoped_ptr<base::Value> SettingsOverrideAPIPermission::ToValue() const {
return scoped_ptr<base::Value>();
}
APIPermission* SettingsOverrideAPIPermission::Clone() const {
return new SettingsOverrideAPIPermission(info(), setting_value_);
}
APIPermission* SettingsOverrideAPIPermission::Diff(
const APIPermission* rhs) const {
CHECK(info() == rhs->info());
return NULL;
}
APIPermission* SettingsOverrideAPIPermission::Union(
const APIPermission* rhs) const {
CHECK(info() == rhs->info());
return new SettingsOverrideAPIPermission(info(), setting_value_);
}
APIPermission* SettingsOverrideAPIPermission::Intersect(
const APIPermission* rhs) const {
CHECK(info() == rhs->info());
return new SettingsOverrideAPIPermission(info(), setting_value_);
}
void SettingsOverrideAPIPermission::Write(IPC::Message* m) const {
}
bool SettingsOverrideAPIPermission::Read(
const IPC::Message* m, PickleIterator* iter) {
return true;
}
void SettingsOverrideAPIPermission::Log(std::string* log) const {
}
} // namespace extensions
// Copyright 2013 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.
#ifndef CHROME_COMMON_EXTENSIONS_PERMISSIONS_SETTINGS_OVERRIDE_PERMISSION_H_
#define CHROME_COMMON_EXTENSIONS_PERMISSIONS_SETTINGS_OVERRIDE_PERMISSION_H_
#include <string>
#include "extensions/common/permissions/api_permission.h"
namespace extensions {
// Takes care of creating custom permission messages for extensions that
// override settings.
class SettingsOverrideAPIPermission : public APIPermission {
public:
SettingsOverrideAPIPermission(
const APIPermissionInfo* permission, const std::string& setting_value);
virtual ~SettingsOverrideAPIPermission();
// APIPermission overrides.
virtual bool HasMessages() const OVERRIDE;
virtual PermissionMessages GetMessages() const OVERRIDE;
virtual bool Check(const APIPermission::CheckParam* param) const OVERRIDE;
virtual bool Contains(const APIPermission* rhs) const OVERRIDE;
virtual bool Equal(const APIPermission* rhs) const OVERRIDE;
virtual bool FromValue(const base::Value* value) OVERRIDE;
virtual scoped_ptr<base::Value> ToValue() const OVERRIDE;
virtual APIPermission* Clone() const OVERRIDE;
virtual APIPermission* Diff(const APIPermission* rhs) const OVERRIDE;
virtual APIPermission* Union(const APIPermission* rhs) const OVERRIDE;
virtual APIPermission* Intersect(const APIPermission* rhs) const OVERRIDE;
virtual void Write(IPC::Message* m) const OVERRIDE;
virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE;
virtual void Log(std::string* log) const OVERRIDE;
private:
std::string setting_value_;
};
} // namespace extensions
#endif // CHROME_COMMON_EXTENSIONS_PERMISSIONS_SETTINGS_OVERRIDE_PERMISSION_H_
// Copyright 2013 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.
// These tests make sure SettingsOverridePermission values are set correctly.
#include "base/basictypes.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/extensions/permissions/settings_override_permission.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/permissions/permission_set.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
namespace {
class SettingsOverridePermissionTest : public ExtensionManifestTest {
protected:
enum Flags {
kHomepage = 1,
kStartupPages = 1 << 1,
kSearchProvider = 1 << 2,
};
scoped_refptr<Extension> GetPermissionSet(uint32 flags) {
base::DictionaryValue ext_manifest;
ext_manifest.SetString(manifest_keys::kName, "test");
ext_manifest.SetString(manifest_keys::kVersion, "0.1");
ext_manifest.SetInteger(manifest_keys::kManifestVersion, 2);
scoped_ptr<base::DictionaryValue> settings_override(
new base::DictionaryValue);
if (flags & kHomepage)
settings_override->SetString("homepage", "http://www.google.com");
if (flags & kStartupPages) {
scoped_ptr<ListValue> startup_pages(new ListValue);
startup_pages->AppendString("http://startup.com/startup.html");
settings_override->Set("startup_pages", startup_pages.release());
}
if (flags & kSearchProvider) {
scoped_ptr<DictionaryValue> search_provider(new DictionaryValue);
search_provider->SetString("search_url", "http://google.com/search.html");
search_provider->SetString("name", "test");
search_provider->SetString("keyword", "lock");
search_provider->SetString("encoding", "UTF-8");
search_provider->SetBoolean("is_default", true);
search_provider->SetString("favicon_url", "wikipedia.org/wiki/Favicon");
settings_override->Set("search_provider", search_provider.release());
}
ext_manifest.Set(
manifest_keys::kSettingsOverride, settings_override.release());
Manifest manifest(&ext_manifest, "test");
return LoadAndExpectSuccess(manifest);
}
};
TEST_F(SettingsOverridePermissionTest, HomePage) {
scoped_refptr<Extension> extension(GetPermissionSet(kHomepage));
scoped_refptr<const PermissionSet> permission_set(
extension->GetActivePermissions());
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kHomepage));
std::vector<string16> warnings =
PermissionsData::GetPermissionMessageStrings(extension.get());
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Change your home page to: google.com/",
UTF16ToUTF8(warnings[0]));
EXPECT_FALSE(permission_set->HasAPIPermission(APIPermission::kStartupPages));
EXPECT_FALSE(permission_set->HasAPIPermission(
APIPermission::kSearchProvider));
}
TEST_F(SettingsOverridePermissionTest, SartupPages) {
scoped_refptr<Extension> extension(GetPermissionSet(kStartupPages));
scoped_refptr<const PermissionSet> permission_set(
extension->GetActivePermissions());
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kStartupPages));
std::vector<string16> warnings =
PermissionsData::GetPermissionMessageStrings(extension.get());
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Change your start page to: startup.com/startup.html",
UTF16ToUTF8(warnings[0]));
EXPECT_FALSE(permission_set->HasAPIPermission(APIPermission::kHomepage));
EXPECT_FALSE(permission_set->HasAPIPermission(
APIPermission::kSearchProvider));
}
TEST_F(SettingsOverridePermissionTest, SearchSettings) {
scoped_refptr<Extension> extension(GetPermissionSet(kSearchProvider));
scoped_refptr<const PermissionSet> permission_set(
extension->GetActivePermissions());
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kSearchProvider));
std::vector<string16> warnings =
PermissionsData::GetPermissionMessageStrings(extension.get());
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ("Change your search settings to: google.com",
UTF16ToUTF8(warnings[0]));
EXPECT_FALSE(permission_set->HasAPIPermission(APIPermission::kHomepage));
EXPECT_FALSE(permission_set->HasAPIPermission(APIPermission::kStartupPages));
}
TEST_F(SettingsOverridePermissionTest, All) {
scoped_refptr<Extension> extension(GetPermissionSet(
kSearchProvider | kStartupPages | kHomepage));
scoped_refptr<const PermissionSet> permission_set(
extension->GetActivePermissions());
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kSearchProvider));
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kHomepage));
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kStartupPages));
}
TEST_F(SettingsOverridePermissionTest, Some) {
scoped_refptr<Extension> extension(GetPermissionSet(
kSearchProvider | kHomepage));
scoped_refptr<const PermissionSet> permission_set(
extension->GetActivePermissions());
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kSearchProvider));
EXPECT_TRUE(permission_set->HasAPIPermission(APIPermission::kHomepage));
EXPECT_FALSE(permission_set->HasAPIPermission(APIPermission::kStartupPages));
}
} // namespace
} // namespace extensions
...@@ -90,6 +90,7 @@ class APIPermission { ...@@ -90,6 +90,7 @@ class APIPermission {
kFullscreen, kFullscreen,
kGeolocation, kGeolocation,
kHistory, kHistory,
kHomepage,
kIdentity, kIdentity,
kIdentityPrivate, kIdentityPrivate,
kIdltest, kIdltest,
...@@ -121,11 +122,13 @@ class APIPermission { ...@@ -121,11 +122,13 @@ class APIPermission {
kPushMessaging, kPushMessaging,
kImageWriterPrivate, kImageWriterPrivate,
kRtcPrivate, kRtcPrivate,
kSearchProvider,
kSerial, kSerial,
kSessions, kSessions,
kSignedInDevices, kSignedInDevices,
kSocket, kSocket,
kSocketsUdp, kSocketsUdp,
kStartupPages,
kStorage, kStorage,
kStreamsPrivate, kStreamsPrivate,
kSyncFileSystem, kSyncFileSystem,
......
...@@ -74,6 +74,9 @@ class PermissionMessage { ...@@ -74,6 +74,9 @@ class PermissionMessage {
kSignedInDevices, kSignedInDevices,
kWallpaper, kWallpaper,
kNetworkState, kNetworkState,
kHomepage,
kSearchProvider,
kStartupPages,
kEnumBoundary, kEnumBoundary,
}; };
COMPILE_ASSERT(PermissionMessage::kNone > PermissionMessage::kUnknown, COMPILE_ASSERT(PermissionMessage::kNone > PermissionMessage::kUnknown,
......
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