1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/features/simple_feature.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/debug/alias.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sha1.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/extension_api.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/features/feature_provider.h" 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "extensions/common/switches.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFeature::Availability IsAvailableToManifestForBind( 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& extension_id, 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Manifest::Type type, 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Manifest::Location location, 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int manifest_version, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Feature::Platform platform, 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Feature* feature) { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return feature->IsAvailableToManifest( 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_id, type, location, manifest_version, platform); 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 37116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFeature::Availability IsAvailableToContextForBind(const Extension* extension, 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Feature::Context context, 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url, 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Feature::Platform platform, 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Feature* feature) { 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return feature->IsAvailableToContext(extension, context, url, platform); 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct Mappings { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mappings() { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_types["extension"] = Manifest::TYPE_EXTENSION; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_types["theme"] = Manifest::TYPE_THEME; 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contexts["web_page"] = Feature::WEB_PAGE_CONTEXT; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT; 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) contexts["webui"] = Feature::WEBUI_CONTEXT; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch locations["component"] = SimpleFeature::COMPONENT_LOCATION; 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch locations["policy"] = SimpleFeature::POLICY_LOCATION; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) platforms["chromeos"] = Feature::CHROMEOS_PLATFORM; 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) platforms["linux"] = Feature::LINUX_PLATFORM; 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) platforms["mac"] = Feature::MACOSX_PLATFORM; 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) platforms["win"] = Feature::WIN_PLATFORM; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, Manifest::Type> extension_types; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, Feature::Context> contexts; 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::map<std::string, SimpleFeature::Location> locations; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, Feature::Platform> platforms; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(aa): Can we replace all this manual parsing with JSON schema stuff? 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ParseSet(const base::DictionaryValue* value, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& property, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<std::string>* set) { 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::ListValue* list_value = NULL; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!value->GetList(property, &list_value)) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set->clear(); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < list_value->GetSize(); ++i) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string str_val; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(list_value->GetString(i, &str_val)) << property << " " << i; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set->insert(str_val); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseEnum(const std::string& string_value, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T* enum_value, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<std::string, T>& mapping) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typename std::map<std::string, T>::const_iterator iter = 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mapping.find(string_value); 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (iter == mapping.end()) { 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // For http://crbug.com/365192. 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch char minidump[256]; 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::debug::Alias(&minidump); 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::snprintf(minidump, arraysize(minidump), 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "e::simple_feature.cc:%d:\"%s\"", __LINE__, string_value.c_str()); 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(false) << string_value; 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *enum_value = iter->second; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ParseEnum(const base::DictionaryValue* value, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& property, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T* enum_value, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<std::string, T>& mapping) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string string_value; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!value->GetString(property, &string_value)) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseEnum(string_value, enum_value, mapping); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ParseEnumSet(const base::DictionaryValue* value, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& property, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<T>* enum_set, 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<std::string, T>& mapping) { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!value->HasKey(property)) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum_set->clear(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string property_string; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value->GetString(property, &property_string)) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (property_string == "all") { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (typename std::map<std::string, T>::const_iterator j = 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mapping.begin(); j != mapping.end(); ++j) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum_set->insert(j->second); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<std::string> string_set; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseSet(value, property, &string_set); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<std::string>::iterator iter = string_set.begin(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != string_set.end(); ++iter) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) T enum_value = static_cast<T>(0); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseEnum(*iter, &enum_value, mapping); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum_set->insert(enum_value); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ParseURLPatterns(const base::DictionaryValue* value, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& key, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLPatternSet* set) { 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::ListValue* matches = NULL; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (value->GetList(key, &matches)) { 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) set->ClearPatterns(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < matches->GetSize(); ++i) { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string pattern; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(matches->GetString(i, &pattern)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set->AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Gets a human-readable name for the given extension type, suitable for giving 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// to developers in an error message. 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string GetDisplayName(Manifest::Type type) { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_UNKNOWN: 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "unknown"; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_EXTENSION: 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "extension"; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_HOSTED_APP: 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "hosted app"; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_LEGACY_PACKAGED_APP: 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "legacy packaged app"; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_PLATFORM_APP: 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "packaged app"; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_THEME: 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "theme"; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case Manifest::TYPE_USER_SCRIPT: 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "user script"; 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case Manifest::TYPE_SHARED_MODULE: 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return "shared module"; 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case Manifest::NUM_LOAD_TYPES: 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) NOTREACHED(); 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return ""; 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Gets a human-readable name for the given context type, suitable for giving 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// to developers in an error message. 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string GetDisplayName(Feature::Context context) { 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) switch (context) { 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case Feature::UNSPECIFIED_CONTEXT: 2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "unknown"; 2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case Feature::BLESSED_EXTENSION_CONTEXT: 2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // "privileged" is vague but hopefully the developer will understand that 2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // means background or app window. 2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "privileged page"; 2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case Feature::UNBLESSED_EXTENSION_CONTEXT: 2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // "iframe" is a bit of a lie/oversimplification, but that's the most 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // common unblessed context. 2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "extension iframe"; 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case Feature::CONTENT_SCRIPT_CONTEXT: 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "content script"; 2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case Feature::WEB_PAGE_CONTEXT: 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "web page"; 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case Feature::BLESSED_WEB_PAGE_CONTEXT: 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return "hosted app"; 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case Feature::WEBUI_CONTEXT: 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "webui"; 2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return ""; 2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Gets a human-readable list of the display names (pluralized, comma separated 2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// with the "and" in the correct place) for each of |enum_types|. 2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <typename EnumType> 2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string ListDisplayNames(const std::vector<EnumType> enum_types) { 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string display_name_list; 2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (size_t i = 0; i < enum_types.size(); ++i) { 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Pluralize type name. 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) display_name_list += GetDisplayName(enum_types[i]) + "s"; 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Comma-separate entries, with an Oxford comma if there is more than 2 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // total entries. 2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (enum_types.size() > 2) { 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (i < enum_types.size() - 2) 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) display_name_list += ", "; 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else if (i == enum_types.size() - 2) 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) display_name_list += ", and "; 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else if (enum_types.size() == 2 && i == 0) { 2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) display_name_list += " and "; 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return display_name_list; 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string HashExtensionId(const std::string& extension_id) { 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string id_hash = base::SHA1HashString(extension_id); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(id_hash.length() == base::kSHA1Length); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::HexEncode(id_hash.c_str(), id_hash.length()); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SimpleFeature::SimpleFeature() 254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : location_(UNSPECIFIED_LOCATION), 255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch min_manifest_version_(0), 256e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch max_manifest_version_(0), 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) has_parent_(false), 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) component_extensions_auto_granted_(true) {} 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 260e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochSimpleFeature::~SimpleFeature() {} 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SimpleFeature::HasDependencies() { 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return !dependencies_.empty(); 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 266e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { 267e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch filters_.push_back(make_linked_ptr(filter.release())); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string SimpleFeature::Parse(const base::DictionaryValue* value) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseURLPatterns(value, "matches", &matches_); 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ParseSet(value, "blacklist", &blacklist_); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseSet(value, "whitelist", &whitelist_); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ParseSet(value, "dependencies", &dependencies_); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_mappings.Get().extension_types); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseEnumSet<Context>(value, "contexts", &contexts_, 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_mappings.Get().contexts); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ParseEnum<Location>(value, "location", &location_, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_mappings.Get().locations); 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ParseEnumSet<Platform>(value, "platforms", &platforms_, 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_mappings.Get().platforms); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value->GetInteger("min_manifest_version", &min_manifest_version_); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value->GetInteger("max_manifest_version", &max_manifest_version_); 2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) no_parent_ = false; 2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) value->GetBoolean("noparent", &no_parent_); 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) component_extensions_auto_granted_ = true; 290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) value->GetBoolean("component_extensions_auto_granted", 291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &component_extensions_auto_granted_); 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // NOTE: ideally we'd sanity check that "matches" can be specified if and 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // only if there's a "web_page" or "webui" context, but without 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // (Simple)Features being aware of their own heirarchy this is impossible. 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // For example, we might have feature "foo" available to "web_page" context 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // and "matches" google.com/*. Then a sub-feature "foo.bar" might override 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "matches" to be chromium.org/*. That sub-feature doesn't need to specify 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "web_page" context because it's inherited, but we don't know that here. 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (FilterList::iterator filter_iter = filters_.begin(); 303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch filter_iter != filters_.end(); 304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ++filter_iter) { 305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::string result = (*filter_iter)->Parse(value); 306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!result.empty()) { 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return result; 308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability SimpleFeature::IsAvailableToManifest( 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Type type, 3170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Manifest::Location location, 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int manifest_version, 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Platform platform) const { 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check extension type first to avoid granting platform app permissions 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to component extensions. 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // HACK(kalman): user script -> extension. Solve this in a more generic way 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // when we compile feature files. 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Manifest::TYPE_EXTENSION : type; 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extension_types_.empty() && 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_types_.find(type_to_check) == extension_types_.end()) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CreateAvailability(INVALID_TYPE, type); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsIdInBlacklist(extension_id)) 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return CreateAvailability(FOUND_IN_BLACKLIST, type); 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(benwells): don't grant all component extensions. 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // See http://crbug.com/370375 for more details. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Component extensions can access any feature. 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // NOTE: Deliberately does not match EXTERNAL_COMPONENT. 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(IS_AVAILABLE, type); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!whitelist_.empty()) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsIdInWhitelist(extension_id)) { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(aa): This is gross. There should be a better way to test the 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // whitelist. 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string whitelist_switch_value = 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kWhitelistedExtensionID); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension_id != whitelist_switch_value) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!MatchesManifestLocation(location)) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(INVALID_LOCATION, type); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!platforms_.empty() && 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) platforms_.find(platform) == platforms_.end()) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(INVALID_PLATFORM, type); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 370e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (FilterList::const_iterator filter_iter = filters_.begin(); 371e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch filter_iter != filters_.end(); 372e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ++filter_iter) { 373e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Availability availability = (*filter_iter)->IsAvailableToManifest( 374e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extension_id, type, location, manifest_version, platform); 375e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!availability.is_available()) 376e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return availability; 377e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_id, 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch type, 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch location, 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch manifest_version, 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch platform)); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability SimpleFeature::IsAvailableToContext( 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SimpleFeature::Context context, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SimpleFeature::Platform platform) const { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) { 3930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Availability result = IsAvailableToManifest(extension->id(), 3940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension->GetType(), 3950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension->location(), 3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension->manifest_version(), 3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch platform); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result.is_available()) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!contexts_.empty() && contexts_.find(context) == contexts_.end()) 4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return CreateAvailability(INVALID_CONTEXT, context); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(kalman): Consider checking |matches_| regardless of context type. 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Fewer surprises, and if the feature configuration wants to isolate 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // "matches" from say "blessed_extension" then they can use complex features. 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !matches_.MatchesURL(url)) { 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateAvailability(INVALID_URL, url); 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 413e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (FilterList::const_iterator filter_iter = filters_.begin(); 414e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch filter_iter != filters_.end(); 415e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ++filter_iter) { 416e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Availability availability = 417e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch (*filter_iter)->IsAvailableToContext(extension, context, url, platform); 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!availability.is_available()) 419e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return availability; 420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 421e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(kalman): Assert that if the context was a webpage or WebUI context 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // then at some point a "matches" restriction was checked. 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return CheckDependencies(base::Bind( 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &IsAvailableToContextForBind, extension, context, url, platform)); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string SimpleFeature::GetAvailabilityMessage( 4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvailabilityResult result, 4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Manifest::Type type, 4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const GURL& url, 4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Context context) const { 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (result) { 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case IS_AVAILABLE: 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case NOT_FOUND_IN_WHITELIST: 437010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case FOUND_IN_BLACKLIST: 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' is not allowed for specified extension ID.", 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str()); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_URL: 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("'%s' is not allowed on %s.", 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str(), url.spec().c_str()); 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case INVALID_TYPE: 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "'%s' is only allowed for %s, but this is a %s.", 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str(), 4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ListDisplayNames(std::vector<Manifest::Type>( 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extension_types_.begin(), extension_types_.end())).c_str(), 4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetDisplayName(type).c_str()); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_CONTEXT: 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "'%s' is only allowed to run in %s, but this is a %s", 4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) name().c_str(), 4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ListDisplayNames(std::vector<Context>( 4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) contexts_.begin(), contexts_.end())).c_str(), 4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetDisplayName(context).c_str()); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_LOCATION: 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' is not allowed for specified install location.", 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str()); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_PLATFORM: 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' is not allowed for specified platform.", 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str()); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_MIN_MANIFEST_VERSION: 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' requires manifest version of at least %d.", 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str(), 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) min_manifest_version_); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case INVALID_MAX_MANIFEST_VERSION: 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' requires manifest version of %d or lower.", 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str(), 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_manifest_version_); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case NOT_PRESENT: 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "'%s' requires a different Feature that is not present.", 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name().c_str()); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case UNSUPPORTED_CHANNEL: 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 482e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "'%s' is unsupported in this version of the platform.", 483e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch name().c_str()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability SimpleFeature::CreateAvailability( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AvailabilityResult result) const { 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Availability( 4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), 4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UNSPECIFIED_CONTEXT)); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability SimpleFeature::CreateAvailability( 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AvailabilityResult result, Manifest::Type type) const { 4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return Availability(result, GetAvailabilityMessage(result, type, GURL(), 5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UNSPECIFIED_CONTEXT)); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability SimpleFeature::CreateAvailability( 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AvailabilityResult result, 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url) const { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Availability( 5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, 5088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UNSPECIFIED_CONTEXT)); 5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)Feature::Availability SimpleFeature::CreateAvailability( 5128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AvailabilityResult result, 5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Context context) const { 5148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return Availability( 5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), 5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) context)); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SimpleFeature::IsInternal() const { 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { 524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return IsIdInList(extension_id, blacklist_); 525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return IsIdInList(extension_id, whitelist_); 529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool SimpleFeature::IsIdInList(const std::string& extension_id, 533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<std::string>& list) { 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Belt-and-suspenders philosophy here. We should be pretty confident by this 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // point that we've validated the extension ID format, but in case something 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // slips through, we avoid a class of attack where creative ID manipulation 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leads to hash collisions. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (list.find(extension_id) != list.end() || 542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) list.find(HashExtensionId(extension_id)) != list.end()) { 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool SimpleFeature::MatchesManifestLocation( 5500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Manifest::Location manifest_location) const { 5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch switch (location_) { 5520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case SimpleFeature::UNSPECIFIED_LOCATION: 5530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 5540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case SimpleFeature::COMPONENT_LOCATION: 5550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? 5560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return manifest_location == Manifest::COMPONENT; 5570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case SimpleFeature::POLICY_LOCATION: 5580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return manifest_location == Manifest::EXTERNAL_POLICY || 5590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; 5600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 5610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NOTREACHED(); 5620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 5640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 565116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFeature::Availability SimpleFeature::CheckDependencies( 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::Callback<Availability(const Feature*)>& checker) const { 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::set<std::string>::const_iterator it = dependencies_.begin(); 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != dependencies_.end(); 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++it) { 570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Feature* dependency = 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionAPI::GetSharedInstance()->GetFeatureDependency(*it); 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!dependency) 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return CreateAvailability(NOT_PRESENT); 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Availability dependency_availability = checker.Run(dependency); 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!dependency_availability.is_available()) 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return dependency_availability; 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return CreateAvailability(IS_AVAILABLE); 579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 582