Componentize component_updater: Copy over test data with executable bit.
[chromium-blink-merge.git] / chrome / browser / password_manager / chrome_password_manager_client.cc
blobc5c50bf4136126177d73dbf711fad41cdcd6e35e
1 // Copyright 2014 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/password_manager/chrome_password_manager_client.h"
7 #include "base/bind_helpers.h"
8 #include "base/command_line.h"
9 #include "base/memory/singleton.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/password_manager/password_manager_util.h"
13 #include "chrome/browser/password_manager/password_store_factory.h"
14 #include "chrome/browser/password_manager/save_password_infobar_delegate.h"
15 #include "chrome/browser/password_manager/sync_metrics.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/sync/profile_sync_service.h"
18 #include "chrome/browser/sync/profile_sync_service_factory.h"
19 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h"
20 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "chrome/common/url_constants.h"
24 #include "components/autofill/content/common/autofill_messages.h"
25 #include "components/autofill/core/browser/password_generator.h"
26 #include "components/autofill/core/common/password_form.h"
27 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
28 #include "components/password_manager/core/browser/log_receiver.h"
29 #include "components/password_manager/core/browser/password_form_manager.h"
30 #include "components/password_manager/core/browser/password_manager.h"
31 #include "components/password_manager/core/browser/password_manager_internals_service.h"
32 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
33 #include "components/password_manager/core/common/password_manager_switches.h"
34 #include "content/public/browser/navigation_entry.h"
35 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h"
37 #include "google_apis/gaia/gaia_urls.h"
38 #include "net/base/url_util.h"
40 #if defined(OS_ANDROID)
41 #include "chrome/browser/android/password_authentication_manager.h"
42 #endif // OS_ANDROID
44 using password_manager::PasswordManagerInternalsService;
45 using password_manager::PasswordManagerInternalsServiceFactory;
47 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromePasswordManagerClient);
49 // static
50 void ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
51 content::WebContents* contents,
52 autofill::AutofillClient* autofill_client) {
53 if (FromWebContents(contents))
54 return;
56 contents->SetUserData(
57 UserDataKey(),
58 new ChromePasswordManagerClient(contents, autofill_client));
61 ChromePasswordManagerClient::ChromePasswordManagerClient(
62 content::WebContents* web_contents,
63 autofill::AutofillClient* autofill_client)
64 : content::WebContentsObserver(web_contents),
65 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
66 driver_(web_contents, this, autofill_client),
67 observer_(NULL),
68 weak_factory_(this),
69 can_use_log_router_(false),
70 autofill_sync_state_(ALLOW_SYNC_CREDENTIALS),
71 sync_credential_was_filtered_(false) {
72 PasswordManagerInternalsService* service =
73 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
74 if (service)
75 can_use_log_router_ = service->RegisterClient(this);
76 SetUpAutofillSyncState();
79 ChromePasswordManagerClient::~ChromePasswordManagerClient() {
80 PasswordManagerInternalsService* service =
81 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
82 if (service)
83 service->UnregisterClient(this);
86 bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
87 return CommandLine::ForCurrentProcess()->HasSwitch(
88 password_manager::switches::kEnableAutomaticPasswordSaving) &&
89 chrome::VersionInfo::GetChannel() ==
90 chrome::VersionInfo::CHANNEL_UNKNOWN;
93 bool ChromePasswordManagerClient::IsPasswordManagerEnabledForCurrentPage()
94 const {
95 if (EnabledForSyncSignin())
96 return true;
98 DCHECK(web_contents());
99 content::NavigationEntry* entry =
100 web_contents()->GetController().GetLastCommittedEntry();
101 if (!entry) {
102 // TODO(gcasto): Determine if fix for crbug.com/388246 is relevant here.
103 return true;
105 // Do not fill nor save password when a user is signing in for sync. This
106 // is because users need to remember their password if they are syncing as
107 // this is effectively their master password.
108 return entry->GetURL().host() != chrome::kChromeUIChromeSigninHost;
111 bool ChromePasswordManagerClient::ShouldFilterAutofillResult(
112 const autofill::PasswordForm& form) {
113 if (!IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
114 form.signon_realm))
115 return false;
117 if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
118 sync_credential_was_filtered_ = true;
119 return true;
122 if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
123 LastLoadWasTransactionalReauthPage()) {
124 sync_credential_was_filtered_ = true;
125 return true;
128 return false;
131 bool ChromePasswordManagerClient::IsSyncAccountCredential(
132 const std::string& username, const std::string& origin) const {
133 return password_manager_sync_metrics::IsSyncAccountCredential(
134 profile_, username, origin);
137 void ChromePasswordManagerClient::AutofillResultsComputed() {
138 UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
139 sync_credential_was_filtered_);
140 sync_credential_was_filtered_ = false;
143 void ChromePasswordManagerClient::PromptUserToSavePassword(
144 scoped_ptr<password_manager::PasswordFormManager> form_to_save) {
145 if (IsTheHotNewBubbleUIEnabled()) {
146 ManagePasswordsUIController* manage_passwords_ui_controller =
147 ManagePasswordsUIController::FromWebContents(web_contents());
148 manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save.Pass());
149 } else {
150 std::string uma_histogram_suffix(
151 password_manager::metrics_util::GroupIdToString(
152 password_manager::metrics_util::MonitoredDomainGroupId(
153 form_to_save->realm(), GetPrefs())));
154 SavePasswordInfoBarDelegate::Create(
155 web_contents(), form_to_save.Pass(), uma_histogram_suffix);
159 void ChromePasswordManagerClient::AutomaticPasswordSave(
160 scoped_ptr<password_manager::PasswordFormManager> saved_form) {
161 if (IsTheHotNewBubbleUIEnabled()) {
162 ManagePasswordsUIController* manage_passwords_ui_controller =
163 ManagePasswordsUIController::FromWebContents(web_contents());
164 manage_passwords_ui_controller->OnAutomaticPasswordSave(
165 saved_form.Pass());
169 void ChromePasswordManagerClient::PasswordWasAutofilled(
170 const autofill::PasswordFormMap& best_matches) const {
171 ManagePasswordsUIController* manage_passwords_ui_controller =
172 ManagePasswordsUIController::FromWebContents(web_contents());
173 if (manage_passwords_ui_controller && IsTheHotNewBubbleUIEnabled())
174 manage_passwords_ui_controller->OnPasswordAutofilled(best_matches);
177 void ChromePasswordManagerClient::PasswordAutofillWasBlocked(
178 const autofill::PasswordFormMap& best_matches) const {
179 ManagePasswordsUIController* controller =
180 ManagePasswordsUIController::FromWebContents(web_contents());
181 if (controller && IsTheHotNewBubbleUIEnabled())
182 controller->OnBlacklistBlockedAutofill(best_matches);
185 void ChromePasswordManagerClient::AuthenticateAutofillAndFillForm(
186 scoped_ptr<autofill::PasswordFormFillData> fill_data) {
187 #if defined(OS_ANDROID)
188 PasswordAuthenticationManager::AuthenticatePasswordAutofill(
189 web_contents(),
190 base::Bind(&ChromePasswordManagerClient::CommitFillPasswordForm,
191 weak_factory_.GetWeakPtr(),
192 base::Owned(fill_data.release())));
193 #else
194 // Additional authentication is currently only available for Android, so all
195 // other plaftorms should just fill the password form directly.
196 CommitFillPasswordForm(fill_data.get());
197 #endif // OS_ANDROID
200 void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
201 if (popup_controller_)
202 popup_controller_->HideAndDestroy();
205 PrefService* ChromePasswordManagerClient::GetPrefs() {
206 return profile_->GetPrefs();
209 password_manager::PasswordStore*
210 ChromePasswordManagerClient::GetPasswordStore() {
211 // Always use EXPLICIT_ACCESS as the password manager checks IsOffTheRecord
212 // itself when it shouldn't access the PasswordStore.
213 // TODO(gcasto): Is is safe to change this to Profile::IMPLICIT_ACCESS?
214 return PasswordStoreFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS)
215 .get();
218 password_manager::PasswordManagerDriver*
219 ChromePasswordManagerClient::GetDriver() {
220 return &driver_;
223 base::FieldTrial::Probability
224 ChromePasswordManagerClient::GetProbabilityForExperiment(
225 const std::string& experiment_name) {
226 base::FieldTrial::Probability enabled_probability = 0;
227 if (experiment_name ==
228 password_manager::PasswordManager::kOtherPossibleUsernamesExperiment) {
229 switch (chrome::VersionInfo::GetChannel()) {
230 case chrome::VersionInfo::CHANNEL_DEV:
231 case chrome::VersionInfo::CHANNEL_BETA:
232 enabled_probability = 50;
233 break;
234 default:
235 break;
238 return enabled_probability;
241 bool ChromePasswordManagerClient::IsPasswordSyncEnabled() {
242 ProfileSyncService* sync_service =
243 ProfileSyncServiceFactory::GetForProfile(profile_);
244 // Don't consider sync enabled if the user has a custom passphrase. See
245 // crbug.com/358998 for more details.
246 if (sync_service &&
247 sync_service->HasSyncSetupCompleted() &&
248 sync_service->sync_initialized() &&
249 !sync_service->IsUsingSecondaryPassphrase()) {
250 return sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS);
252 return false;
255 void ChromePasswordManagerClient::OnLogRouterAvailabilityChanged(
256 bool router_can_be_used) {
257 if (can_use_log_router_ == router_can_be_used)
258 return;
259 can_use_log_router_ = router_can_be_used;
261 NotifyRendererOfLoggingAvailability();
264 void ChromePasswordManagerClient::LogSavePasswordProgress(
265 const std::string& text) {
266 if (!IsLoggingActive())
267 return;
268 PasswordManagerInternalsService* service =
269 PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
270 if (service)
271 service->ProcessLog(text);
274 bool ChromePasswordManagerClient::IsLoggingActive() const {
275 // WebUI tabs do not need to log password saving progress. In particular, the
276 // internals page itself should not send any logs.
277 return can_use_log_router_ && !web_contents()->GetWebUI();
280 // static
281 password_manager::PasswordGenerationManager*
282 ChromePasswordManagerClient::GetGenerationManagerFromWebContents(
283 content::WebContents* contents) {
284 ChromePasswordManagerClient* client =
285 ChromePasswordManagerClient::FromWebContents(contents);
286 if (!client)
287 return NULL;
288 return client->GetDriver()->GetPasswordGenerationManager();
291 // static
292 password_manager::PasswordManager*
293 ChromePasswordManagerClient::GetManagerFromWebContents(
294 content::WebContents* contents) {
295 ChromePasswordManagerClient* client =
296 ChromePasswordManagerClient::FromWebContents(contents);
297 if (!client)
298 return NULL;
299 return client->GetDriver()->GetPasswordManager();
302 void ChromePasswordManagerClient::SetTestObserver(
303 autofill::PasswordGenerationPopupObserver* observer) {
304 observer_ = observer;
307 bool ChromePasswordManagerClient::OnMessageReceived(
308 const IPC::Message& message) {
309 bool handled = true;
310 IPC_BEGIN_MESSAGE_MAP(ChromePasswordManagerClient, message)
311 IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordGenerationPopup,
312 ShowPasswordGenerationPopup)
313 IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordEditingPopup,
314 ShowPasswordEditingPopup)
315 IPC_MESSAGE_HANDLER(AutofillHostMsg_HidePasswordGenerationPopup,
316 HidePasswordGenerationPopup)
317 IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordAutofillAgentConstructed,
318 NotifyRendererOfLoggingAvailability)
319 IPC_MESSAGE_UNHANDLED(handled = false)
320 IPC_END_MESSAGE_MAP()
321 return handled;
324 gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
325 const gfx::RectF& bounds) {
326 gfx::Rect client_area = web_contents()->GetContainerBounds();
327 return bounds + client_area.OffsetFromOrigin();
330 void ChromePasswordManagerClient::ShowPasswordGenerationPopup(
331 const gfx::RectF& bounds,
332 int max_length,
333 const autofill::PasswordForm& form) {
334 // TODO(gcasto): Validate data in PasswordForm.
336 // Not yet implemented on other platforms.
337 #if defined(USE_AURA) || defined(OS_MACOSX)
338 gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
340 popup_controller_ =
341 autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
342 popup_controller_,
343 element_bounds_in_screen_space,
344 form,
345 max_length,
346 driver_.GetPasswordManager(),
347 observer_,
348 web_contents(),
349 web_contents()->GetNativeView());
350 popup_controller_->Show(true /* display_password */);
351 #endif // defined(USE_AURA) || defined(OS_MACOSX)
354 void ChromePasswordManagerClient::ShowPasswordEditingPopup(
355 const gfx::RectF& bounds,
356 const autofill::PasswordForm& form) {
357 gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
358 // Not yet implemented on other platforms.
359 #if defined(USE_AURA) || defined(OS_MACOSX)
360 popup_controller_ =
361 autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
362 popup_controller_,
363 element_bounds_in_screen_space,
364 form,
365 0, // Unspecified max length.
366 driver_.GetPasswordManager(),
367 observer_,
368 web_contents(),
369 web_contents()->GetNativeView());
370 popup_controller_->Show(false /* display_password */);
371 #endif // defined(USE_AURA) || defined(OS_MACOSX)
374 void ChromePasswordManagerClient::NotifyRendererOfLoggingAvailability() {
375 if (!web_contents())
376 return;
378 web_contents()->GetRenderViewHost()->Send(new AutofillMsg_SetLoggingState(
379 web_contents()->GetRenderViewHost()->GetRoutingID(),
380 can_use_log_router_));
383 void ChromePasswordManagerClient::CommitFillPasswordForm(
384 autofill::PasswordFormFillData* data) {
385 driver_.FillPasswordForm(*data);
388 bool ChromePasswordManagerClient::LastLoadWasTransactionalReauthPage() const {
389 DCHECK(web_contents());
390 content::NavigationEntry* entry =
391 web_contents()->GetController().GetLastCommittedEntry();
392 if (!entry)
393 return false;
395 if (entry->GetURL().GetOrigin() !=
396 GaiaUrls::GetInstance()->gaia_url().GetOrigin())
397 return false;
399 // "rart" is the transactional reauth paramter.
400 std::string ignored_value;
401 return net::GetValueForKeyInQuery(entry->GetURL(),
402 "rart",
403 &ignored_value);
406 bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() {
407 #if !defined(USE_AURA)
408 return false;
409 #endif
410 CommandLine* command_line = CommandLine::ForCurrentProcess();
411 if (command_line->HasSwitch(switches::kDisableSavePasswordBubble))
412 return false;
414 if (command_line->HasSwitch(switches::kEnableSavePasswordBubble))
415 return true;
417 std::string group_name =
418 base::FieldTrialList::FindFullName("PasswordManagerUI");
420 // The bubble should be the default case that runs on the bots.
421 return group_name != "Infobar";
424 bool ChromePasswordManagerClient::EnabledForSyncSignin() {
425 CommandLine* command_line = CommandLine::ForCurrentProcess();
426 if (command_line->HasSwitch(
427 password_manager::switches::kDisableManagerForSyncSignin))
428 return false;
430 if (command_line->HasSwitch(
431 password_manager::switches::kEnableManagerForSyncSignin))
432 return true;
434 // Default is enabled.
435 std::string group_name =
436 base::FieldTrialList::FindFullName("PasswordManagerStateForSyncSignin");
437 return group_name != "Disabled";
440 void ChromePasswordManagerClient::SetUpAutofillSyncState() {
441 std::string group_name =
442 base::FieldTrialList::FindFullName("AutofillSyncCredential");
444 CommandLine* command_line = CommandLine::ForCurrentProcess();
445 if (command_line->HasSwitch(
446 password_manager::switches::kAllowAutofillSyncCredential)) {
447 autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
448 return;
450 if (command_line->HasSwitch(
451 password_manager::switches::
452 kDisallowAutofillSyncCredentialForReauth)) {
453 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
454 return;
456 if (command_line->HasSwitch(
457 password_manager::switches::kDisallowAutofillSyncCredential)) {
458 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
459 return;
462 if (group_name == "DisallowSyncCredentialsForReauth") {
463 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
464 } else if (group_name == "DisallowSyncCredentials") {
465 autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
466 } else {
467 // Allow by default.
468 autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;