diff options
Diffstat (limited to 'chrome/common/extensions/api/extension_api.cc')
-rw-r--r-- | chrome/common/extensions/api/extension_api.cc | 169 |
1 files changed, 56 insertions, 113 deletions
diff --git a/chrome/common/extensions/api/extension_api.cc b/chrome/common/extensions/api/extension_api.cc index 5bd45f9..f8909b0 100644 --- a/chrome/common/extensions/api/extension_api.cc +++ b/chrome/common/extensions/api/extension_api.cc @@ -15,7 +15,6 @@ #include "base/values.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_permission_set.h" -#include "googleurl/src/gurl.h" #include "grit/common_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -23,6 +22,22 @@ namespace extensions { namespace { +// Adds any APIs listed in "dependencies" found in |schema| but not in +// |reference| to |out|. +void GetMissingDependencies( + const DictionaryValue& schema, + const ExtensionAPI::SchemaMap& reference, + std::set<std::string>* out) { + ListValue* dependencies = NULL; + if (!schema.GetList("dependencies", &dependencies)) + return; + for (size_t i = 0; i < dependencies->GetSize(); ++i) { + std::string api_name; + if (dependencies->GetString(i, &api_name) && !reference.count(api_name)) + out->insert(api_name); + } +} + // Returns whether the list at |name_space_node|.|child_kind| contains any // children with an { "unprivileged": true } property. bool HasUnprivilegedChild(const DictionaryValue* name_space_node, @@ -80,7 +95,6 @@ void ExtensionAPI::LoadSchemaFromResource(int resource_id) { ExtensionAPI::ExtensionAPI() { static int kJsonApiResourceIds[] = { - IDR_EXTENSION_API_JSON_APP, IDR_EXTENSION_API_JSON_BOOKMARKS, IDR_EXTENSION_API_JSON_BROWSERACTION, IDR_EXTENSION_API_JSON_BROWSING_DATA, @@ -165,27 +179,6 @@ ExtensionAPI::ExtensionAPI() { partially_unprivileged_apis_.insert(it->first); } } - - // Populate |url_matching_apis_|. - for (SchemaMap::const_iterator it = schemas_.begin(); - it != schemas_.end(); ++it) { - ListValue* matches = NULL; - { - Value* matches_value = NULL; - if (!it->second->Get("matches", &matches_value)) - continue; - CHECK_EQ(Value::TYPE_LIST, matches_value->GetType()); - matches = static_cast<ListValue*>(matches_value); - } - URLPatternSet pattern_set; - for (size_t i = 0; i < matches->GetSize(); ++i) { - std::string pattern; - CHECK(matches->GetString(i, &pattern)); - pattern_set.AddPattern( - URLPattern(UserScript::kValidUserScriptSchemes, pattern)); - } - url_matching_apis_[it->first] = pattern_set; - } } ExtensionAPI::~ExtensionAPI() { @@ -265,109 +258,59 @@ const base::DictionaryValue* ExtensionAPI::GetSchema( return maybe_schema != schemas_.end() ? maybe_schema->second.get() : NULL; } -scoped_ptr<std::set<std::string> > ExtensionAPI::GetAPIsForContext( - Feature::Context context, - const Extension* extension, - const GURL& url) const { - scoped_ptr<std::set<std::string> > result(new std::set<std::string>()); - - switch (context) { - case Feature::UNSPECIFIED_CONTEXT: - break; - - case Feature::PRIVILEGED_CONTEXT: - // Availability is determined by the permissions of the extension. - CHECK(extension); - GetAllowedAPIs(extension, result.get()); - ResolveDependencies(result.get()); - break; - - case Feature::UNPRIVILEGED_CONTEXT: - case Feature::CONTENT_SCRIPT_CONTEXT: - // Availability is determined by the permissions of the extension - // (but only those APIs that are unprivileged). - CHECK(extension); - GetAllowedAPIs(extension, result.get()); - // Resolving dependencies before removing unprivileged APIs means that - // some unprivileged APIs may have unrealised dependencies. Too bad! - ResolveDependencies(result.get()); - RemovePrivilegedAPIs(result.get()); - break; - - case Feature::WEB_PAGE_CONTEXT: - // Availablility is determined by the url. - CHECK(url.is_valid()); - GetAPIsMatchingURL(url, result.get()); - break; - } - - return result.Pass(); -} - -void ExtensionAPI::GetAllowedAPIs( - const Extension* extension, std::set<std::string>* out) const { - for (SchemaMap::const_iterator i = schemas_.begin(); i != schemas_.end(); - ++i) { - if (extension->required_permission_set()->HasAnyAccessToAPI(i->first) || - extension->optional_permission_set()->HasAnyAccessToAPI(i->first)) { - out->insert(i->first); - } - } +void ExtensionAPI::GetSchemasForExtension(const Extension& extension, + GetSchemasFilter filter, + SchemaMap* out) const { + // Check both required_permissions and optional_permissions since we need + // to return all schemas that might be needed. + GetSchemasForPermissions(*extension.required_permission_set(), filter, out); + GetSchemasForPermissions(*extension.optional_permission_set(), filter, out); + + // Note that dependency resolution might introduce APIs outside of the filter + // (for example, "extensions" has unprivileged componenents but relies on + // "tabs" which doesn't). It doesn't matter because schema_generated_bindings + // does individual function/event based checking anyway, but it's a shame. + ResolveDependencies(out); } -void ExtensionAPI::ResolveDependencies(std::set<std::string>* out) const { +void ExtensionAPI::ResolveDependencies(SchemaMap* out) const { std::set<std::string> missing_dependencies; - for (std::set<std::string>::iterator i = out->begin(); i != out->end(); ++i) - GetMissingDependencies(*i, *out, &missing_dependencies); + for (SchemaMap::const_iterator i = out->begin(); i != out->end(); ++i) + GetMissingDependencies(*i->second, *out, &missing_dependencies); while (missing_dependencies.size()) { - std::string next = *missing_dependencies.begin(); - missing_dependencies.erase(next); - out->insert(next); - GetMissingDependencies(next, *out, &missing_dependencies); + std::string api_name = *missing_dependencies.begin(); + missing_dependencies.erase(api_name); + linked_ptr<const DictionaryValue> schema = schemas_.find(api_name)->second; + (*out)[api_name] = schema; + GetMissingDependencies(*schema, *out, &missing_dependencies); } } -void ExtensionAPI::GetMissingDependencies( - const std::string& api_name, - const std::set<std::string>& excluding, - std::set<std::string>* out) const { - const base::DictionaryValue* schema = GetSchema(api_name); - CHECK(schema) << "Schema for " << api_name << " not found"; - - ListValue* dependencies = NULL; - if (!schema->GetList("dependencies", &dependencies)) - return; - - for (size_t i = 0; i < dependencies->GetSize(); ++i) { - std::string api_name; - if (dependencies->GetString(i, &api_name) && !excluding.count(api_name)) - out->insert(api_name); - } +void ExtensionAPI::GetDefaultSchemas(GetSchemasFilter filter, + SchemaMap* out) const { + scoped_refptr<ExtensionPermissionSet> default_permissions( + new ExtensionPermissionSet()); + GetSchemasForPermissions(*default_permissions, filter, out); + ResolveDependencies(out); } -void ExtensionAPI::RemovePrivilegedAPIs(std::set<std::string>* apis) const { - std::set<std::string> privileged_apis; - for (std::set<std::string>::iterator i = apis->begin(); i != apis->end(); - ++i) { - if (!completely_unprivileged_apis_.count(*i) && - !partially_unprivileged_apis_.count(*i)) { - privileged_apis.insert(*i); - } - } - for (std::set<std::string>::iterator i = privileged_apis.begin(); - i != privileged_apis.end(); ++i) { - apis->erase(*i); +void ExtensionAPI::GetSchemasForPermissions( + const ExtensionPermissionSet& permissions, + GetSchemasFilter filter, + SchemaMap* out) const { + for (SchemaMap::const_iterator it = schemas_.begin(); it != schemas_.end(); + ++it) { + if (filter == ONLY_UNPRIVILEGED && IsWholeAPIPrivileged(it->first)) + continue; + if (permissions.HasAnyAccessToAPI(it->first)) + (*out)[it->first] = it->second; } } -void ExtensionAPI::GetAPIsMatchingURL(const GURL& url, - std::set<std::string>* out) const { - for (std::map<std::string, URLPatternSet>::const_iterator i = - url_matching_apis_.begin(); i != url_matching_apis_.end(); ++i) { - if (i->second.MatchesURL(url)) - out->insert(i->first); - } +bool ExtensionAPI::IsWholeAPIPrivileged(const std::string& api_name) const { + return !completely_unprivileged_apis_.count(api_name) && + !partially_unprivileged_apis_.count(api_name); } } // namespace extensions |