1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/common/extensions/chrome_extensions_client.h" 6 7 #include "base/command_line.h" 8 #include "chrome/common/extensions/chrome_manifest_handlers.h" 9 #include "chrome/common/extensions/extension_constants.h" 10 #include "chrome/common/extensions/features/base_feature_provider.h" 11 #include "chrome/common/url_constants.h" 12 #include "content/public/common/url_constants.h" 13 #include "extensions/common/extension.h" 14 #include "extensions/common/manifest_constants.h" 15 #include "extensions/common/permissions/api_permission_set.h" 16 #include "extensions/common/permissions/permission_message.h" 17 #include "extensions/common/switches.h" 18 #include "extensions/common/url_pattern.h" 19 #include "extensions/common/url_pattern_set.h" 20 #include "grit/generated_resources.h" 21 #include "ui/base/l10n/l10n_util.h" 22 #include "url/gurl.h" 23 24 namespace { 25 const char kThumbsWhiteListedExtension[] = "khopmbdjffemhegeeobelklnbglcdgfh"; 26 } // namespace 27 28 namespace extensions { 29 30 static base::LazyInstance<ChromeExtensionsClient> g_client = 31 LAZY_INSTANCE_INITIALIZER; 32 33 ChromeExtensionsClient::ChromeExtensionsClient() 34 : chrome_api_permissions_(ChromeAPIPermissions()) { 35 } 36 37 ChromeExtensionsClient::~ChromeExtensionsClient() { 38 } 39 40 void ChromeExtensionsClient::Initialize() { 41 RegisterChromeManifestHandlers(); 42 43 // Set up the scripting whitelist. 44 // Whitelist ChromeVox, an accessibility extension from Google that needs 45 // the ability to script webui pages. This is temporary and is not 46 // meant to be a general solution. 47 // TODO(dmazzoni): remove this once we have an extension API that 48 // allows any extension to request read-only access to webui pages. 49 scripting_whitelist_.push_back(extension_misc::kChromeVoxExtensionId); 50 51 // Whitelist "Discover DevTools Companion" extension from Google that 52 // needs the ability to script DevTools pages. Companion will assist 53 // online courses and will be needed while the online educational programs 54 // are in place. 55 scripting_whitelist_.push_back("angkfkebojeancgemegoedelbnjgcgme"); 56 } 57 58 const PermissionsProvider& 59 ChromeExtensionsClient::GetPermissionsProvider() const { 60 return chrome_api_permissions_; 61 } 62 63 const PermissionMessageProvider& 64 ChromeExtensionsClient::GetPermissionMessageProvider() const { 65 return permission_message_provider_; 66 } 67 68 FeatureProvider* ChromeExtensionsClient::GetFeatureProviderByName( 69 const std::string& name) const { 70 return BaseFeatureProvider::GetByName(name); 71 } 72 73 void ChromeExtensionsClient::FilterHostPermissions( 74 const URLPatternSet& hosts, 75 URLPatternSet* new_hosts, 76 std::set<PermissionMessage>* messages) const { 77 for (URLPatternSet::const_iterator i = hosts.begin(); 78 i != hosts.end(); ++i) { 79 // Filters out every URL pattern that matches chrome:// scheme. 80 if (i->scheme() == chrome::kChromeUIScheme) { 81 // chrome://favicon is the only URL for chrome:// scheme that we 82 // want to support. We want to deprecate the "chrome" scheme. 83 // We should not add any additional "host" here. 84 if (GURL(chrome::kChromeUIFaviconURL).host() != i->host()) 85 continue; 86 messages->insert(PermissionMessage( 87 PermissionMessage::kFavicon, 88 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FAVICON))); 89 } else { 90 new_hosts->AddPattern(*i); 91 } 92 } 93 } 94 95 void ChromeExtensionsClient::SetScriptingWhitelist( 96 const ExtensionsClient::ScriptingWhitelist& whitelist) { 97 scripting_whitelist_ = whitelist; 98 } 99 100 const ExtensionsClient::ScriptingWhitelist& 101 ChromeExtensionsClient::GetScriptingWhitelist() const { 102 return scripting_whitelist_; 103 } 104 105 URLPatternSet ChromeExtensionsClient::GetPermittedChromeSchemeHosts( 106 const Extension* extension, 107 const APIPermissionSet& api_permissions) const { 108 URLPatternSet hosts; 109 // Regular extensions are only allowed access to chrome://favicon. 110 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 111 chrome::kChromeUIFaviconURL)); 112 113 // Experimental extensions are also allowed chrome://thumb. 114 // 115 // TODO: A public API should be created for retrieving thumbnails. 116 // See http://crbug.com/222856. A temporary hack is implemented here to 117 // make chrome://thumbs available to NTP Russia extension as 118 // non-experimental. 119 if ((api_permissions.find(APIPermission::kExperimental) != 120 api_permissions.end()) || 121 (extension->id() == kThumbsWhiteListedExtension && 122 extension->from_webstore())) { 123 hosts.AddPattern(URLPattern(URLPattern::SCHEME_CHROMEUI, 124 chrome::kChromeUIThumbnailURL)); 125 } 126 return hosts; 127 } 128 129 bool ChromeExtensionsClient::IsScriptableURL( 130 const GURL& url, std::string* error) const { 131 // The gallery is special-cased as a restricted URL for scripting to prevent 132 // access to special JS bindings we expose to the gallery (and avoid things 133 // like extensions removing the "report abuse" link). 134 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing 135 // against the store app extent? 136 GURL store_url(extension_urls::GetWebstoreLaunchURL()); 137 if (CommandLine::ForCurrentProcess()->HasSwitch( 138 switches::kAllowScriptingGallery)) { 139 return true; 140 } 141 if (url.host() == store_url.host()) { 142 if (error) 143 *error = manifest_errors::kCannotScriptGallery; 144 return false; 145 } 146 return true; 147 } 148 149 // static 150 ChromeExtensionsClient* ChromeExtensionsClient::GetInstance() { 151 return g_client.Pointer(); 152 } 153 154 } // namespace extensions 155