OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" | 5 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/strings/stringprintf.h" | |
10 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
11 #include "base/values.h" | 10 #include "base/values.h" |
12 #include "chrome/common/extensions/extension_messages.h" | 11 #include "chrome/common/extensions/extension_messages.h" |
13 #include "chrome/common/extensions/permissions/settings_override_permission.h" | |
14 #include "extensions/common/error_utils.h" | 12 #include "extensions/common/error_utils.h" |
15 #include "extensions/common/feature_switch.h" | 13 #include "extensions/common/feature_switch.h" |
16 #include "extensions/common/manifest_constants.h" | 14 #include "extensions/common/manifest_constants.h" |
17 #include "extensions/common/permissions/api_permission_set.h" | |
18 #include "extensions/common/permissions/manifest_permission.h" | 15 #include "extensions/common/permissions/manifest_permission.h" |
19 #include "extensions/common/permissions/permissions_data.h" | 16 #include "extensions/common/permissions/permissions_data.h" |
20 #include "extensions/common/permissions/permissions_info.h" | 17 #include "extensions/common/permissions/permissions_info.h" |
21 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
22 #include "ipc/ipc_message.h" | 19 #include "ipc/ipc_message.h" |
23 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
24 #include "url/gurl.h" | |
25 | 21 |
26 using extensions::api::manifest_types::ChromeSettingsOverrides; | 22 using extensions::api::manifest_types::ChromeUIOverrides; |
27 | 23 |
28 namespace extensions { | 24 namespace extensions { |
29 namespace { | |
30 | |
31 const char* kWwwPrefix = "www."; | |
32 | |
33 scoped_ptr<GURL> CreateManifestURL(const std::string& url) { | |
34 scoped_ptr<GURL> manifest_url(new GURL(url)); | |
35 if (!manifest_url->is_valid() || | |
36 !manifest_url->SchemeIsHTTPOrHTTPS()) | |
37 return scoped_ptr<GURL>(); | |
38 return manifest_url.Pass(); | |
39 } | |
40 | |
41 scoped_ptr<GURL> ParseHomepage(const ChromeSettingsOverrides& overrides, | |
42 base::string16* error) { | |
43 if (!overrides.homepage) | |
44 return scoped_ptr<GURL>(); | |
45 scoped_ptr<GURL> manifest_url = CreateManifestURL(*overrides.homepage); | |
46 if (!manifest_url) { | |
47 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
48 manifest_errors::kInvalidHomepageOverrideURL, *overrides.homepage); | |
49 } | |
50 return manifest_url.Pass(); | |
51 } | |
52 | |
53 std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides, | |
54 base::string16* error) { | |
55 std::vector<GURL> urls; | |
56 if (!overrides.startup_pages) | |
57 return urls; | |
58 | |
59 for (std::vector<std::string>::const_iterator i = | |
60 overrides.startup_pages->begin(); i != overrides.startup_pages->end(); | |
61 ++i) { | |
62 scoped_ptr<GURL> manifest_url = CreateManifestURL(*i); | |
63 if (!manifest_url) { | |
64 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
65 manifest_errors::kInvalidStartupOverrideURL, *i); | |
66 } else { | |
67 urls.push_back(GURL()); | |
68 urls.back().Swap(manifest_url.get()); | |
69 } | |
70 } | |
71 return urls; | |
72 } | |
73 | |
74 scoped_ptr<ChromeSettingsOverrides::Search_provider> ParseSearchEngine( | |
75 ChromeSettingsOverrides* overrides, | |
76 base::string16* error) { | |
77 if (!overrides->search_provider) | |
78 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
79 if (!CreateManifestURL(overrides->search_provider->favicon_url)) { | |
80 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
81 manifest_errors::kInvalidSearchEngineURL, | |
82 overrides->search_provider->favicon_url); | |
83 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
84 } | |
85 if (!CreateManifestURL(overrides->search_provider->search_url)) { | |
86 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
87 manifest_errors::kInvalidSearchEngineURL, | |
88 overrides->search_provider->search_url); | |
89 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
90 } | |
91 return overrides->search_provider.Pass(); | |
92 } | |
93 | |
94 // A www. prefix is not informative and thus not worth the limited real estate | |
95 // in the permissions UI. | |
96 std::string RemoveWwwPrefix(const std::string& url) { | |
97 if (StartsWithASCII(url, kWwwPrefix, false)) | |
98 return url.substr(strlen(kWwwPrefix)); | |
99 return url; | |
100 } | |
101 | |
102 } // namespace | |
103 | 25 |
104 // The manifest permission implementation supports a permission for overriding | 26 // The manifest permission implementation supports a permission for overriding |
105 // the bookmark UI. | 27 // the bookmark UI. |
106 class SettingsOverridesHandler::ManifestPermissionImpl | 28 class UIOverridesHandler::ManifestPermissionImpl : public ManifestPermission { |
107 : public ManifestPermission { | |
108 public: | 29 public: |
109 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) | 30 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) |
110 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} | 31 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} |
111 | 32 |
112 // extensions::ManifestPermission overrides. | 33 // extensions::ManifestPermission overrides. |
113 virtual std::string name() const OVERRIDE { | 34 virtual std::string name() const OVERRIDE { |
114 return manifest_keys::kSettingsOverride; | 35 return manifest_keys::kUIOverride; |
115 } | 36 } |
116 | 37 |
117 virtual std::string id() const OVERRIDE { | 38 virtual std::string id() const OVERRIDE { |
118 return name(); | 39 return name(); |
119 } | 40 } |
120 | 41 |
121 virtual bool HasMessages() const OVERRIDE { | 42 virtual bool HasMessages() const OVERRIDE { |
122 return override_bookmarks_ui_permission_; | 43 return override_bookmarks_ui_permission_; |
123 } | 44 } |
124 | 45 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 } | 124 } |
204 | 125 |
205 virtual void Log(std::string* log) const OVERRIDE { | 126 virtual void Log(std::string* log) const OVERRIDE { |
206 IPC::LogParam(override_bookmarks_ui_permission_, log); | 127 IPC::LogParam(override_bookmarks_ui_permission_, log); |
207 } | 128 } |
208 | 129 |
209 private: | 130 private: |
210 bool override_bookmarks_ui_permission_; | 131 bool override_bookmarks_ui_permission_; |
211 }; | 132 }; |
212 | 133 |
213 SettingsOverrides::SettingsOverrides() {} | 134 UIOverrides::UIOverrides() {} |
214 | 135 |
215 SettingsOverrides::~SettingsOverrides() {} | 136 UIOverrides::~UIOverrides() {} |
216 | 137 |
217 const SettingsOverrides* SettingsOverrides::Get( | 138 const UIOverrides* UIOverrides::Get(const Extension* extension) { |
218 const Extension* extension) { | 139 return static_cast<UIOverrides*>( |
219 return static_cast<SettingsOverrides*>( | 140 extension->GetManifestData(manifest_keys::kUIOverride)); |
220 extension->GetManifestData(manifest_keys::kSettingsOverride)); | |
221 } | 141 } |
222 | 142 |
223 bool SettingsOverrides::RemovesBookmarkButton( | 143 bool UIOverrides::RemovesBookmarkButton(const UIOverrides& ui_overrides) { |
224 const SettingsOverrides& settings_overrides) { | 144 return ui_overrides.bookmarks_ui && |
225 return settings_overrides.bookmarks_ui && | 145 ui_overrides.bookmarks_ui->remove_button && |
226 settings_overrides.bookmarks_ui->remove_button && | 146 *ui_overrides.bookmarks_ui->remove_button; |
227 *settings_overrides.bookmarks_ui->remove_button; | |
228 } | 147 } |
229 | 148 |
230 bool SettingsOverrides::RemovesBookmarkShortcut( | 149 bool UIOverrides::RemovesBookmarkShortcut(const UIOverrides& ui_overrides) { |
231 const SettingsOverrides& settings_overrides) { | 150 return ui_overrides.bookmarks_ui && |
232 return settings_overrides.bookmarks_ui && | 151 ui_overrides.bookmarks_ui->remove_bookmark_shortcut && |
233 settings_overrides.bookmarks_ui->remove_bookmark_shortcut && | 152 *ui_overrides.bookmarks_ui->remove_bookmark_shortcut; |
234 *settings_overrides.bookmarks_ui->remove_bookmark_shortcut; | |
235 } | 153 } |
236 | 154 |
237 SettingsOverridesHandler::SettingsOverridesHandler() {} | 155 UIOverridesHandler::UIOverridesHandler() {} |
238 | 156 |
239 SettingsOverridesHandler::~SettingsOverridesHandler() {} | 157 UIOverridesHandler::~UIOverridesHandler() {} |
240 | 158 |
241 bool SettingsOverridesHandler::Parse(Extension* extension, | 159 bool UIOverridesHandler::Parse(Extension* extension, base::string16* error) { |
242 base::string16* error) { | |
243 const base::Value* dict = NULL; | 160 const base::Value* dict = NULL; |
244 CHECK(extension->manifest()->Get(manifest_keys::kSettingsOverride, &dict)); | 161 CHECK(extension->manifest()->Get(manifest_keys::kUIOverride, &dict)); |
245 scoped_ptr<ChromeSettingsOverrides> settings( | 162 scoped_ptr<ChromeUIOverrides> overrides( |
246 ChromeSettingsOverrides::FromValue(*dict, error)); | 163 ChromeUIOverrides::FromValue(*dict, error)); |
247 if (!settings) | 164 if (!overrides) |
248 return false; | 165 return false; |
249 | 166 |
250 scoped_ptr<SettingsOverrides> info(new SettingsOverrides); | 167 scoped_ptr<UIOverrides> info(new UIOverrides); |
251 info->bookmarks_ui.swap(settings->bookmarks_ui); | 168 info->bookmarks_ui.swap(overrides->bookmarks_ui); |
252 // Support backward compatibility for deprecated key | 169 if (!info->bookmarks_ui) { |
253 // chrome_settings_overrides.bookmarks_ui.hide_bookmark_button. | 170 *error = ErrorUtils::FormatErrorMessageUTF16( |
254 if (info->bookmarks_ui && !info->bookmarks_ui->remove_button && | 171 manifest_errors::kInvalidEmptyDictionary, |
255 info->bookmarks_ui->hide_bookmark_button) { | 172 manifest_keys::kUIOverride); |
256 info->bookmarks_ui->remove_button.reset( | |
257 new bool(*info->bookmarks_ui->hide_bookmark_button)); | |
258 } | |
259 info->homepage = ParseHomepage(*settings, error); | |
260 info->search_engine = ParseSearchEngine(settings.get(), error); | |
261 info->startup_pages = ParseStartupPage(*settings, error); | |
262 if (!info->bookmarks_ui && !info->homepage && | |
263 !info->search_engine && info->startup_pages.empty()) { | |
264 *error = | |
265 base::ASCIIToUTF16(manifest_errors::kInvalidEmptySettingsOverrides); | |
266 return false; | 173 return false; |
267 } | 174 } |
268 info->manifest_permission.reset(new ManifestPermissionImpl( | 175 info->manifest_permission.reset(new ManifestPermissionImpl( |
269 SettingsOverrides::RemovesBookmarkButton(*info))); | 176 UIOverrides::RemovesBookmarkButton(*info))); |
270 | 177 extension->SetManifestData(manifest_keys::kUIOverride, info.release()); |
271 APIPermissionSet* permission_set = | |
272 PermissionsData::GetInitialAPIPermissions(extension); | |
273 DCHECK(permission_set); | |
274 if (info->search_engine) { | |
275 permission_set->insert(new SettingsOverrideAPIPermission( | |
276 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSearchProvider), | |
277 RemoveWwwPrefix(CreateManifestURL(info->search_engine->search_url)-> | |
278 GetOrigin().host()))); | |
279 } | |
280 if (!info->startup_pages.empty()) { | |
281 permission_set->insert(new SettingsOverrideAPIPermission( | |
282 PermissionsInfo::GetInstance()->GetByID(APIPermission::kStartupPages), | |
283 // We only support one startup page even though the type of the manifest | |
284 // property is a list, only the first one is used. | |
285 RemoveWwwPrefix(info->startup_pages[0].GetContent()))); | |
286 } | |
287 if (info->homepage) { | |
288 permission_set->insert(new SettingsOverrideAPIPermission( | |
289 PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage), | |
290 RemoveWwwPrefix(info->homepage.get()->GetContent()))); | |
291 } | |
292 extension->SetManifestData(manifest_keys::kSettingsOverride, | |
293 info.release()); | |
294 return true; | 178 return true; |
295 } | 179 } |
296 | 180 |
297 bool SettingsOverridesHandler::Validate( | 181 bool UIOverridesHandler::Validate(const Extension* extension, |
298 const Extension* extension, | 182 std::string* error, |
299 std::string* error, | 183 std::vector<InstallWarning>* warnings) const { |
300 std::vector<InstallWarning>* warnings) const { | 184 const UIOverrides* ui_overrides = UIOverrides::Get(extension); |
301 const SettingsOverrides* settings_overrides = | |
302 SettingsOverrides::Get(extension); | |
303 | 185 |
304 if (settings_overrides && settings_overrides->bookmarks_ui) { | 186 if (ui_overrides && ui_overrides->bookmarks_ui) { |
305 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { | 187 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { |
306 warnings->push_back(InstallWarning( | 188 warnings->push_back(InstallWarning( |
307 ErrorUtils::FormatErrorMessage( | 189 ErrorUtils::FormatErrorMessage( |
308 manifest_errors::kUnrecognizedManifestKey, | 190 manifest_errors::kUnrecognizedManifestKey, |
309 manifest_keys::kBookmarkUI))); | 191 manifest_keys::kBookmarkUI))); |
310 } else if (settings_overrides->bookmarks_ui->hide_bookmark_button) { | |
311 warnings->push_back(InstallWarning( | |
312 ErrorUtils::FormatErrorMessage( | |
313 manifest_errors::kKeyIsDeprecatedWithReplacement, | |
314 manifest_keys::kHideBookmarkButton, | |
315 manifest_keys::kRemoveButton))); | |
316 } | 192 } |
317 } | 193 } |
318 | 194 |
319 return true; | 195 return true; |
320 } | 196 } |
321 | 197 |
322 ManifestPermission* SettingsOverridesHandler::CreatePermission() { | 198 ManifestPermission* UIOverridesHandler::CreatePermission() { |
323 return new ManifestPermissionImpl(false); | 199 return new ManifestPermissionImpl(false); |
324 } | 200 } |
325 | 201 |
326 ManifestPermission* SettingsOverridesHandler::CreateInitialRequiredPermission( | 202 ManifestPermission* UIOverridesHandler::CreateInitialRequiredPermission( |
327 const Extension* extension) { | 203 const Extension* extension) { |
328 const SettingsOverrides* data = SettingsOverrides::Get(extension); | 204 const UIOverrides* data = UIOverrides::Get(extension); |
329 if (data) | 205 if (data) |
330 return data->manifest_permission->Clone(); | 206 return data->manifest_permission->Clone(); |
331 return NULL; | 207 return NULL; |
332 } | 208 } |
333 const std::vector<std::string> SettingsOverridesHandler::Keys() const { | 209 const std::vector<std::string> UIOverridesHandler::Keys() const { |
334 return SingleKey(manifest_keys::kSettingsOverride); | 210 return SingleKey(manifest_keys::kUIOverride); |
335 } | 211 } |
336 | 212 |
337 } // namespace extensions | 213 } // namespace extensions |
OLD | NEW |