Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / content_settings / content_settings_api.cc
blob2bc6010b858f5a6d01d3607d936bb0c19608d978
1 // Copyright (c) 2012 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/browser/extensions/api/content_settings/content_settings_api.h"
7 #include <set>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/values.h"
14 #include "chrome/browser/content_settings/cookie_settings_factory.h"
15 #include "chrome/browser/extensions/api/content_settings/content_settings_api_constants.h"
16 #include "chrome/browser/extensions/api/content_settings/content_settings_helpers.h"
17 #include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
18 #include "chrome/browser/extensions/api/content_settings/content_settings_store.h"
19 #include "chrome/browser/extensions/api/preference/preference_api_constants.h"
20 #include "chrome/browser/extensions/api/preference/preference_helpers.h"
21 #include "chrome/browser/plugins/plugin_finder.h"
22 #include "chrome/browser/plugins/plugin_installer.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/extensions/api/content_settings.h"
26 #include "components/content_settings/core/browser/cookie_settings.h"
27 #include "components/content_settings/core/browser/host_content_settings_map.h"
28 #include "content/public/browser/plugin_service.h"
29 #include "extensions/browser/extension_prefs_scope.h"
30 #include "extensions/common/error_utils.h"
32 using content::BrowserThread;
33 using content::PluginService;
35 namespace Clear = extensions::api::content_settings::ContentSetting::Clear;
36 namespace Get = extensions::api::content_settings::ContentSetting::Get;
37 namespace Set = extensions::api::content_settings::ContentSetting::Set;
38 namespace pref_helpers = extensions::preference_helpers;
39 namespace pref_keys = extensions::preference_api_constants;
41 namespace {
43 bool RemoveContentType(base::ListValue* args,
44 ContentSettingsType* content_type) {
45 std::string content_type_str;
46 if (!args->GetString(0, &content_type_str))
47 return false;
48 // We remove the ContentSettingsType parameter since this is added by the
49 // renderer, and is not part of the JSON schema.
50 args->Remove(0, NULL);
51 *content_type =
52 extensions::content_settings_helpers::StringToContentSettingsType(
53 content_type_str);
54 return *content_type != CONTENT_SETTINGS_TYPE_DEFAULT;
57 } // namespace
59 namespace extensions {
61 namespace helpers = content_settings_helpers;
62 namespace keys = content_settings_api_constants;
64 bool ContentSettingsContentSettingClearFunction::RunSync() {
65 ContentSettingsType content_type;
66 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
68 scoped_ptr<Clear::Params> params(Clear::Params::Create(*args_));
69 EXTENSION_FUNCTION_VALIDATE(params.get());
71 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular;
72 bool incognito = false;
73 if (params->details.scope ==
74 api::content_settings::SCOPE_INCOGNITO_SESSION_ONLY) {
75 scope = kExtensionPrefsScopeIncognitoSessionOnly;
76 incognito = true;
79 if (incognito) {
80 // We don't check incognito permissions here, as an extension should be
81 // always allowed to clear its own settings.
82 } else {
83 // Incognito profiles can't access regular mode ever, they only exist in
84 // split mode.
85 if (GetProfile()->IsOffTheRecord()) {
86 error_ = keys::kIncognitoContextError;
87 return false;
91 scoped_refptr<ContentSettingsStore> store =
92 ContentSettingsService::Get(GetProfile())->content_settings_store();
93 store->ClearContentSettingsForExtension(extension_id(), scope);
95 return true;
98 bool ContentSettingsContentSettingGetFunction::RunSync() {
99 ContentSettingsType content_type;
100 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
102 scoped_ptr<Get::Params> params(Get::Params::Create(*args_));
103 EXTENSION_FUNCTION_VALIDATE(params.get());
105 GURL primary_url(params->details.primary_url);
106 if (!primary_url.is_valid()) {
107 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
108 params->details.primary_url);
109 return false;
112 GURL secondary_url(primary_url);
113 if (params->details.secondary_url.get()) {
114 secondary_url = GURL(*params->details.secondary_url);
115 if (!secondary_url.is_valid()) {
116 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
117 *params->details.secondary_url);
118 return false;
122 std::string resource_identifier;
123 if (params->details.resource_identifier.get())
124 resource_identifier = params->details.resource_identifier->id;
126 bool incognito = false;
127 if (params->details.incognito.get())
128 incognito = *params->details.incognito;
129 if (incognito && !include_incognito()) {
130 error_ = pref_keys::kIncognitoErrorMessage;
131 return false;
134 HostContentSettingsMap* map;
135 content_settings::CookieSettings* cookie_settings;
136 if (incognito) {
137 if (!GetProfile()->HasOffTheRecordProfile()) {
138 // TODO(bauerb): Allow reading incognito content settings
139 // outside of an incognito session.
140 error_ = keys::kIncognitoSessionOnlyError;
141 return false;
143 map = GetProfile()->GetOffTheRecordProfile()->GetHostContentSettingsMap();
144 cookie_settings = CookieSettingsFactory::GetForProfile(
145 GetProfile()->GetOffTheRecordProfile()).get();
146 } else {
147 map = GetProfile()->GetHostContentSettingsMap();
148 cookie_settings = CookieSettingsFactory::GetForProfile(GetProfile()).get();
151 ContentSetting setting;
152 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) {
153 // TODO(jochen): Do we return the value for setting or for reading cookies?
154 bool setting_cookie = false;
155 setting = cookie_settings->GetCookieSetting(primary_url, secondary_url,
156 setting_cookie, NULL);
157 } else {
158 setting = map->GetContentSetting(primary_url, secondary_url, content_type,
159 resource_identifier);
162 base::DictionaryValue* result = new base::DictionaryValue();
163 result->SetString(keys::kContentSettingKey,
164 helpers::ContentSettingToString(setting));
166 SetResult(result);
168 return true;
171 bool ContentSettingsContentSettingSetFunction::RunSync() {
172 ContentSettingsType content_type;
173 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
175 scoped_ptr<Set::Params> params(Set::Params::Create(*args_));
176 EXTENSION_FUNCTION_VALIDATE(params.get());
178 std::string primary_error;
179 ContentSettingsPattern primary_pattern =
180 helpers::ParseExtensionPattern(params->details.primary_pattern,
181 &primary_error);
182 if (!primary_pattern.IsValid()) {
183 error_ = primary_error;
184 return false;
187 ContentSettingsPattern secondary_pattern = ContentSettingsPattern::Wildcard();
188 if (params->details.secondary_pattern.get()) {
189 std::string secondary_error;
190 secondary_pattern =
191 helpers::ParseExtensionPattern(*params->details.secondary_pattern,
192 &secondary_error);
193 if (!secondary_pattern.IsValid()) {
194 error_ = secondary_error;
195 return false;
199 std::string resource_identifier;
200 if (params->details.resource_identifier.get())
201 resource_identifier = params->details.resource_identifier->id;
203 std::string setting_str;
204 EXTENSION_FUNCTION_VALIDATE(
205 params->details.setting->GetAsString(&setting_str));
206 ContentSetting setting;
207 EXTENSION_FUNCTION_VALIDATE(
208 helpers::StringToContentSetting(setting_str, &setting));
209 EXTENSION_FUNCTION_VALIDATE(HostContentSettingsMap::IsSettingAllowedForType(
210 GetProfile()->GetPrefs(), setting, content_type));
212 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular;
213 bool incognito = false;
214 if (params->details.scope ==
215 api::content_settings::SCOPE_INCOGNITO_SESSION_ONLY) {
216 scope = kExtensionPrefsScopeIncognitoSessionOnly;
217 incognito = true;
220 if (incognito) {
221 // Regular profiles can't access incognito unless include_incognito is true.
222 if (!GetProfile()->IsOffTheRecord() && !include_incognito()) {
223 error_ = pref_keys::kIncognitoErrorMessage;
224 return false;
226 } else {
227 // Incognito profiles can't access regular mode ever, they only exist in
228 // split mode.
229 if (GetProfile()->IsOffTheRecord()) {
230 error_ = keys::kIncognitoContextError;
231 return false;
235 if (scope == kExtensionPrefsScopeIncognitoSessionOnly &&
236 !GetProfile()->HasOffTheRecordProfile()) {
237 error_ = pref_keys::kIncognitoSessionOnlyErrorMessage;
238 return false;
241 scoped_refptr<ContentSettingsStore> store =
242 ContentSettingsService::Get(GetProfile())->content_settings_store();
243 store->SetExtensionContentSetting(extension_id(), primary_pattern,
244 secondary_pattern, content_type,
245 resource_identifier, setting, scope);
246 return true;
249 bool ContentSettingsContentSettingGetResourceIdentifiersFunction::RunAsync() {
250 ContentSettingsType content_type;
251 EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
253 if (content_type != CONTENT_SETTINGS_TYPE_PLUGINS) {
254 SendResponse(true);
255 return true;
258 PluginService::GetInstance()->GetPlugins(
259 base::Bind(&ContentSettingsContentSettingGetResourceIdentifiersFunction::
260 OnGotPlugins,
261 this));
262 return true;
265 void ContentSettingsContentSettingGetResourceIdentifiersFunction::OnGotPlugins(
266 const std::vector<content::WebPluginInfo>& plugins) {
267 PluginFinder* finder = PluginFinder::GetInstance();
268 std::set<std::string> group_identifiers;
269 base::ListValue* list = new base::ListValue();
270 for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin();
271 it != plugins.end(); ++it) {
272 scoped_ptr<PluginMetadata> plugin_metadata(finder->GetPluginMetadata(*it));
273 const std::string& group_identifier = plugin_metadata->identifier();
274 if (group_identifiers.find(group_identifier) != group_identifiers.end())
275 continue;
277 group_identifiers.insert(group_identifier);
278 base::DictionaryValue* dict = new base::DictionaryValue();
279 dict->SetString(keys::kIdKey, group_identifier);
280 dict->SetString(keys::kDescriptionKey, plugin_metadata->name());
281 list->Append(dict);
283 SetResult(list);
284 BrowserThread::PostTask(
285 BrowserThread::UI, FROM_HERE, base::Bind(
286 &ContentSettingsContentSettingGetResourceIdentifiersFunction::
287 SendResponse,
288 this,
289 true));
292 } // namespace extensions