• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ChromeExtensionsClient()33 ChromeExtensionsClient::ChromeExtensionsClient()
34     :  chrome_api_permissions_(ChromeAPIPermissions()) {
35 }
36 
~ChromeExtensionsClient()37 ChromeExtensionsClient::~ChromeExtensionsClient() {
38 }
39 
Initialize()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&
GetPermissionsProvider() const59 ChromeExtensionsClient::GetPermissionsProvider() const {
60   return chrome_api_permissions_;
61 }
62 
63 const PermissionMessageProvider&
GetPermissionMessageProvider() const64 ChromeExtensionsClient::GetPermissionMessageProvider() const {
65   return permission_message_provider_;
66 }
67 
GetFeatureProviderByName(const std::string & name) const68 FeatureProvider* ChromeExtensionsClient::GetFeatureProviderByName(
69     const std::string& name) const {
70   return BaseFeatureProvider::GetByName(name);
71 }
72 
FilterHostPermissions(const URLPatternSet & hosts,URLPatternSet * new_hosts,std::set<PermissionMessage> * messages) const73 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 
SetScriptingWhitelist(const ExtensionsClient::ScriptingWhitelist & whitelist)95 void ChromeExtensionsClient::SetScriptingWhitelist(
96     const ExtensionsClient::ScriptingWhitelist& whitelist) {
97   scripting_whitelist_ = whitelist;
98 }
99 
100 const ExtensionsClient::ScriptingWhitelist&
GetScriptingWhitelist() const101 ChromeExtensionsClient::GetScriptingWhitelist() const {
102   return scripting_whitelist_;
103 }
104 
GetPermittedChromeSchemeHosts(const Extension * extension,const APIPermissionSet & api_permissions) const105 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 
IsScriptableURL(const GURL & url,std::string * error) const129 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
GetInstance()150 ChromeExtensionsClient* ChromeExtensionsClient::GetInstance() {
151   return g_client.Pointer();
152 }
153 
154 }  // namespace extensions
155