summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/api/bluetooth/bluetooth_apitest.cc4
-rw-r--r--chrome/browser/extensions/api/permissions/permissions_api.cc41
-rw-r--r--chrome/browser/extensions/api/permissions/permissions_api.h4
-rw-r--r--chrome/browser/extensions/api/permissions/permissions_apitest.cc11
-rw-r--r--chrome/browser/extensions/bundle_installer.cc4
-rw-r--r--chrome/browser/extensions/content_script_apitest.cc4
-rw-r--r--chrome/browser/extensions/extension_service.cc8
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/extensions/api/extension_api.cc7
-rw-r--r--chrome/common/extensions/api/plugins/plugins_handler.cc4
-rw-r--r--chrome/common/extensions/api/system_indicator/system_indicator_handler.cc4
-rw-r--r--chrome/common/extensions/background_info.cc3
-rw-r--r--chrome/common/extensions/extension.cc288
-rw-r--r--chrome/common/extensions/extension.h57
-rw-r--r--chrome/common/extensions/features/permission_feature.cc4
-rw-r--r--chrome/common/extensions/manifest_handlers/app_isolation_info.cc3
-rw-r--r--chrome/common/extensions/manifest_url_handler.cc4
-rw-r--r--chrome/common/extensions/permissions/permissions_data.cc371
-rw-r--r--chrome/common/extensions/permissions/permissions_data.h65
19 files changed, 520 insertions, 368 deletions
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest.cc
index 41ff365..a840e14 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest.cc
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest.cc
@@ -583,8 +583,8 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevicesError) {
}
IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Permissions) {
- PermissionsRequestFunction::SetAutoConfirmForTests(true);
- PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
+ extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
+ extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
event_router()->AddProfile(
"00001101-0000-1000-8000-00805f9b34fb", profile1_.get());
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.cc b/chrome/browser/extensions/api/permissions/permissions_api.cc
index d7aec6f3..ab523a5 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api.cc
@@ -13,26 +13,21 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/api/permissions.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/url_pattern_set.h"
#include "googleurl/src/gurl.h"
-using extensions::api::permissions::Permissions;
-using extensions::APIPermission;
-using extensions::APIPermissionSet;
-using extensions::ErrorUtils;
-using extensions::ExtensionPrefs;
-using extensions::ExtensionSystem;
-using extensions::PermissionSet;
-using extensions::PermissionsInfo;
-using extensions::PermissionsUpdater;
-
-namespace Contains = extensions::api::permissions::Contains;
-namespace GetAll = extensions::api::permissions::GetAll;
-namespace Remove = extensions::api::permissions::Remove;
-namespace Request = extensions::api::permissions::Request;
-namespace helpers = extensions::permissions_api_helpers;
+namespace extensions {
+
+using api::permissions::Permissions;
+
+namespace Contains = api::permissions::Contains;
+namespace GetAll = api::permissions::GetAll;
+namespace Remove = api::permissions::Remove;
+namespace Request = api::permissions::Request;
+namespace helpers = permissions_api_helpers;
namespace {
@@ -91,7 +86,7 @@ bool PermissionsRemoveFunction::RunImpl() {
if (!permissions.get())
return false;
- const extensions::Extension* extension = GetExtension();
+ const Extension* extension = GetExtension();
// Make sure they're only trying to remove permissions supported by this API.
APIPermissionSet apis = permissions->apis();
@@ -105,7 +100,8 @@ bool PermissionsRemoveFunction::RunImpl() {
}
// Make sure we don't remove any required pemissions.
- const PermissionSet* required = extension->required_permission_set();
+ const PermissionSet* required =
+ PermissionsData::GetRequiredPermissions(extension);
scoped_refptr<PermissionSet> intersection(
PermissionSet::CreateIntersection(permissions.get(), required));
if (!intersection->IsEmpty()) {
@@ -182,13 +178,12 @@ bool PermissionsRequestFunction::RunImpl() {
// Filter out permissions that do not need to be listed in the optional
// section of the manifest.
- scoped_refptr<extensions::PermissionSet>
- manifest_required_requested_permissions =
- PermissionSet::ExcludeNotInManifestPermissions(
- requested_permissions_.get());
+ scoped_refptr<PermissionSet> manifest_required_requested_permissions =
+ PermissionSet::ExcludeNotInManifestPermissions(
+ requested_permissions_.get());
// The requested permissions must be defined as optional in the manifest.
- if (!GetExtension()->optional_permission_set()->Contains(
+ if (!PermissionsData::GetOptionalPermissions(GetExtension())->Contains(
*manifest_required_requested_permissions)) {
error_ = kNotInOptionalPermissionsError;
return false;
@@ -231,3 +226,5 @@ bool PermissionsRequestFunction::RunImpl() {
return true;
}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.h b/chrome/browser/extensions/api/permissions/permissions_api.h
index e15f64c..a0d6ccb 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.h
+++ b/chrome/browser/extensions/api/permissions/permissions_api.h
@@ -14,6 +14,8 @@
class ExtensionService;
+namespace extensions {
+
// chrome.permissions.contains
class PermissionsContainsFunction : public SyncExtensionFunction {
public:
@@ -77,4 +79,6 @@ class PermissionsRequestFunction : public AsyncExtensionFunction,
scoped_refptr<extensions::PermissionSet> requested_permissions_;
};
+} // namespace extensions
+
#endif // CHROME_BROWSER_EXTENSIONS_API_PERMISSIONS_PERMISSIONS_API_H_
diff --git a/chrome/browser/extensions/api/permissions/permissions_apitest.cc b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
index 73ec0fa..82bd17f 100644
--- a/chrome/browser/extensions/api/permissions/permissions_apitest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
@@ -12,10 +12,7 @@
#include "chrome/common/extensions/permissions/permission_set.h"
#include "net/dns/mock_host_resolver.h"
-using extensions::APIPermission;
-using extensions::APIPermissionSet;
-using extensions::PermissionSet;
-using extensions::URLPatternSet;
+namespace extensions {
namespace {
@@ -80,7 +77,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, OptionalPermissionsGranted) {
scoped_refptr<PermissionSet> granted_permissions =
new PermissionSet(apis, explicit_hosts, URLPatternSet());
- extensions::ExtensionPrefs* prefs =
+ ExtensionPrefs* prefs =
browser()->profile()->GetExtensionService()->extension_prefs();
prefs->AddGrantedPermissions("kjmkgkdkpedkejedfhmfcenooemhbpbo",
granted_permissions);
@@ -137,7 +134,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, OptionalPermissionsFileAccess) {
PermissionsRequestFunction::SetAutoConfirmForTests(false);
PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
- extensions::ExtensionPrefs* prefs =
+ ExtensionPrefs* prefs =
browser()->profile()->GetExtensionService()->extension_prefs();
EXPECT_TRUE(
@@ -163,3 +160,5 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, HostSubsets) {
PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
EXPECT_TRUE(RunExtensionTest("permissions/host_subsets")) << message_;
}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/bundle_installer.cc b/chrome/browser/extensions/bundle_installer.cc
index 7cf66d3..c5db010 100644
--- a/chrome/browser/extensions/bundle_installer.cc
+++ b/chrome/browser/extensions/bundle_installer.cc
@@ -22,6 +22,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/permissions/permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
@@ -260,7 +261,8 @@ void BundleInstaller::ShowPrompt() {
scoped_refptr<PermissionSet> permissions;
for (size_t i = 0; i < dummy_extensions_.size(); ++i) {
permissions = PermissionSet::CreateUnion(
- permissions, dummy_extensions_[i]->required_permission_set());
+ permissions,
+ PermissionsData::GetRequiredPermissions(dummy_extensions_[i]));
}
if (g_auto_approve_for_test == PROCEED) {
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index f3d5035..52d28c3 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -163,8 +163,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionAPIs) {
}
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptPermissionsApi) {
- PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
- PermissionsRequestFunction::SetAutoConfirmForTests(true);
+ extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
+ extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
host_resolver()->AddRule("*.com", "127.0.0.1");
ASSERT_TRUE(StartTestServer());
ASSERT_TRUE(RunExtensionTest("content_scripts/permissions")) << message_;
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index c7171e6..2cfc144 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -89,6 +89,7 @@
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/startup_metric_utils.h"
#include "chrome/common/url_constants.h"
@@ -2151,8 +2152,8 @@ void ExtensionService::UpdateActivePermissions(const Extension* extension) {
// b) active permissions must contains all default permissions
scoped_refptr<PermissionSet> total_permissions =
PermissionSet::CreateUnion(
- extension->required_permission_set(),
- extension->optional_permission_set());
+ extensions::PermissionsData::GetRequiredPermissions(extension),
+ extensions::PermissionsData::GetOptionalPermissions(extension));
// Make sure the active permissions contain no more than optional + default.
scoped_refptr<PermissionSet> adjusted_active =
@@ -2161,7 +2162,8 @@ void ExtensionService::UpdateActivePermissions(const Extension* extension) {
// Make sure the active permissions contain the default permissions.
adjusted_active = PermissionSet::CreateUnion(
- extension->required_permission_set(), adjusted_active.get());
+ extensions::PermissionsData::GetRequiredPermissions(extension),
+ adjusted_active.get());
extensions::PermissionsUpdater perms_updater(profile());
perms_updater.UpdateActivePermissions(extension, adjusted_active);
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 9fc8534..72b9527 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -295,6 +295,8 @@
'common/extensions/permissions/permission_message.h',
'common/extensions/permissions/permission_set.cc',
'common/extensions/permissions/permission_set.h',
+ 'common/extensions/permissions/permissions_data.cc',
+ 'common/extensions/permissions/permissions_data.h',
'common/extensions/permissions/permissions_info.cc',
'common/extensions/permissions/permissions_info.h',
'common/extensions/permissions/set_disjunction_permission.h',
diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc
index b158aa9..029c8fd 100644
--- a/chrome/common/extensions/api/extension_api.cc
+++ b/chrome/common/extensions/api/extension_api.cc
@@ -21,6 +21,7 @@
#include "chrome/common/extensions/features/base_feature_provider.h"
#include "chrome/common/extensions/features/simple_feature.h"
#include "chrome/common/extensions/permissions/permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "googleurl/src/gurl.h"
#include "grit/common_resources.h"
#include "grit/extensions_api_resources.h"
@@ -576,8 +577,10 @@ std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name,
bool ExtensionAPI::IsAPIAllowed(const std::string& name,
const Extension* extension) {
- return extension->required_permission_set()->HasAnyAccessToAPI(name) ||
- extension->optional_permission_set()->HasAnyAccessToAPI(name);
+ return PermissionsData::GetRequiredPermissions(extension)->
+ HasAnyAccessToAPI(name) ||
+ PermissionsData::GetOptionalPermissions(extension)->
+ HasAnyAccessToAPI(name);
}
bool ExtensionAPI::IsPrivilegedAPI(const std::string& name) {
diff --git a/chrome/common/extensions/api/plugins/plugins_handler.cc b/chrome/common/extensions/api/plugins/plugins_handler.cc
index 2f255f1..618aa7d 100644
--- a/chrome/common/extensions/api/plugins/plugins_handler.cc
+++ b/chrome/common/extensions/api/plugins/plugins_handler.cc
@@ -12,6 +12,7 @@
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "extensions/common/error_utils.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -117,7 +118,8 @@ bool PluginsHandler::Parse(Extension* extension, string16* error) {
if (!plugins_data->plugins.empty()) {
extension->SetManifestData(keys::kPlugins, plugins_data.release());
- extension->initial_api_permissions()->insert(APIPermission::kPlugin);
+ PermissionsData::GetInitialAPIPermissions(extension)->insert(
+ APIPermission::kPlugin);
}
return true;
diff --git a/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc b/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
index 638b539..17246c3 100644
--- a/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
+++ b/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
@@ -11,6 +11,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
namespace extensions {
@@ -36,7 +37,8 @@ bool SystemIndicatorHandler::Parse(Extension* extension, string16* error) {
// Because the manifest was successfully parsed, auto-grant the permission.
// TODO(dewittj) Add this for all extension action APIs.
- extension->initial_api_permissions()->insert(APIPermission::kSystemIndicator);
+ PermissionsData::GetInitialAPIPermissions(extension)->insert(
+ APIPermission::kSystemIndicator);
ActionInfo::SetSystemIndicatorInfo(extension, action_info.release());
return true;
diff --git a/chrome/common/extensions/background_info.cc b/chrome/common/extensions/background_info.cc
index f995c54..77dd5af 100644
--- a/chrome/common/extensions/background_info.cc
+++ b/chrome/common/extensions/background_info.cc
@@ -15,6 +15,7 @@
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "extensions/common/error_utils.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -149,7 +150,7 @@ bool BackgroundInfo::LoadBackgroundPage(const Extension* extension,
if (extension->is_hosted_app()) {
background_url_ = GURL(background_str);
- if (!extension->initial_api_permissions()->count(
+ if (!PermissionsData::GetInitialAPIPermissions(extension)->count(
APIPermission::kBackground)) {
*error = ASCIIToUTF16(errors::kBackgroundPermissionNeeded);
return false;
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index aa7b5f4..8f7bf79 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -30,19 +30,15 @@
#include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "chrome/common/extensions/background_info.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/feature_switch.h"
-#include "chrome/common/extensions/features/base_feature_provider.h"
-#include "chrome/common/extensions/features/feature.h"
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handler.h"
-#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
#include "chrome/common/extensions/manifest_handlers/offline_enabled_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
#include "chrome/common/extensions/permissions/permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/url_constants.h"
@@ -81,8 +77,6 @@ const char kPrivate[] = "PRIVATE";
const int kRSAKeySize = 1024;
-const char kThumbsWhiteListedExtension[] = "khopmbdjffemhegeeobelklnbglcdgfh";
-
// A singleton object containing global data needed by the extension objects.
class ExtensionConfig {
public:
@@ -142,21 +136,6 @@ bool ReadLaunchDimension(const extensions::Manifest* manifest,
return true;
}
-bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis,
- string16* error) {
- CHECK(error);
- for (APIPermissionSet::const_iterator i = apis.begin();
- i != apis.end(); ++i) {
- if ((*i)->ManifestEntryForbidden()) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kPermissionNotAllowedInManifest,
- (*i)->info()->name());
- return true;
- }
- }
- return false;
-}
-
} // namespace
#if defined(OS_WIN)
@@ -426,147 +405,6 @@ const Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() {
return ExtensionConfig::GetInstance()->whitelist();
}
-bool Extension::ParsePermissions(const char* key,
- string16* error,
- APIPermissionSet* api_permissions,
- URLPatternSet* host_permissions) {
- if (manifest_->HasKey(key)) {
- const ListValue* permissions = NULL;
- if (!manifest_->GetList(key, &permissions)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidPermissions,
- std::string());
- return false;
- }
-
- // NOTE: We need to get the APIPermission before we check if features
- // associated with them are available because the feature system does not
- // know about aliases.
-
- std::vector<std::string> host_data;
- if (!APIPermissionSet::ParseFromJSON(permissions, api_permissions,
- error, &host_data))
- return false;
-
- // Verify feature availability of permissions.
- std::vector<APIPermission::ID> to_remove;
- FeatureProvider* permission_features =
- BaseFeatureProvider::GetByName("permission");
- for (APIPermissionSet::const_iterator it = api_permissions->begin();
- it != api_permissions->end(); ++it) {
- extensions::Feature* feature =
- permission_features->GetFeature(it->name());
-
- // The feature should exist since we just got an APIPermission
- // for it. The two systems should be updated together whenever a
- // permission is added.
- DCHECK(feature);
- // http://crbug.com/176381
- if (!feature) {
- to_remove.push_back(it->id());
- continue;
- }
-
- Feature::Availability availability =
- feature->IsAvailableToManifest(
- id(),
- GetType(),
- Feature::ConvertLocation(location()),
- manifest_version());
- if (!availability.is_available()) {
- // Don't fail, but warn the developer that the manifest contains
- // unrecognized permissions. This may happen legitimately if the
- // extensions requests platform- or channel-specific permissions.
- install_warnings_.push_back(InstallWarning(InstallWarning::FORMAT_TEXT,
- availability.message()));
- to_remove.push_back(it->id());
- continue;
- }
-
- if (it->id() == APIPermission::kExperimental) {
- if (!CanSpecifyExperimentalPermission()) {
- *error = ASCIIToUTF16(errors::kExperimentalFlagRequired);
- return false;
- }
- }
- }
-
- // Remove permissions that are not available to this extension.
- for (std::vector<APIPermission::ID>::const_iterator it = to_remove.begin();
- it != to_remove.end(); ++it) {
- api_permissions->erase(*it);
- }
-
- // Parse host pattern permissions.
- const int kAllowedSchemes = CanExecuteScriptEverywhere() ?
- URLPattern::SCHEME_ALL : kValidHostPermissionSchemes;
-
- for (std::vector<std::string>::const_iterator it = host_data.begin();
- it != host_data.end(); ++it) {
- const std::string& permission_str = *it;
-
- // Check if it's a host pattern permission.
- URLPattern pattern = URLPattern(kAllowedSchemes);
- URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
- if (parse_result == URLPattern::PARSE_SUCCESS) {
- // The path component is not used for host permissions, so we force it
- // to match all paths.
- pattern.SetPath("/*");
- int valid_schemes = pattern.valid_schemes();
- if (pattern.MatchesScheme(chrome::kFileScheme) &&
- !CanExecuteScriptEverywhere()) {
- wants_file_access_ = true;
- if (!(creation_flags_ & ALLOW_FILE_ACCESS))
- valid_schemes &= ~URLPattern::SCHEME_FILE;
- }
-
- if (pattern.scheme() != chrome::kChromeUIScheme &&
- !CanExecuteScriptEverywhere()) {
- // Keep chrome:// in allowed schemes only if it's explicitly requested
- // or CanExecuteScriptEverywhere is true. If the
- // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
- // will fail, so don't check the flag here.
- valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
- }
- pattern.SetValidSchemes(valid_schemes);
-
- if (!CanSpecifyHostPermission(pattern, *api_permissions)) {
- // TODO(aboxhall): make a warning (see line 633)
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidPermissionScheme, permission_str);
- return false;
- }
-
- host_permissions->AddPattern(pattern);
-
- // We need to make sure all_urls matches chrome://favicon and
- // (maybe) chrome://thumbnail, so add them back in to host_permissions
- // separately.
- if (pattern.match_all_urls()) {
- host_permissions->AddPattern(
- URLPattern(URLPattern::SCHEME_CHROMEUI,
- chrome::kChromeUIFaviconURL));
- if (api_permissions->find(APIPermission::kExperimental) !=
- api_permissions->end()) {
- host_permissions->AddPattern(
- URLPattern(URLPattern::SCHEME_CHROMEUI,
- chrome::kChromeUIThumbnailURL));
- }
- }
- continue;
- }
-
- // It's probably an unknown API permission. Do not throw an error so
- // extensions can retain backwards compatability (http://crbug.com/42742).
- install_warnings_.push_back(InstallWarning(
- InstallWarning::FORMAT_TEXT,
- base::StringPrintf(
- "Permission '%s' is unknown or URL pattern is malformed.",
- permission_str.c_str())));
- }
- }
- return true;
-}
-
bool Extension::HasAPIPermission(APIPermission::ID permission) const {
base::AutoLock auto_lock(runtime_data_lock_);
return runtime_data_.GetActivePermissions()->HasAPIPermission(permission);
@@ -643,14 +481,12 @@ bool Extension::ShouldSkipPermissionWarnings() const {
return IsTrustedId(id());
}
-void Extension::SetActivePermissions(
- const PermissionSet* permissions) const {
+void Extension::SetActivePermissions(const PermissionSet* permissions) const {
base::AutoLock auto_lock(runtime_data_lock_);
runtime_data_.SetActivePermissions(permissions);
}
-scoped_refptr<const PermissionSet>
- Extension::GetActivePermissions() const {
+scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const {
base::AutoLock auto_lock(runtime_data_lock_);
return runtime_data_.GetActivePermissions();
}
@@ -1095,13 +931,6 @@ Extension::~Extension() {
bool Extension::InitFromValue(int flags, string16* error) {
DCHECK(error);
- base::AutoLock auto_lock(runtime_data_lock_);
-
- // Initialize permissions with an empty, default permission set.
- runtime_data_.SetActivePermissions(new PermissionSet());
- optional_permission_set_ = new PermissionSet();
- required_permission_set_ = new PermissionSet();
-
creation_flags_ = flags;
// Important to load manifest version first because many other features
@@ -1128,47 +957,9 @@ bool Extension::InitFromValue(int flags, string16* error) {
if (is_app() && !LoadAppFeatures(error))
return false;
- initial_api_permissions_.reset(new APIPermissionSet);
- URLPatternSet host_permissions;
- if (!ParsePermissions(keys::kPermissions,
- error,
- initial_api_permissions_.get(),
- &host_permissions)) {
+ permissions_data_.reset(new PermissionsData);
+ if (!permissions_data_->ParsePermissions(this, error))
return false;
- }
-
- // Check for any permissions that are optional only.
- for (APIPermissionSet::const_iterator i = initial_api_permissions_->begin();
- i != initial_api_permissions_->end(); ++i) {
- if ((*i)->info()->must_be_optional()) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kPermissionMustBeOptional, (*i)->info()->name());
- return false;
- }
- }
-
- // TODO(jeremya/kalman) do this via the features system by exposing the
- // app.window API to platform apps, with no dependency on any permissions.
- // See http://crbug.com/120069.
- if (is_platform_app()) {
- initial_api_permissions_->insert(APIPermission::kAppCurrentWindowInternal);
- initial_api_permissions_->insert(APIPermission::kAppRuntime);
- initial_api_permissions_->insert(APIPermission::kAppWindow);
- }
-
- APIPermissionSet optional_api_permissions;
- URLPatternSet optional_host_permissions;
- if (!ParsePermissions(keys::kOptionalPermissions,
- error,
- &optional_api_permissions,
- &optional_host_permissions)) {
- return false;
- }
-
- if (ContainsManifestForbiddenPermission(*initial_api_permissions_, error) ||
- ContainsManifestForbiddenPermission(optional_api_permissions, error)) {
- return false;
- }
if (!LoadSharedFeatures(error))
return false;
@@ -1182,17 +973,9 @@ bool Extension::InitFromValue(int flags, string16* error) {
return false;
}
- URLPatternSet scriptable_hosts = ContentScriptsInfo::GetScriptableHosts(this);
-
finished_parsing_manifest_ = true;
- runtime_data_.SetActivePermissions(new PermissionSet(
- *initial_api_permissions_, host_permissions, scriptable_hosts));
- required_permission_set_ = new PermissionSet(
- *initial_api_permissions_, host_permissions, scriptable_hosts);
- optional_permission_set_ = new PermissionSet(
- optional_api_permissions, optional_host_permissions, URLPatternSet());
- initial_api_permissions_.reset();
+ permissions_data_->FinalizePermissions(this);
return true;
}
@@ -1274,8 +1057,8 @@ bool Extension::LoadExtent(const char* key,
std::string pattern_string;
if (!pattern_list->GetString(i, &pattern_string)) {
*error = ErrorUtils::FormatErrorMessageUTF16(value_error,
- base::UintToString(i),
- errors::kExpectString);
+ base::UintToString(i),
+ errors::kExpectString);
return false;
}
@@ -1609,61 +1392,6 @@ void Extension::OverrideLaunchUrl(const GURL& override_url) {
}
}
-bool Extension::CanSpecifyExperimentalPermission() const {
- if (location() == Manifest::COMPONENT)
- return true;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalExtensionApis)) {
- return true;
- }
-
- // We rely on the webstore to check access to experimental. This way we can
- // whitelist extensions to have access to experimental in just the store, and
- // not have to push a new version of the client.
- if (from_webstore())
- return true;
-
- return false;
-}
-
-bool Extension::CanSpecifyHostPermission(const URLPattern& pattern,
- const APIPermissionSet& permissions) const {
- if (!pattern.match_all_urls() &&
- pattern.MatchesScheme(chrome::kChromeUIScheme)) {
- // Regular extensions are only allowed access to chrome://favicon.
- if (pattern.host() == chrome::kChromeUIFaviconHost)
- return true;
-
- // Experimental extensions are also allowed chrome://thumb.
- //
- // TODO: A public API should be created for retrieving thumbnails.
- // See http://crbug.com/222856. A temporary hack is implemented here to
- // make chrome://thumbs available to NTP Russia extension as
- // non-experimental.
- if (pattern.host() == chrome::kChromeUIThumbnailHost) {
- return
- permissions.find(APIPermission::kExperimental) != permissions.end() ||
- (id() == kThumbsWhiteListedExtension && from_webstore());
- }
-
- // Component extensions can have access to all of chrome://*.
- if (CanExecuteScriptEverywhere())
- return true;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kExtensionsOnChromeURLs))
- return true;
-
- // TODO(aboxhall): return from_webstore() when webstore handles blocking
- // extensions which request chrome:// urls
- return false;
- }
-
- // Otherwise, the valid schemes were handled by URLPattern.
- return true;
-}
-
bool Extension::CheckMinimumChromeVersion(string16* error) const {
if (!manifest_->HasKey(keys::kMinimumChromeVersion))
return true;
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 4f8674c..7f05620 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -47,6 +47,7 @@ class ImageSkia;
}
namespace extensions {
+class PermissionsData;
class APIPermissionSet;
class PermissionSet;
@@ -170,11 +171,11 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// In a few special circumstances, we want to create an Extension and give it
// an explicit id. Most consumers should just use the other Create() method.
static scoped_refptr<Extension> Create(const base::FilePath& path,
- Manifest::Location location,
- const base::DictionaryValue& value,
- int flags,
- const std::string& explicit_id,
- std::string* error);
+ Manifest::Location location,
+ const base::DictionaryValue& value,
+ int flags,
+ const std::string& explicit_id,
+ std::string* error);
// Valid schemes for web extent URLPatterns.
static const int kValidWebExtentSchemes;
@@ -246,13 +247,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
static void SetScriptingWhitelist(const ScriptingWhitelist& whitelist);
static const ScriptingWhitelist* GetScriptingWhitelist();
- // Parses the host and api permissions from the specified permission |key|
- // from |manifest_|.
- bool ParsePermissions(const char* key,
- string16* error,
- APIPermissionSet* api_permissions,
- URLPatternSet* host_permissions);
-
// Returns true if this extension has the given permission. Prefer
// IsExtensionWithPermissionOrSuggestInConsole when developers may be using an
// api that requires a permission they didn't know about, e.g. open web apis.
@@ -260,7 +254,8 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
bool HasAPIPermission(const std::string& function_name) const;
bool HasAPIPermissionForTab(int tab_id, APIPermission::ID permission) const;
- bool CheckAPIPermissionWithParam(APIPermission::ID permission,
+ bool CheckAPIPermissionWithParam(
+ APIPermission::ID permission,
const APIPermission::CheckParam* param) const;
const URLPatternSet& GetEffectiveHostPermissions() const;
@@ -409,20 +404,11 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
const std::vector<NaClModuleInfo>& nacl_modules() const {
return nacl_modules_;
}
- const PermissionSet* optional_permission_set() const {
- return optional_permission_set_.get();
- }
- const PermissionSet* required_permission_set() const {
- return required_permission_set_.get();
- }
- // Returns the temporary APIPermissionSet used in initialization.
- // (NULL after initialization is completed.)
- APIPermissionSet* initial_api_permissions() {
- return initial_api_permissions_.get();
- }
- const APIPermissionSet* initial_api_permissions() const {
- return initial_api_permissions_.get();
+ PermissionsData* permissions_data() { return permissions_data_.get(); }
+ const PermissionsData* permissions_data() const {
+ return permissions_data_.get();
}
+
// Appends |new_warning[s]| to install_warnings_.
void AddInstallWarning(const InstallWarning& new_warning);
void AddInstallWarnings(const std::vector<InstallWarning>& new_warnings);
@@ -549,15 +535,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// |override_url|.
void OverrideLaunchUrl(const GURL& override_url);
- // Custom checks for the experimental permission that can't be expressed in
- // _permission_features.json.
- bool CanSpecifyExperimentalPermission() const;
-
- // Checks whether the host |pattern| is allowed for this extension, given API
- // permissions |permissions|.
- bool CanSpecifyHostPermission(const URLPattern& pattern,
- const APIPermissionSet& permissions) const;
-
bool CheckMinimumChromeVersion(string16* error) const;
// Check that platform app features are valid. Called after InitFromValue.
@@ -594,15 +571,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
mutable base::Lock runtime_data_lock_;
mutable RuntimeData runtime_data_;
- // The API permission set; used during extension initialization.
- // Cleared after permissions are finalized by SetActivePermissions.
- scoped_ptr<APIPermissionSet> initial_api_permissions_;
-
- // The set of permissions the extension can request at runtime.
- scoped_refptr<const PermissionSet> optional_permission_set_;
-
- // The extension's required / default set of permissions.
- scoped_refptr<const PermissionSet> required_permission_set_;
+ scoped_ptr<PermissionsData> permissions_data_;
// Any warnings that occurred when trying to create/parse the extension.
std::vector<InstallWarning> install_warnings_;
diff --git a/chrome/common/extensions/features/permission_feature.cc b/chrome/common/extensions/features/permission_feature.cc
index 4681aa2..5fa2ba2 100644
--- a/chrome/common/extensions/features/permission_feature.cc
+++ b/chrome/common/extensions/features/permission_feature.cc
@@ -5,6 +5,7 @@
#include "chrome/common/extensions/features/permission_feature.h"
#include "chrome/common/extensions/permissions/permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
namespace extensions {
@@ -29,7 +30,8 @@ Feature::Availability PermissionFeature::IsAvailableToContext(
// Optional permissions need to be checked so an API will not be set to
// undefined forever, when it could just need optional permissions.
if (extension && !extension->HasAPIPermission(name()) &&
- !extension->optional_permission_set()->HasAnyAccessToAPI(name())) {
+ !PermissionsData::GetOptionalPermissions(extension)->
+ HasAnyAccessToAPI(name())) {
return CreateAvailability(NOT_PRESENT, extension->GetType());
}
diff --git a/chrome/common/extensions/manifest_handlers/app_isolation_info.cc b/chrome/common/extensions/manifest_handlers/app_isolation_info.cc
index 0d667a9..4b126c0 100644
--- a/chrome/common/extensions/manifest_handlers/app_isolation_info.cc
+++ b/chrome/common/extensions/manifest_handlers/app_isolation_info.cc
@@ -11,6 +11,7 @@
#include "base/values.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "extensions/common/error_utils.h"
namespace keys = extension_manifest_keys;
@@ -47,7 +48,7 @@ bool AppIsolationHandler::Parse(Extension* extension, string16* error) {
// Other apps only get it if it is requested _and_ experimental APIs are
// enabled.
if (!extension->is_app() ||
- !extension->initial_api_permissions()->count(
+ !PermissionsData::GetInitialAPIPermissions(extension)->count(
APIPermission::kExperimental)) {
return true;
}
diff --git a/chrome/common/extensions/manifest_url_handler.cc b/chrome/common/extensions/manifest_url_handler.cc
index 20b399a..1d15f40 100644
--- a/chrome/common/extensions/manifest_url_handler.cc
+++ b/chrome/common/extensions/manifest_url_handler.cc
@@ -17,6 +17,7 @@
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/url_constants.h"
#include "extensions/common/error_utils.h"
#include "grit/generated_resources.h"
@@ -110,7 +111,8 @@ bool DevToolsPageHandler::Parse(Extension* extension, string16* error) {
}
manifest_url->url_ = extension->GetResourceURL(devtools_str);
extension->SetManifestData(keys::kDevToolsPage, manifest_url.release());
- extension->initial_api_permissions()->insert(APIPermission::kDevtools);
+ PermissionsData::GetInitialAPIPermissions(extension)->insert(
+ APIPermission::kDevtools);
return true;
}
diff --git a/chrome/common/extensions/permissions/permissions_data.cc b/chrome/common/extensions/permissions/permissions_data.cc
new file mode 100644
index 0000000..445da12
--- /dev/null
+++ b/chrome/common/extensions/permissions/permissions_data.cc
@@ -0,0 +1,371 @@
+// Copyright (c) 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/permissions_data.h"
+
+#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
+#include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/extensions/features/base_feature_provider.h"
+#include "chrome/common/extensions/features/feature.h"
+#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
+#include "chrome/common/extensions/permissions/api_permission_set.h"
+#include "chrome/common/extensions/permissions/permission_set.h"
+#include "chrome/common/extensions/permissions/permissions_info.h"
+#include "chrome/common/url_constants.h"
+#include "extensions/common/error_utils.h"
+
+namespace keys = extension_manifest_keys;
+namespace errors = extension_manifest_errors;
+
+namespace extensions {
+
+namespace {
+
+const char kThumbsWhiteListedExtension[] = "khopmbdjffemhegeeobelklnbglcdgfh";
+
+bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis,
+ string16* error) {
+ CHECK(error);
+ for (APIPermissionSet::const_iterator iter = apis.begin();
+ iter != apis.end(); ++iter) {
+ if ((*iter)->ManifestEntryForbidden()) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kPermissionNotAllowedInManifest,
+ (*iter)->info()->name());
+ return true;
+ }
+ }
+ return false;
+}
+
+// Custom checks for the experimental permission that can't be expressed in
+// _permission_features.json.
+bool CanSpecifyExperimentalPermission(const Extension* extension) {
+ if (extension->location() == Manifest::COMPONENT)
+ return true;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalExtensionApis)) {
+ return true;
+ }
+
+ // We rely on the webstore to check access to experimental. This way we can
+ // whitelist extensions to have access to experimental in just the store, and
+ // not have to push a new version of the client.
+ if (extension->from_webstore())
+ return true;
+
+ return false;
+}
+
+// Checks whether the host |pattern| is allowed for the given |extension|,
+// given API permissions |permissions|.
+bool CanSpecifyHostPermission(const Extension* extension,
+ const URLPattern& pattern,
+ const APIPermissionSet& permissions) {
+ if (!pattern.match_all_urls() &&
+ pattern.MatchesScheme(chrome::kChromeUIScheme)) {
+ // Regular extensions are only allowed access to chrome://favicon.
+ if (pattern.host() == chrome::kChromeUIFaviconHost)
+ return true;
+
+ // Experimental extensions are also allowed chrome://thumb.
+ //
+ // TODO: A public API should be created for retrieving thumbnails.
+ // See http://crbug.com/222856. A temporary hack is implemented here to
+ // make chrome://thumbs available to NTP Russia extension as
+ // non-experimental.
+ if (pattern.host() == chrome::kChromeUIThumbnailHost) {
+ return
+ permissions.find(APIPermission::kExperimental) != permissions.end() ||
+ (extension->id() == kThumbsWhiteListedExtension &&
+ extension->from_webstore());
+ }
+
+ // Component extensions can have access to all of chrome://*.
+ if (extension->CanExecuteScriptEverywhere())
+ return true;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kExtensionsOnChromeURLs)) {
+ return true;
+ }
+
+ // TODO(aboxhall): return from_webstore() when webstore handles blocking
+ // extensions which request chrome:// urls
+ return false;
+ }
+
+ // Otherwise, the valid schemes were handled by URLPattern.
+ return true;
+}
+
+// Parses the host and api permissions from the specified permission |key|
+// from |extension|'s manifest.
+bool ParseHelper(Extension* extension,
+ const char* key,
+ APIPermissionSet* api_permissions,
+ URLPatternSet* host_permissions,
+ string16* error) {
+ if (!extension->manifest()->HasKey(key))
+ return true;
+
+ const ListValue* permissions = NULL;
+ if (!extension->manifest()->GetList(key, &permissions)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidPermissions,
+ std::string());
+ return false;
+ }
+
+ // NOTE: We need to get the APIPermission before we check if features
+ // associated with them are available because the feature system does not
+ // know about aliases.
+
+ std::vector<std::string> host_data;
+ if (!APIPermissionSet::ParseFromJSON(
+ permissions, api_permissions, error, &host_data)) {
+ return false;
+ }
+
+ // Verify feature availability of permissions.
+ std::vector<APIPermission::ID> to_remove;
+ FeatureProvider* permission_features =
+ BaseFeatureProvider::GetByName("permission");
+ for (APIPermissionSet::const_iterator iter = api_permissions->begin();
+ iter != api_permissions->end(); ++iter) {
+ Feature* feature = permission_features->GetFeature(iter->name());
+
+ // The feature should exist since we just got an APIPermission for it. The
+ // two systems should be updated together whenever a permission is added.
+ DCHECK(feature);
+ // http://crbug.com/176381
+ if (!feature) {
+ to_remove.push_back(iter->id());
+ continue;
+ }
+
+ Feature::Availability availability = feature->IsAvailableToManifest(
+ extension->id(),
+ extension->GetType(),
+ Feature::ConvertLocation(extension->location()),
+ extension->manifest_version());
+
+ if (!availability.is_available()) {
+ // Don't fail, but warn the developer that the manifest contains
+ // unrecognized permissions. This may happen legitimately if the
+ // extensions requests platform- or channel-specific permissions.
+ extension->AddInstallWarning(InstallWarning(InstallWarning::FORMAT_TEXT,
+ availability.message()));
+ to_remove.push_back(iter->id());
+ continue;
+ }
+
+ if (iter->id() == APIPermission::kExperimental) {
+ if (!CanSpecifyExperimentalPermission(extension)) {
+ *error = ASCIIToUTF16(errors::kExperimentalFlagRequired);
+ return false;
+ }
+ }
+ }
+
+ // Remove permissions that are not available to this extension.
+ for (std::vector<APIPermission::ID>::const_iterator iter = to_remove.begin();
+ iter != to_remove.end(); ++iter) {
+ api_permissions->erase(*iter);
+ }
+
+ // Parse host pattern permissions.
+ const int kAllowedSchemes = extension->CanExecuteScriptEverywhere() ?
+ URLPattern::SCHEME_ALL : Extension::kValidHostPermissionSchemes;
+
+ for (std::vector<std::string>::const_iterator iter = host_data.begin();
+ iter != host_data.end(); ++iter) {
+ const std::string& permission_str = *iter;
+
+ // Check if it's a host pattern permission.
+ URLPattern pattern = URLPattern(kAllowedSchemes);
+ URLPattern::ParseResult parse_result = pattern.Parse(permission_str);
+ if (parse_result == URLPattern::PARSE_SUCCESS) {
+ // The path component is not used for host permissions, so we force it
+ // to match all paths.
+ pattern.SetPath("/*");
+ int valid_schemes = pattern.valid_schemes();
+ if (pattern.MatchesScheme(chrome::kFileScheme) &&
+ !extension->CanExecuteScriptEverywhere()) {
+ extension->set_wants_file_access(true);
+ if (!(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS))
+ valid_schemes &= ~URLPattern::SCHEME_FILE;
+ }
+
+ if (pattern.scheme() != chrome::kChromeUIScheme &&
+ !extension->CanExecuteScriptEverywhere()) {
+ // Keep chrome:// in allowed schemes only if it's explicitly requested
+ // or CanExecuteScriptEverywhere is true. If the
+ // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission
+ // will fail, so don't check the flag here.
+ valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
+ }
+ pattern.SetValidSchemes(valid_schemes);
+
+ if (!CanSpecifyHostPermission(extension, pattern, *api_permissions)) {
+ // TODO(aboxhall): make a warning (see pattern.match_all_urls() block
+ // below).
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidPermissionScheme, permission_str);
+ return false;
+ }
+
+ host_permissions->AddPattern(pattern);
+
+ // We need to make sure all_urls matches chrome://favicon and (maybe)
+ // chrome://thumbnail, so add them back in to host_permissions separately.
+ if (pattern.match_all_urls()) {
+ host_permissions->AddPattern(
+ URLPattern(URLPattern::SCHEME_CHROMEUI,
+ chrome::kChromeUIFaviconURL));
+ if (api_permissions->find(APIPermission::kExperimental) !=
+ api_permissions->end()) {
+ host_permissions->AddPattern(
+ URLPattern(URLPattern::SCHEME_CHROMEUI,
+ chrome::kChromeUIThumbnailURL));
+ }
+ }
+ continue;
+ }
+
+ // It's probably an unknown API permission. Do not throw an error so
+ // extensions can retain backwards compatability (http://crbug.com/42742).
+ extension->AddInstallWarning(InstallWarning(
+ InstallWarning::FORMAT_TEXT,
+ base::StringPrintf(
+ "Permission '%s' is unknown or URL pattern is malformed.",
+ permission_str.c_str())));
+ }
+
+ return true;
+}
+
+} // namespace
+
+struct PermissionsData::InitialPermissions {
+ APIPermissionSet api_permissions;
+ URLPatternSet host_permissions;
+};
+
+PermissionsData::PermissionsData() {
+}
+
+PermissionsData::~PermissionsData() {
+}
+
+// static
+const PermissionSet* PermissionsData::GetOptionalPermissions(
+ const Extension* extension) {
+ return extension->permissions_data()->optional_permission_set_.get();
+}
+
+// static
+const PermissionSet* PermissionsData::GetRequiredPermissions(
+ const Extension* extension) {
+ return extension->permissions_data()->required_permission_set_.get();
+}
+
+// static
+const APIPermissionSet* PermissionsData::GetInitialAPIPermissions(
+ const Extension* extension) {
+ return &extension->permissions_data()->
+ initial_required_permissions_->api_permissions;
+}
+
+// static
+APIPermissionSet* PermissionsData::GetInitialAPIPermissions(
+ Extension* extension) {
+ return &extension->permissions_data()->
+ initial_required_permissions_->api_permissions;
+}
+
+bool PermissionsData::ParsePermissions(Extension* extension, string16* error) {
+ initial_required_permissions_.reset(new InitialPermissions);
+ if (!ParseHelper(extension,
+ keys::kPermissions,
+ &initial_required_permissions_->api_permissions,
+ &initial_required_permissions_->host_permissions,
+ error)) {
+ return false;
+ }
+
+ // Check for any permissions that are optional only.
+ for (APIPermissionSet::const_iterator iter =
+ initial_required_permissions_->api_permissions.begin();
+ iter != initial_required_permissions_->api_permissions.end(); ++iter) {
+ if ((*iter)->info()->must_be_optional()) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kPermissionMustBeOptional, (*iter)->info()->name());
+ return false;
+ }
+ }
+
+ // TODO(jeremya/kalman) do this via the features system by exposing the
+ // app.window API to platform apps, with no dependency on any permissions.
+ // See http://crbug.com/120069.
+ if (extension->is_platform_app()) {
+ initial_required_permissions_->api_permissions.insert(
+ APIPermission::kAppCurrentWindowInternal);
+ initial_required_permissions_->api_permissions.insert(
+ APIPermission::kAppRuntime);
+ initial_required_permissions_->api_permissions.insert(
+ APIPermission::kAppWindow);
+ }
+
+ initial_optional_permissions_.reset(new InitialPermissions);
+ if (!ParseHelper(extension,
+ keys::kOptionalPermissions,
+ &initial_optional_permissions_->api_permissions,
+ &initial_optional_permissions_->host_permissions,
+ error)) {
+ return false;
+ }
+
+ if (ContainsManifestForbiddenPermission(
+ initial_required_permissions_->api_permissions, error) ||
+ ContainsManifestForbiddenPermission(
+ initial_optional_permissions_->api_permissions, error)) {
+ return false;
+ }
+
+ return true;
+}
+
+void PermissionsData::FinalizePermissions(Extension* extension) {
+ URLPatternSet scriptable_hosts =
+ ContentScriptsInfo::GetScriptableHosts(extension);
+
+ extension->SetActivePermissions(new PermissionSet(
+ initial_required_permissions_->api_permissions,
+ initial_required_permissions_->host_permissions,
+ scriptable_hosts));
+
+ required_permission_set_ = new PermissionSet(
+ initial_required_permissions_->api_permissions,
+ initial_required_permissions_->host_permissions,
+ scriptable_hosts);
+
+ optional_permission_set_ = new PermissionSet(
+ initial_optional_permissions_->api_permissions,
+ initial_optional_permissions_->host_permissions,
+ URLPatternSet());
+
+ initial_required_permissions_.reset();
+ initial_optional_permissions_.reset();
+}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/permissions/permissions_data.h b/chrome/common/extensions/permissions/permissions_data.h
new file mode 100644
index 0000000..95c26c6
--- /dev/null
+++ b/chrome/common/extensions/permissions/permissions_data.h
@@ -0,0 +1,65 @@
+// Copyright (c) 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_PERMISSIONS_DATA_H_
+#define CHROME_COMMON_EXTENSIONS_PERMISSIONS_PERMISSIONS_DATA_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
+
+namespace extensions {
+
+class PermissionSet;
+class APIPermissionSet;
+class Extension;
+
+// A container for the permissions data of the extension; also responsible for
+// parsing the "permissions" and "optional_permissions" manifest keys.
+// This class holds the permissions which were established in the extension's
+// manifest; the runtime extensions of the extension (which may be different)
+// are stored in Extension::RuntimeData.
+class PermissionsData {
+ public:
+ PermissionsData();
+ ~PermissionsData();
+
+ // Parse the permissions of a given extension in the initialization process.
+ bool ParsePermissions(Extension* extension, string16* error);
+
+ // Finalize permissions after the initialization process completes.
+ void FinalizePermissions(Extension* extension);
+
+ // Return the optional or required permission set for the given |extension|.
+ static const PermissionSet* GetOptionalPermissions(
+ const Extension* extension);
+ static const PermissionSet* GetRequiredPermissions(
+ const Extension* extension);
+
+ // Return the temporary API permission set which is used during extension
+ // initialization. Once initialization completes, this is NULL.
+ static const APIPermissionSet* GetInitialAPIPermissions(
+ const Extension* extension);
+ static APIPermissionSet* GetInitialAPIPermissions(Extension* extension);
+
+ private:
+ struct InitialPermissions;
+
+ // Temporary permissions during the initialization process; NULL after
+ // initialization completes.
+ scoped_ptr<InitialPermissions> initial_required_permissions_;
+ scoped_ptr<InitialPermissions> initial_optional_permissions_;
+
+ // The set of permissions the extension can request at runtime.
+ scoped_refptr<const PermissionSet> optional_permission_set_;
+
+ // The extension's required / default set of permissions.
+ scoped_refptr<const PermissionSet> required_permission_set_;
+
+ DISALLOW_COPY_AND_ASSIGN(PermissionsData);
+};
+
+} // namespace extensions
+
+#endif // CHROME_COMMON_EXTENSIONS_PERMISSIONS_PERMISSIONS_DATA_H_