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"
25 using extensions::api::manifest_types::ChromeSettingsOverrides
;
27 namespace extensions
{
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
);
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
)
58 for (std::vector
<std::string
>::const_iterator i
=
59 overrides
.startup_pages
->begin(); i
!= overrides
.startup_pages
->end();
61 scoped_ptr
<GURL
> manifest_url
= CreateManifestURL(*i
);
63 *error
= extensions::ErrorUtils::FormatErrorMessageUTF16(
64 manifest_errors::kInvalidStartupOverrideURL
, *i
);
66 urls
.push_back(GURL());
67 urls
.back().Swap(manifest_url
.get());
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
) {
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
));
113 SettingsOverrides::SettingsOverrides() {}
115 SettingsOverrides::~SettingsOverrides() {}
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
));
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
);
148 if (info
->search_engine
) {
149 PermissionsParser::AddAPIPermission(
151 new SettingsOverrideAPIPermission(
152 PermissionsInfo::GetInstance()->GetByID(
153 APIPermission::kSearchProvider
),
154 RemoveWwwPrefix(CreateManifestURL(info
->search_engine
->search_url
)
158 if (!info
->startup_pages
.empty()) {
159 PermissionsParser::AddAPIPermission(
161 new SettingsOverrideAPIPermission(
162 PermissionsInfo::GetInstance()->GetByID(
163 APIPermission::kStartupPages
),
164 // We only support one startup page even though the type of the
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(
172 new SettingsOverrideAPIPermission(
173 PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage
),
174 RemoveWwwPrefix(info
->homepage
.get()->GetContent())));
176 extension
->SetManifestData(manifest_keys::kSettingsOverride
,
181 const std::vector
<std::string
> SettingsOverridesHandler::Keys() const {
182 return SingleKey(manifest_keys::kSettingsOverride
);
185 } // namespace extensions