Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / common / extensions / manifest_handlers / settings_overrides_handler.cc
blob5b9c84397bd13f9b354446d78d4de7d4e47a3333
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.
5 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "extensions/common/error_utils.h"
13 #include "extensions/common/extension_set.h"
14 #include "extensions/common/feature_switch.h"
15 #include "extensions/common/manifest_constants.h"
16 #include "extensions/common/manifest_handlers/permissions_parser.h"
17 #include "extensions/common/permissions/api_permission_set.h"
18 #include "extensions/common/permissions/manifest_permission.h"
19 #include "extensions/common/permissions/permissions_info.h"
20 #include "extensions/common/permissions/settings_override_permission.h"
21 #include "ipc/ipc_message.h"
22 #include "ipc/ipc_message_utils.h"
23 #include "url/gurl.h"
25 using extensions::api::manifest_types::ChromeSettingsOverrides;
27 namespace extensions {
28 namespace {
30 const char kWwwPrefix[] = "www.";
32 scoped_ptr<GURL> CreateManifestURL(const std::string& url) {
33 scoped_ptr<GURL> manifest_url(new GURL(url));
34 if (!manifest_url->is_valid() ||
35 !manifest_url->SchemeIsHTTPOrHTTPS())
36 return scoped_ptr<GURL>();
37 return manifest_url.Pass();
40 scoped_ptr<GURL> ParseHomepage(const ChromeSettingsOverrides& overrides,
41 base::string16* error) {
42 if (!overrides.homepage)
43 return scoped_ptr<GURL>();
44 scoped_ptr<GURL> manifest_url = CreateManifestURL(*overrides.homepage);
45 if (!manifest_url) {
46 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
47 manifest_errors::kInvalidHomepageOverrideURL, *overrides.homepage);
49 return manifest_url.Pass();
52 std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides,
53 base::string16* error) {
54 std::vector<GURL> urls;
55 if (!overrides.startup_pages)
56 return urls;
58 for (std::vector<std::string>::const_iterator i =
59 overrides.startup_pages->begin(); i != overrides.startup_pages->end();
60 ++i) {
61 scoped_ptr<GURL> manifest_url = CreateManifestURL(*i);
62 if (!manifest_url) {
63 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
64 manifest_errors::kInvalidStartupOverrideURL, *i);
65 } else {
66 urls.push_back(GURL());
67 urls.back().Swap(manifest_url.get());
70 return urls;
73 scoped_ptr<ChromeSettingsOverrides::Search_provider> ParseSearchEngine(
74 ChromeSettingsOverrides* overrides,
75 base::string16* error) {
76 if (!overrides->search_provider)
77 return scoped_ptr<ChromeSettingsOverrides::Search_provider>();
78 if (!CreateManifestURL(overrides->search_provider->search_url)) {
79 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
80 manifest_errors::kInvalidSearchEngineURL,
81 overrides->search_provider->search_url);
82 return scoped_ptr<ChromeSettingsOverrides::Search_provider>();
84 if (overrides->search_provider->prepopulated_id)
85 return overrides->search_provider.Pass();
86 if (!overrides->search_provider->name ||
87 !overrides->search_provider->keyword ||
88 !overrides->search_provider->encoding ||
89 !overrides->search_provider->favicon_url) {
90 *error =
91 base::ASCIIToUTF16(manifest_errors::kInvalidSearchEngineMissingKeys);
92 return scoped_ptr<ChromeSettingsOverrides::Search_provider>();
94 if (!CreateManifestURL(*overrides->search_provider->favicon_url)) {
95 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
96 manifest_errors::kInvalidSearchEngineURL,
97 *overrides->search_provider->favicon_url);
98 return scoped_ptr<ChromeSettingsOverrides::Search_provider>();
100 return overrides->search_provider.Pass();
103 // A www. prefix is not informative and thus not worth the limited real estate
104 // in the permissions UI.
105 std::string RemoveWwwPrefix(const std::string& url) {
106 if (base::StartsWith(url, kWwwPrefix, base::CompareCase::INSENSITIVE_ASCII))
107 return url.substr(strlen(kWwwPrefix));
108 return url;
111 } // namespace
113 SettingsOverrides::SettingsOverrides() {}
115 SettingsOverrides::~SettingsOverrides() {}
117 // static
118 const SettingsOverrides* SettingsOverrides::Get(
119 const Extension* extension) {
120 return static_cast<SettingsOverrides*>(
121 extension->GetManifestData(manifest_keys::kSettingsOverride));
124 SettingsOverridesHandler::SettingsOverridesHandler() {}
126 SettingsOverridesHandler::~SettingsOverridesHandler() {}
128 bool SettingsOverridesHandler::Parse(Extension* extension,
129 base::string16* error) {
130 const base::Value* dict = NULL;
131 CHECK(extension->manifest()->Get(manifest_keys::kSettingsOverride, &dict));
132 scoped_ptr<ChromeSettingsOverrides> settings(
133 ChromeSettingsOverrides::FromValue(*dict, error));
134 if (!settings)
135 return false;
137 scoped_ptr<SettingsOverrides> info(new SettingsOverrides);
138 info->homepage = ParseHomepage(*settings, error);
139 info->search_engine = ParseSearchEngine(settings.get(), error);
140 info->startup_pages = ParseStartupPage(*settings, error);
141 if (!info->homepage && !info->search_engine && info->startup_pages.empty()) {
142 *error = ErrorUtils::FormatErrorMessageUTF16(
143 manifest_errors::kInvalidEmptyDictionary,
144 manifest_keys::kSettingsOverride);
145 return false;
148 if (info->search_engine) {
149 PermissionsParser::AddAPIPermission(
150 extension,
151 new SettingsOverrideAPIPermission(
152 PermissionsInfo::GetInstance()->GetByID(
153 APIPermission::kSearchProvider),
154 RemoveWwwPrefix(CreateManifestURL(info->search_engine->search_url)
155 ->GetOrigin()
156 .host())));
158 if (!info->startup_pages.empty()) {
159 PermissionsParser::AddAPIPermission(
160 extension,
161 new SettingsOverrideAPIPermission(
162 PermissionsInfo::GetInstance()->GetByID(
163 APIPermission::kStartupPages),
164 // We only support one startup page even though the type of the
165 // manifest
166 // property is a list, only the first one is used.
167 RemoveWwwPrefix(info->startup_pages[0].GetContent())));
169 if (info->homepage) {
170 PermissionsParser::AddAPIPermission(
171 extension,
172 new SettingsOverrideAPIPermission(
173 PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage),
174 RemoveWwwPrefix(info->homepage.get()->GetContent())));
176 extension->SetManifestData(manifest_keys::kSettingsOverride,
177 info.release());
178 return true;
181 const std::vector<std::string> SettingsOverridesHandler::Keys() const {
182 return SingleKey(manifest_keys::kSettingsOverride);
185 } // namespace extensions