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 |
107 : public ManifestPermission { | 29 : public ManifestPermission { |
108 public: | 30 public: |
109 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) | 31 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) |
110 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} | 32 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} |
111 | 33 |
112 // extensions::ManifestPermission overrides. | 34 // extensions::ManifestPermission overrides. |
113 virtual std::string name() const OVERRIDE { | 35 virtual std::string name() const OVERRIDE { |
114 return manifest_keys::kSettingsOverride; | 36 return manifest_keys::kUIOverride; |
115 } | 37 } |
116 | 38 |
117 virtual std::string id() const OVERRIDE { | 39 virtual std::string id() const OVERRIDE { |
118 return name(); | 40 return name(); |
119 } | 41 } |
120 | 42 |
121 virtual bool HasMessages() const OVERRIDE { | 43 virtual bool HasMessages() const OVERRIDE { |
122 return override_bookmarks_ui_permission_; | 44 return override_bookmarks_ui_permission_; |
123 } | 45 } |
124 | 46 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 } | 125 } |
204 | 126 |
205 virtual void Log(std::string* log) const OVERRIDE { | 127 virtual void Log(std::string* log) const OVERRIDE { |
206 IPC::LogParam(override_bookmarks_ui_permission_, log); | 128 IPC::LogParam(override_bookmarks_ui_permission_, log); |
207 } | 129 } |
208 | 130 |
209 private: | 131 private: |
210 bool override_bookmarks_ui_permission_; | 132 bool override_bookmarks_ui_permission_; |
211 }; | 133 }; |
212 | 134 |
213 SettingsOverrides::SettingsOverrides() {} | 135 UIOverrides::UIOverrides() {} |
214 | 136 |
215 SettingsOverrides::~SettingsOverrides() {} | 137 UIOverrides::~UIOverrides() {} |
216 | 138 |
217 const SettingsOverrides* SettingsOverrides::Get( | 139 const UIOverrides* UIOverrides::Get( |
218 const Extension* extension) { | 140 const Extension* extension) { |
219 return static_cast<SettingsOverrides*>( | 141 return static_cast<UIOverrides*>( |
220 extension->GetManifestData(manifest_keys::kSettingsOverride)); | 142 extension->GetManifestData(manifest_keys::kUIOverride)); |
221 } | 143 } |
222 | 144 |
223 bool SettingsOverrides::RemovesBookmarkButton( | 145 bool UIOverrides::RemovesBookmarkButton(const UIOverrides& ui_overrides) { |
224 const SettingsOverrides& settings_overrides) { | 146 return ui_overrides.bookmarks_ui && |
225 return settings_overrides.bookmarks_ui && | 147 ui_overrides.bookmarks_ui->remove_button && |
226 settings_overrides.bookmarks_ui->remove_button && | 148 *ui_overrides.bookmarks_ui->remove_button; |
227 *settings_overrides.bookmarks_ui->remove_button; | |
228 } | 149 } |
229 | 150 |
230 bool SettingsOverrides::RemovesBookmarkShortcut( | 151 bool UIOverrides::RemovesBookmarkShortcut(const UIOverrides& ui_overrides) { |
231 const SettingsOverrides& settings_overrides) { | 152 return ui_overrides.bookmarks_ui && |
232 return settings_overrides.bookmarks_ui && | 153 ui_overrides.bookmarks_ui->remove_bookmark_shortcut && |
233 settings_overrides.bookmarks_ui->remove_bookmark_shortcut && | 154 *ui_overrides.bookmarks_ui->remove_bookmark_shortcut; |
234 *settings_overrides.bookmarks_ui->remove_bookmark_shortcut; | |
235 } | 155 } |
236 | 156 |
237 SettingsOverridesHandler::SettingsOverridesHandler() {} | 157 UIOverridesHandler::UIOverridesHandler() {} |
238 | 158 |
239 SettingsOverridesHandler::~SettingsOverridesHandler() {} | 159 UIOverridesHandler::~UIOverridesHandler() {} |
240 | 160 |
241 bool SettingsOverridesHandler::Parse(Extension* extension, | 161 bool UIOverridesHandler::Parse(Extension* extension, base::string16* error) { |
242 base::string16* error) { | |
243 const base::Value* dict = NULL; | 162 const base::Value* dict = NULL; |
244 CHECK(extension->manifest()->Get(manifest_keys::kSettingsOverride, &dict)); | 163 CHECK(extension->manifest()->Get(manifest_keys::kUIOverride, &dict)); |
245 scoped_ptr<ChromeSettingsOverrides> settings( | 164 scoped_ptr<ChromeUIOverrides> overrides( |
246 ChromeSettingsOverrides::FromValue(*dict, error)); | 165 ChromeUIOverrides::FromValue(*dict, error)); |
247 if (!settings) | 166 if (!overrides) |
248 return false; | 167 return false; |
249 | 168 |
250 scoped_ptr<SettingsOverrides> info(new SettingsOverrides); | 169 scoped_ptr<UIOverrides> info(new UIOverrides); |
251 info->bookmarks_ui.swap(settings->bookmarks_ui); | 170 info->bookmarks_ui.swap(overrides->bookmarks_ui); |
252 // Support backward compatibility for deprecated key | 171 if (!info->bookmarks_ui) { |
253 // chrome_settings_overrides.bookmarks_ui.hide_bookmark_button. | 172 *error = ErrorUtils::FormatErrorMessageUTF16( |
254 if (info->bookmarks_ui && !info->bookmarks_ui->remove_button && | 173 manifest_errors::kInvalidEmptyDictionary, |
255 info->bookmarks_ui->hide_bookmark_button) { | 174 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; | 175 return false; |
267 } | 176 } |
268 info->manifest_permission.reset(new ManifestPermissionImpl( | 177 info->manifest_permission.reset(new ManifestPermissionImpl( |
269 SettingsOverrides::RemovesBookmarkButton(*info))); | 178 UIOverrides::RemovesBookmarkButton(*info))); |
270 | 179 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; | 180 return true; |
295 } | 181 } |
296 | 182 |
297 bool SettingsOverridesHandler::Validate( | 183 bool UIOverridesHandler::Validate( |
298 const Extension* extension, | 184 const Extension* extension, |
299 std::string* error, | 185 std::string* error, |
300 std::vector<InstallWarning>* warnings) const { | 186 std::vector<InstallWarning>* warnings) const { |
301 const SettingsOverrides* settings_overrides = | 187 const UIOverrides* ui_overrides = UIOverrides::Get(extension); |
302 SettingsOverrides::Get(extension); | |
303 | 188 |
304 if (settings_overrides && settings_overrides->bookmarks_ui) { | 189 if (ui_overrides && ui_overrides->bookmarks_ui) { |
305 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { | 190 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { |
306 warnings->push_back(InstallWarning( | 191 warnings->push_back(InstallWarning( |
307 ErrorUtils::FormatErrorMessage( | 192 ErrorUtils::FormatErrorMessage( |
308 manifest_errors::kUnrecognizedManifestKey, | 193 manifest_errors::kUnrecognizedManifestKey, |
309 manifest_keys::kBookmarkUI))); | 194 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 } | 195 } |
317 } | 196 } |
318 | 197 |
319 return true; | 198 return true; |
320 } | 199 } |
321 | 200 |
322 ManifestPermission* SettingsOverridesHandler::CreatePermission() { | 201 ManifestPermission* UIOverridesHandler::CreatePermission() { |
323 return new ManifestPermissionImpl(false); | 202 return new ManifestPermissionImpl(false); |
324 } | 203 } |
325 | 204 |
326 ManifestPermission* SettingsOverridesHandler::CreateInitialRequiredPermission( | 205 ManifestPermission* UIOverridesHandler::CreateInitialRequiredPermission( |
327 const Extension* extension) { | 206 const Extension* extension) { |
328 const SettingsOverrides* data = SettingsOverrides::Get(extension); | 207 const UIOverrides* data = UIOverrides::Get(extension); |
329 if (data) | 208 if (data) |
330 return data->manifest_permission->Clone(); | 209 return data->manifest_permission->Clone(); |
331 return NULL; | 210 return NULL; |
332 } | 211 } |
333 const std::vector<std::string> SettingsOverridesHandler::Keys() const { | 212 const std::vector<std::string> UIOverridesHandler::Keys() const { |
334 return SingleKey(manifest_keys::kSettingsOverride); | 213 return SingleKey(manifest_keys::kUIOverride); |
335 } | 214 } |
336 | 215 |
337 } // namespace extensions | 216 } // namespace extensions |
OLD | NEW |