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/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/common/extensions/permissions/permissions_data.h"
10 #include "chrome/common/extensions/permissions/settings_override_permission.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/manifest_constants.h"
13 #include "extensions/common/permissions/api_permission_set.h"
14 #include "extensions/common/permissions/permissions_info.h"
17 using extensions::api::manifest_types::ChromeSettingsOverrides;
19 namespace extensions {
22 const char* kWwwPrefix = "www.";
24 scoped_ptr<GURL> CreateManifestURL(const std::string& url) {
25 scoped_ptr<GURL> manifest_url(new GURL(url));
26 if (!manifest_url->is_valid() ||
27 !manifest_url->SchemeIsHTTPOrHTTPS())
28 return scoped_ptr<GURL>();
29 return manifest_url.Pass();
32 scoped_ptr<GURL> ParseHomepage(const ChromeSettingsOverrides& overrides,
34 if (!overrides.homepage)
35 return scoped_ptr<GURL>();
36 scoped_ptr<GURL> manifest_url = CreateManifestURL(*overrides.homepage);
38 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
39 manifest_errors::kInvalidHomepageOverrideURL, *overrides.homepage);
41 return manifest_url.Pass();
44 std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides,
46 std::vector<GURL> urls;
47 if (!overrides.startup_pages)
50 for (std::vector<std::string>::const_iterator i =
51 overrides.startup_pages->begin(); i != overrides.startup_pages->end();
53 scoped_ptr<GURL> manifest_url = CreateManifestURL(*i);
55 *error = extensions::ErrorUtils::FormatErrorMessageUTF16(
56 manifest_errors::kInvalidStartupOverrideURL, *i);
58 urls.push_back(GURL());
59 urls.back().Swap(manifest_url.get());
65 // A www. prefix is not informative and thus not worth the limited real estate
66 // in the permissions UI.
67 std::string RemoveWwwPrefix(const std::string& url) {
68 if (StartsWithASCII(url, kWwwPrefix, false))
69 return url.substr(strlen(kWwwPrefix));
75 SettingsOverrides::SettingsOverrides() {}
77 SettingsOverrides::~SettingsOverrides() {}
79 const SettingsOverrides* SettingsOverrides::Get(
80 const Extension* extension) {
81 return static_cast<SettingsOverrides*>(
82 extension->GetManifestData(manifest_keys::kSettingsOverride));
85 SettingsOverridesHandler::SettingsOverridesHandler() {}
87 SettingsOverridesHandler::~SettingsOverridesHandler() {}
89 bool SettingsOverridesHandler::Parse(Extension* extension, string16* error) {
90 const base::Value* dict = NULL;
91 CHECK(extension->manifest()->Get(manifest_keys::kSettingsOverride, &dict));
92 scoped_ptr<ChromeSettingsOverrides> settings(
93 ChromeSettingsOverrides::FromValue(*dict, error));
97 scoped_ptr<SettingsOverrides> info(new SettingsOverrides);
98 info->homepage = ParseHomepage(*settings, error);
99 info->search_engine = settings->search_provider.Pass();
100 info->startup_pages = ParseStartupPage(*settings, error);
101 if (!info->homepage && !info->search_engine && info->startup_pages.empty()) {
102 *error = ASCIIToUTF16(manifest_errors::kInvalidEmptySettingsOverrides);
105 APIPermissionSet* permission_set =
106 PermissionsData::GetInitialAPIPermissions(extension);
107 DCHECK(permission_set);
108 if (info->search_engine) {
109 permission_set->insert(new SettingsOverrideAPIPermission(
110 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSearchProvider),
111 RemoveWwwPrefix(CreateManifestURL(info->search_engine->search_url)->
112 GetOrigin().host())));
114 if (!info->startup_pages.empty()) {
115 permission_set->insert(new SettingsOverrideAPIPermission(
116 PermissionsInfo::GetInstance()->GetByID(APIPermission::kStartupPages),
117 // We only support one startup page even though the type of the manifest
118 // property is a list, only the first one is used.
119 RemoveWwwPrefix(info->startup_pages[0].GetContent())));
121 if (info->homepage) {
122 permission_set->insert(new SettingsOverrideAPIPermission(
123 PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage),
124 RemoveWwwPrefix(info->homepage.get()->GetContent())));
126 extension->SetManifestData(manifest_keys::kSettingsOverride,
131 const std::vector<std::string> SettingsOverridesHandler::Keys() const {
132 return SingleKey(manifest_keys::kSettingsOverride);
135 } // namespace extensions