OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/extensions/extension_content_settings_api.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/command_line.h" | |
11 #include "base/values.h" | |
12 #include "chrome/browser/content_settings/cookie_settings.h" | |
13 #include "chrome/browser/content_settings/host_content_settings_map.h" | |
14 #include "chrome/browser/extensions/extension_content_settings_api_constants.h" | |
15 #include "chrome/browser/extensions/extension_content_settings_helpers.h" | |
16 #include "chrome/browser/extensions/extension_content_settings_store.h" | |
17 #include "chrome/browser/extensions/extension_preference_api_constants.h" | |
18 #include "chrome/browser/extensions/extension_preference_helpers.h" | |
19 #include "chrome/browser/extensions/extension_service.h" | |
20 #include "chrome/browser/profiles/profile.h" | |
21 #include "chrome/common/chrome_switches.h" | |
22 #include "chrome/common/extensions/extension_error_utils.h" | |
23 #include "content/public/browser/plugin_service.h" | |
24 #include "webkit/plugins/npapi/plugin_group.h" | |
25 | |
26 using content::BrowserThread; | |
27 using content::PluginService; | |
28 | |
29 namespace helpers = extension_content_settings_helpers; | |
30 namespace keys = extension_content_settings_api_constants; | |
31 namespace pref_helpers = extension_preference_helpers; | |
32 namespace pref_keys = extension_preference_api_constants; | |
33 | |
34 namespace { | |
35 | |
36 const std::vector<webkit::npapi::PluginGroup>* g_testing_plugin_groups_; | |
37 | |
38 } // namespace | |
39 | |
40 bool ClearContentSettingsFunction::RunImpl() { | |
41 std::string content_type_str; | |
42 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &content_type_str)); | |
43 ContentSettingsType content_type = | |
44 helpers::StringToContentSettingsType(content_type_str); | |
45 EXTENSION_FUNCTION_VALIDATE(content_type != CONTENT_SETTINGS_TYPE_DEFAULT); | |
46 | |
47 DictionaryValue* details = NULL; | |
48 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | |
49 | |
50 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | |
51 if (details->HasKey(pref_keys::kScopeKey)) { | |
52 std::string scope_str; | |
53 EXTENSION_FUNCTION_VALIDATE(details->GetString(pref_keys::kScopeKey, | |
54 &scope_str)); | |
55 | |
56 EXTENSION_FUNCTION_VALIDATE(pref_helpers::StringToScope(scope_str, &scope)); | |
57 EXTENSION_FUNCTION_VALIDATE( | |
58 scope != kExtensionPrefsScopeIncognitoPersistent); | |
59 } | |
60 | |
61 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || | |
62 scope == kExtensionPrefsScopeIncognitoSessionOnly); | |
63 if (incognito) { | |
64 // We don't check incognito permissions here, as an extension should be | |
65 // always allowed to clear its own settings. | |
66 } else { | |
67 // Incognito profiles can't access regular mode ever, they only exist in | |
68 // split mode. | |
69 if (profile()->IsOffTheRecord()) { | |
70 error_ = keys::kIncognitoContextError; | |
71 return false; | |
72 } | |
73 } | |
74 | |
75 ExtensionContentSettingsStore* store = | |
76 profile_->GetExtensionService()->GetExtensionContentSettingsStore(); | |
77 store->ClearContentSettingsForExtension(extension_id(), scope); | |
78 | |
79 return true; | |
80 } | |
81 | |
82 bool GetContentSettingFunction::RunImpl() { | |
83 std::string content_type_str; | |
84 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &content_type_str)); | |
85 ContentSettingsType content_type = | |
86 helpers::StringToContentSettingsType(content_type_str); | |
87 EXTENSION_FUNCTION_VALIDATE(content_type != CONTENT_SETTINGS_TYPE_DEFAULT); | |
88 | |
89 DictionaryValue* details = NULL; | |
90 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | |
91 | |
92 std::string primary_url_spec; | |
93 EXTENSION_FUNCTION_VALIDATE( | |
94 details->GetString(keys::kPrimaryUrlKey, &primary_url_spec)); | |
95 GURL primary_url(primary_url_spec); | |
96 if (!primary_url.is_valid()) { | |
97 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, | |
98 primary_url_spec); | |
99 return false; | |
100 } | |
101 | |
102 GURL secondary_url(primary_url); | |
103 std::string secondary_url_spec; | |
104 if (details->GetString(keys::kSecondaryUrlKey, &secondary_url_spec)) { | |
105 secondary_url = GURL(secondary_url_spec); | |
106 if (!secondary_url.is_valid()) { | |
107 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, | |
108 secondary_url_spec); | |
109 return false; | |
110 } | |
111 } | |
112 | |
113 std::string resource_identifier; | |
114 if (details->HasKey(keys::kResourceIdentifierKey)) { | |
115 DictionaryValue* resource_identifier_dict = NULL; | |
116 EXTENSION_FUNCTION_VALIDATE( | |
117 details->GetDictionary(keys::kResourceIdentifierKey, | |
118 &resource_identifier_dict)); | |
119 EXTENSION_FUNCTION_VALIDATE( | |
120 resource_identifier_dict->GetString(keys::kIdKey, | |
121 &resource_identifier)); | |
122 } | |
123 | |
124 bool incognito = false; | |
125 if (details->HasKey(pref_keys::kIncognitoKey)) { | |
126 EXTENSION_FUNCTION_VALIDATE( | |
127 details->GetBoolean(pref_keys::kIncognitoKey, &incognito)); | |
128 } | |
129 if (incognito && !include_incognito()) { | |
130 error_ = pref_keys::kIncognitoErrorMessage; | |
131 return false; | |
132 } | |
133 | |
134 HostContentSettingsMap* map; | |
135 CookieSettings* cookie_settings; | |
136 if (incognito) { | |
137 if (!profile()->HasOffTheRecordProfile()) { | |
138 // TODO(bauerb): Allow reading incognito content settings | |
139 // outside of an incognito session. | |
140 error_ = keys::kIncognitoSessionOnlyError; | |
141 return false; | |
142 } | |
143 map = profile()->GetOffTheRecordProfile()->GetHostContentSettingsMap(); | |
144 cookie_settings = CookieSettings::Factory::GetForProfile( | |
145 profile()->GetOffTheRecordProfile()); | |
146 } else { | |
147 map = profile()->GetHostContentSettingsMap(); | |
148 cookie_settings = CookieSettings::Factory::GetForProfile(profile()); | |
149 } | |
150 | |
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); | |
160 } | |
161 | |
162 DictionaryValue* result = new DictionaryValue(); | |
163 result->SetString(keys::kContentSettingKey, | |
164 helpers::ContentSettingToString(setting)); | |
165 | |
166 result_.reset(result); | |
167 | |
168 return true; | |
169 } | |
170 | |
171 bool SetContentSettingFunction::RunImpl() { | |
172 std::string content_type_str; | |
173 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &content_type_str)); | |
174 ContentSettingsType content_type = | |
175 helpers::StringToContentSettingsType(content_type_str); | |
176 EXTENSION_FUNCTION_VALIDATE(content_type != CONTENT_SETTINGS_TYPE_DEFAULT); | |
177 | |
178 DictionaryValue* details = NULL; | |
179 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); | |
180 | |
181 std::string primary_pattern_str; | |
182 EXTENSION_FUNCTION_VALIDATE( | |
183 details->GetString(keys::kPrimaryPatternKey, &primary_pattern_str)); | |
184 std::string primary_error; | |
185 ContentSettingsPattern primary_pattern = | |
186 helpers::ParseExtensionPattern(primary_pattern_str, &primary_error); | |
187 if (!primary_pattern.IsValid()) { | |
188 error_ = primary_error; | |
189 return false; | |
190 } | |
191 | |
192 ContentSettingsPattern secondary_pattern = ContentSettingsPattern::Wildcard(); | |
193 std::string secondary_pattern_str; | |
194 if (details->GetString(keys::kSecondaryPatternKey, &secondary_pattern_str)) { | |
195 std::string secondary_error; | |
196 secondary_pattern = | |
197 helpers::ParseExtensionPattern(secondary_pattern_str, &secondary_error); | |
198 if (!secondary_pattern.IsValid()) { | |
199 error_ = secondary_error; | |
200 return false; | |
201 } | |
202 } | |
203 | |
204 std::string resource_identifier; | |
205 if (details->HasKey(keys::kResourceIdentifierKey)) { | |
206 DictionaryValue* resource_identifier_dict = NULL; | |
207 EXTENSION_FUNCTION_VALIDATE( | |
208 details->GetDictionary(keys::kResourceIdentifierKey, | |
209 &resource_identifier_dict)); | |
210 EXTENSION_FUNCTION_VALIDATE( | |
211 resource_identifier_dict->GetString(keys::kIdKey, | |
212 &resource_identifier)); | |
213 } | |
214 | |
215 std::string setting_str; | |
216 EXTENSION_FUNCTION_VALIDATE( | |
217 details->GetString(keys::kContentSettingKey, &setting_str)); | |
218 ContentSetting setting = CONTENT_SETTING_DEFAULT; | |
219 EXTENSION_FUNCTION_VALIDATE( | |
220 helpers::StringToContentSetting(setting_str, &setting)); | |
221 EXTENSION_FUNCTION_VALIDATE( | |
222 HostContentSettingsMap::IsSettingAllowedForType(setting, content_type)); | |
223 | |
224 ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; | |
225 if (details->HasKey(pref_keys::kScopeKey)) { | |
226 std::string scope_str; | |
227 EXTENSION_FUNCTION_VALIDATE(details->GetString(pref_keys::kScopeKey, | |
228 &scope_str)); | |
229 | |
230 EXTENSION_FUNCTION_VALIDATE(pref_helpers::StringToScope(scope_str, &scope)); | |
231 EXTENSION_FUNCTION_VALIDATE( | |
232 scope != kExtensionPrefsScopeIncognitoPersistent); | |
233 } | |
234 | |
235 bool incognito = (scope == kExtensionPrefsScopeIncognitoPersistent || | |
236 scope == kExtensionPrefsScopeIncognitoSessionOnly); | |
237 if (incognito) { | |
238 // Regular profiles can't access incognito unless include_incognito is true. | |
239 if (!profile()->IsOffTheRecord() && !include_incognito()) { | |
240 error_ = pref_keys::kIncognitoErrorMessage; | |
241 return false; | |
242 } | |
243 } else { | |
244 // Incognito profiles can't access regular mode ever, they only exist in | |
245 // split mode. | |
246 if (profile()->IsOffTheRecord()) { | |
247 error_ = keys::kIncognitoContextError; | |
248 return false; | |
249 } | |
250 } | |
251 | |
252 if (scope == kExtensionPrefsScopeIncognitoSessionOnly && | |
253 !profile_->HasOffTheRecordProfile()) { | |
254 error_ = pref_keys::kIncognitoSessionOnlyErrorMessage; | |
255 return false; | |
256 } | |
257 | |
258 ExtensionContentSettingsStore* store = | |
259 profile_->GetExtensionService()->GetExtensionContentSettingsStore(); | |
260 store->SetExtensionContentSetting(extension_id(), primary_pattern, | |
261 secondary_pattern, content_type, | |
262 resource_identifier, setting, scope); | |
263 return true; | |
264 } | |
265 | |
266 bool GetResourceIdentifiersFunction::RunImpl() { | |
267 std::string content_type_str; | |
268 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &content_type_str)); | |
269 ContentSettingsType content_type = | |
270 helpers::StringToContentSettingsType(content_type_str); | |
271 EXTENSION_FUNCTION_VALIDATE(content_type != CONTENT_SETTINGS_TYPE_DEFAULT); | |
272 | |
273 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) { | |
274 if (g_testing_plugin_groups_) { | |
275 OnGotPluginGroups(*g_testing_plugin_groups_); | |
276 } else { | |
277 PluginService::GetInstance()->GetPluginGroups( | |
278 base::Bind(&GetResourceIdentifiersFunction::OnGotPluginGroups, this)); | |
279 } | |
280 } else { | |
281 SendResponse(true); | |
282 } | |
283 | |
284 return true; | |
285 } | |
286 | |
287 void GetResourceIdentifiersFunction::OnGotPluginGroups( | |
288 const std::vector<webkit::npapi::PluginGroup>& groups) { | |
289 ListValue* list = new ListValue(); | |
290 for (std::vector<webkit::npapi::PluginGroup>::const_iterator it = | |
291 groups.begin(); | |
292 it != groups.end(); ++it) { | |
293 DictionaryValue* dict = new DictionaryValue(); | |
294 dict->SetString(keys::kIdKey, it->identifier()); | |
295 dict->SetString(keys::kDescriptionKey, it->GetGroupName()); | |
296 list->Append(dict); | |
297 } | |
298 result_.reset(list); | |
299 BrowserThread::PostTask( | |
300 BrowserThread::UI, FROM_HERE, base::Bind( | |
301 &GetResourceIdentifiersFunction::SendResponse, this, true)); | |
302 } | |
303 | |
304 // static | |
305 void GetResourceIdentifiersFunction::SetPluginGroupsForTesting( | |
306 const std::vector<webkit::npapi::PluginGroup>* plugin_groups) { | |
307 g_testing_plugin_groups_ = plugin_groups; | |
308 } | |
OLD | NEW |