Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / manifest_handlers / settings_overrides_handler.cc
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/manifest_handlers/settings_overrides_handler.h"
6
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"
24
25 using extensions::api::manifest_types::ChromeSettingsOverrides;
26
27 namespace extensions {
28 namespace {
29
30 const char* kWwwPrefix = "www.";
31
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();
38 }
39
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);
48   }
49   return manifest_url.Pass();
50 }
51
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;
57
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());
68     }
69   }
70   return urls;
71 }
72
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>();
83   }
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>();
93   }
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>();
99   }
100   return overrides->search_provider.Pass();
101 }
102
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 (StartsWithASCII(url, kWwwPrefix, false))
107     return url.substr(strlen(kWwwPrefix));
108   return url;
109 }
110
111 }  // namespace
112
113 SettingsOverrides::SettingsOverrides() {}
114
115 SettingsOverrides::~SettingsOverrides() {}
116
117 // static
118 const SettingsOverrides* SettingsOverrides::Get(
119     const Extension* extension) {
120   return static_cast<SettingsOverrides*>(
121       extension->GetManifestData(manifest_keys::kSettingsOverride));
122 }
123
124 SettingsOverridesHandler::SettingsOverridesHandler() {}
125
126 SettingsOverridesHandler::~SettingsOverridesHandler() {}
127
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;
136
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;
146   }
147
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())));
157   }
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())));
168   }
169   if (info->homepage) {
170     PermissionsParser::AddAPIPermission(
171         extension,
172         new SettingsOverrideAPIPermission(
173             PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage),
174             RemoveWwwPrefix(info->homepage.get()->GetContent())));
175   }
176   extension->SetManifestData(manifest_keys::kSettingsOverride,
177                              info.release());
178   return true;
179 }
180
181 const std::vector<std::string> SettingsOverridesHandler::Keys() const {
182   return SingleKey(manifest_keys::kSettingsOverride);
183 }
184
185 }  // namespace extensions