Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: chrome/browser/external_protocol/external_protocol_handler.cc

Issue 2623033006: [Re-landing] Migrate external protocol prefs from local state to profiles (Closed)
Patch Set: a Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/external_protocol/external_protocol_handler.h" 5 #include "chrome/browser/external_protocol/external_protocol_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 const std::string& protocol, 45 const std::string& protocol,
46 ExternalProtocolHandler::Delegate* delegate) { 46 ExternalProtocolHandler::Delegate* delegate) {
47 if (delegate) 47 if (delegate)
48 return delegate->CreateShellWorker(callback, protocol); 48 return delegate->CreateShellWorker(callback, protocol);
49 49
50 return new shell_integration::DefaultProtocolClientWorker(callback, protocol); 50 return new shell_integration::DefaultProtocolClientWorker(callback, protocol);
51 } 51 }
52 52
53 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate( 53 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
54 const std::string& scheme, 54 const std::string& scheme,
55 ExternalProtocolHandler::Delegate* delegate) { 55 ExternalProtocolHandler::Delegate* delegate,
56 Profile* profile) {
56 if (!delegate) 57 if (!delegate)
57 return ExternalProtocolHandler::GetBlockState(scheme); 58 return ExternalProtocolHandler::GetBlockState(scheme, profile);
58 59
59 return delegate->GetBlockState(scheme); 60 return delegate->GetBlockState(scheme, profile);
60 } 61 }
61 62
62 void RunExternalProtocolDialogWithDelegate( 63 void RunExternalProtocolDialogWithDelegate(
63 const GURL& url, 64 const GURL& url,
64 int render_process_host_id, 65 int render_process_host_id,
65 int routing_id, 66 int routing_id,
66 ui::PageTransition page_transition, 67 ui::PageTransition page_transition,
67 bool has_user_gesture, 68 bool has_user_gesture,
68 ExternalProtocolHandler::Delegate* delegate) { 69 ExternalProtocolHandler::Delegate* delegate) {
69 if (!delegate) { 70 if (!delegate) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 129 }
129 130
130 LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, render_process_host_id, 131 LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, render_process_host_id,
131 render_view_routing_id, delegate); 132 render_view_routing_id, delegate);
132 } 133 }
133 134
134 } // namespace 135 } // namespace
135 136
136 // static 137 // static
137 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( 138 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState(
138 const std::string& scheme) { 139 const std::string& scheme, Profile* profile) {
139 // If we are being carpet bombed, block the request. 140 // If we are being carpet bombed, block the request.
140 if (!g_accept_requests) 141 if (!g_accept_requests)
141 return BLOCK; 142 return BLOCK;
142 143
143 if (scheme.length() == 1) { 144 if (scheme.length() == 1) {
144 // We have a URL that looks something like: 145 // We have a URL that looks something like:
145 // C:/WINDOWS/system32/notepad.exe 146 // C:/WINDOWS/system32/notepad.exe
146 // ShellExecuting this URL will cause the specified program to be executed. 147 // ShellExecuting this URL will cause the specified program to be executed.
147 return BLOCK; 148 return BLOCK;
148 } 149 }
149 150
150 // Check the stored prefs. 151 // Check the stored prefs.
151 // TODO(pkasting): This kind of thing should go in the preferences on the 152 // TODO(pkasting): This kind of thing should go in the preferences on the
dominickn 2017/01/19 07:01:22 Nit: you can remove this TODO, because you're doin
ramyasharma 2017/01/20 04:04:45 Done.
152 // profile, not in the local state. http://crbug.com/457254 153 // profile, not in the local state. http://crbug.com/457254
153 PrefService* pref = g_browser_process->local_state(); 154 PrefService* localPref = g_browser_process->local_state();
dominickn 2017/01/19 07:01:22 Nit: variables use underscore_naming, so call this
ramyasharma 2017/01/20 04:04:45 Done.
154 if (pref) { // May be NULL during testing. 155 PrefService* profilePref = profile->GetPrefs();
dominickn 2017/01/19 07:01:22 Call this profile_prefs
ramyasharma 2017/01/20 04:04:45 Done.
155 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 156 if (localPref && profilePref) { // May be NULL during testing.
156 157 DictionaryPrefUpdate update_excluded_schemas(
dominickn 2017/01/19 07:01:22 Call this local_state_schemas, since we're not act
ramyasharma 2017/01/20 04:04:45 Done.
157 // Warm up the dictionary if needed. 158 localPref, prefs::kExcludedSchemes);
158 PrepopulateDictionary(update_excluded_schemas.Get()); 159 DictionaryPrefUpdate update_excluded_schemas_profile(
160 profilePref, prefs::kExcludedSchemes);
161 if (update_excluded_schemas_profile->empty()) {
162 // Copy local state to profile state.
163 for (base::DictionaryValue::Iterator it(*update_excluded_schemas);
164 !it.IsAtEnd(); it.Advance()) {
165 bool is_blocked;
166 // Discard local state if set to blocked, to reset all users
167 // stuck in 'Do Nothing' + 'Do Not Open' state back to the default
168 // prompt state.
169 if (it.value().GetAsBoolean(&is_blocked) && !is_blocked) {
dominickn 2017/01/19 07:01:22 Nit: one-line if statements don't need braces
ramyasharma 2017/01/20 04:04:45 Done. I was wondering about that, why is it not? U
dominickn 2017/01/20 05:07:46 I used to follow that rule too, but this style is
170 update_excluded_schemas_profile->SetBoolean(it.key(), is_blocked);
171 }
172 }
173 // TODO(ramyasharma): Clear only if required.
174 localPref->ClearPref(prefs::kExcludedSchemes);
175 }
176 // Prepolutate the default states each time.
dominickn 2017/01/19 07:01:22 sp. "Prepopulate"
ramyasharma 2017/01/20 04:04:45 Oops, done.
177 PrepopulateDictionary(update_excluded_schemas_profile.Get());
159 178
160 bool should_block; 179 bool should_block;
161 if (update_excluded_schemas->GetBoolean(scheme, &should_block)) 180 if (update_excluded_schemas_profile->GetBoolean(scheme, &should_block)) {
dominickn 2017/01/19 07:01:22 Nit: don't add the braces here, one line if statem
ramyasharma 2017/01/20 04:04:45 Done.
162 return should_block ? BLOCK : DONT_BLOCK; 181 return should_block ? BLOCK : DONT_BLOCK;
182 }
163 } 183 }
164 184
165 return UNKNOWN; 185 return UNKNOWN;
166 } 186 }
167 187
168 // static 188 // static
169 void ExternalProtocolHandler::SetBlockState(const std::string& scheme, 189 void ExternalProtocolHandler::SetBlockState(const std::string& scheme,
170 BlockState state) { 190 BlockState state,
191 Profile* profile) {
171 // Set in the stored prefs. 192 // Set in the stored prefs.
172 // TODO(pkasting): This kind of thing should go in the preferences on the 193 // TODO(pkasting): This kind of thing should go in the preferences on the
dominickn 2017/01/19 07:01:22 Nit: remove this TODO (you're doing it)
ramyasharma 2017/01/20 04:04:45 Done.
173 // profile, not in the local state. http://crbug.com/457254 194 // profile, not in the local state. http://crbug.com/457254
174 PrefService* pref = g_browser_process->local_state(); 195 PrefService* localPref = g_browser_process->local_state();
175 if (pref) { // May be NULL during testing. 196 PrefService* profilePref = profile->GetPrefs();
dominickn 2017/01/19 07:01:22 local_state_prefs and profile_prefs
ramyasharma 2017/01/20 04:04:45 Done.
176 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 197 if (localPref && profilePref) { // May be NULL during testing.
177 198 DictionaryPrefUpdate update_excluded_schemas(
199 localPref, prefs::kExcludedSchemes);
200 DictionaryPrefUpdate update_excluded_schemas_profile(
201 profilePref, prefs::kExcludedSchemes);
202 bool is_profile_state = !update_excluded_schemas_profile->empty();
178 if (state == UNKNOWN) { 203 if (state == UNKNOWN) {
179 update_excluded_schemas->Remove(scheme, NULL); 204 is_profile_state
dominickn 2017/01/19 07:01:22 What do you think about migrating here as well? My
ramyasharma 2017/01/20 04:04:45 Yes, ideally that's how it is. Removed code that u
180 } else { 205 ? update_excluded_schemas_profile->Remove(scheme, NULL)
181 update_excluded_schemas->SetBoolean(scheme, (state == BLOCK)); 206 : update_excluded_schemas->Remove(scheme, NULL);
207 } else {
208 is_profile_state
dominickn 2017/01/19 07:01:22 Nit: indentation.
ramyasharma 2017/01/20 04:04:45 Done.
209 ? update_excluded_schemas_profile->SetBoolean(
210 scheme, (state == BLOCK))
211 :update_excluded_schemas->SetBoolean(scheme, (state == BLOCK));
dominickn 2017/01/19 07:01:22 Nit: space after :
ramyasharma 2017/01/20 04:04:45 Done.
182 } 212 }
183 } 213 }
184 } 214 }
185 215
186 // static 216 // static
187 void ExternalProtocolHandler::LaunchUrlWithDelegate( 217 void ExternalProtocolHandler::LaunchUrlWithDelegate(
188 const GURL& url, 218 const GURL& url,
189 int render_process_host_id, 219 int render_process_host_id,
190 int render_view_routing_id, 220 int render_view_routing_id,
191 ui::PageTransition page_transition, 221 ui::PageTransition page_transition,
192 bool has_user_gesture, 222 bool has_user_gesture,
193 Delegate* delegate) { 223 Delegate* delegate) {
194 DCHECK(base::MessageLoopForUI::IsCurrent()); 224 DCHECK(base::MessageLoopForUI::IsCurrent());
195 225
196 // Escape the input scheme to be sure that the command does not 226 // Escape the input scheme to be sure that the command does not
197 // have parameters unexpected by the external program. 227 // have parameters unexpected by the external program.
198 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec()); 228 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec());
199 GURL escaped_url(escaped_url_string); 229 GURL escaped_url(escaped_url_string);
230
231 content::WebContents* web_contents = tab_util::GetWebContentsByID(
232 render_process_host_id, render_view_routing_id);
233 Profile* profile = NULL;
dominickn 2017/01/19 07:01:22 Use nullptr instead of NULL (this is a very old fi
ramyasharma 2017/01/20 04:04:45 Done.
234 if (web_contents) { // Maybe NULL during testing.
dominickn 2017/01/19 07:01:22 Nit: no braces around a one-line else.
ramyasharma 2017/01/20 04:04:45 Done.
235 profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
236 }
200 BlockState block_state = 237 BlockState block_state =
201 GetBlockStateWithDelegate(escaped_url.scheme(), delegate); 238 GetBlockStateWithDelegate(escaped_url.scheme(), delegate, profile);
202 if (block_state == BLOCK) { 239 if (block_state == BLOCK) {
203 if (delegate) 240 if (delegate)
204 delegate->BlockRequest(); 241 delegate->BlockRequest();
205 return; 242 return;
206 } 243 }
207 244
208 g_accept_requests = false; 245 g_accept_requests = false;
209 246
210 // The worker creates tasks with references to itself and puts them into 247 // The worker creates tasks with references to itself and puts them into
211 // message loops. 248 // message loops.
(...skipping 24 matching lines...) Expand all
236 273
237 // static 274 // static
238 void ExternalProtocolHandler::PermitLaunchUrl() { 275 void ExternalProtocolHandler::PermitLaunchUrl() {
239 DCHECK(base::MessageLoopForUI::IsCurrent()); 276 DCHECK(base::MessageLoopForUI::IsCurrent());
240 g_accept_requests = true; 277 g_accept_requests = true;
241 } 278 }
242 279
243 // static 280 // static
244 void ExternalProtocolHandler::PrepopulateDictionary( 281 void ExternalProtocolHandler::PrepopulateDictionary(
245 base::DictionaryValue* win_pref) { 282 base::DictionaryValue* win_pref) {
246 static bool is_warm = false;
247 if (is_warm)
248 return;
249 is_warm = true;
250
251 static const char* const denied_schemes[] = { 283 static const char* const denied_schemes[] = {
252 "afp", 284 "afp",
253 "data", 285 "data",
254 "disk", 286 "disk",
255 "disks", 287 "disks",
256 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply 288 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply
257 // execute the file specified! Hopefully we won't see any "file" schemes 289 // execute the file specified! Hopefully we won't see any "file" schemes
258 // because we think of file:// URLs as handled URLs, but better to be safe 290 // because we think of file:// URLs as handled URLs, but better to be safe
259 // than to let an attacker format the user's hard drive. 291 // than to let an attacker format the user's hard drive.
260 "file", 292 "file",
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 324 }
293 325
294 // static 326 // static
295 void ExternalProtocolHandler::RecordMetrics(bool selected) { 327 void ExternalProtocolHandler::RecordMetrics(bool selected) {
296 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox", 328 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox",
297 selected); 329 selected);
298 } 330 }
299 331
300 // static 332 // static
301 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { 333 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) {
302 registry->RegisterDictionaryPref(prefs::kExcludedSchemes); 334 registry->RegisterDictionaryPref(prefs::kExcludedSchemes);
303 } 335 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698