File: manage_passwords_ui_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (405 lines) | stat: -rw-r--r-- 16,577 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
#define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_

#include <list>
#include <memory>
#include <optional>
#include <vector>

#include "base/auto_reset.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/passwords/manage_passwords_state.h"
#include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h"
#include "chrome/browser/ui/passwords/passwords_leak_dialog_delegate.h"
#include "chrome/browser/ui/passwords/passwords_model_delegate.h"
#include "chrome/common/buildflags.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/password_manager/core/browser/ui/post_save_compromised_helper.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"

namespace base {
class TimeDelta;
}

namespace content {
class WebContents;
}

namespace password_manager {
enum class CredentialType;
struct InteractionsStats;
struct PasswordForm;
class MovePasswordToAccountStoreHelper;
class PasswordFeatureManager;
class PasswordFormManagerForUI;
class PostSaveCompromisedHelper;
}  // namespace password_manager

namespace {
inline constexpr int kMaxNumberOfTimesBiometricAuthForFillingPromoWillBeShown =
    3;
}

class AccountChooserPrompt;
class AutoSigninFirstRunPrompt;
class CredentialLeakPrompt;
class ManagePasswordsIconView;
class CredentialLeakDialogController;
class CredentialManagerDialogController;
class PasswordBaseDialogController;

// Per-tab class to control the Omnibox password icon and bubble.
class ManagePasswordsUIController
    : public content::WebContentsObserver,
      public content::WebContentsUserData<ManagePasswordsUIController>,
      public password_manager::PasswordStoreInterface::Observer,
      public PasswordsLeakDialogDelegate,
      public PasswordsModelDelegate,
      public PasswordsClientUIDelegate {
 public:
  ManagePasswordsUIController(const ManagePasswordsUIController&) = delete;
  ManagePasswordsUIController& operator=(const ManagePasswordsUIController&) =
      delete;

  ~ManagePasswordsUIController() override;

#if defined(UNIT_TEST)
  static void set_save_fallback_timeout_in_seconds(int timeout) {
    save_fallback_timeout_in_seconds_ = timeout;
  }
#endif

  // PasswordsClientUIDelegate:
  void OnPasswordSubmitted(
      std::unique_ptr<password_manager::PasswordFormManagerForUI> form_manager)
      override;
  void OnUpdatePasswordSubmitted(
      std::unique_ptr<password_manager::PasswordFormManagerForUI> form_manager)
      override;
  void OnShowManualFallbackForSaving(
      std::unique_ptr<password_manager::PasswordFormManagerForUI> form_manager,
      bool has_generated_password,
      bool is_update) override;
  void OnHideManualFallbackForSaving() override;
  void OnOpenPasswordDetailsBubble(
      const password_manager::PasswordForm& form) override;
  bool OnChooseCredentials(
      std::vector<std::unique_ptr<password_manager::PasswordForm>>
          local_credentials,
      const url::Origin& origin,
      ManagePasswordsState::CredentialsCallback callback) override;
  void OnAutoSignin(
      std::vector<std::unique_ptr<password_manager::PasswordForm>> local_forms,
      const url::Origin& origin) override;
  void OnPromptEnableAutoSignin() override;
  void OnAutomaticPasswordSave(
      std::unique_ptr<password_manager::PasswordFormManagerForUI> form_manager,
      bool is_update_confirmation) override;
  void OnPasswordAutofilled(
      base::span<const password_manager::PasswordForm> password_forms,
      const url::Origin& origin,
      base::span<const password_manager::PasswordForm> federated_matches)
      override;
  void OnCredentialLeak(
      password_manager::LeakedPasswordDetails details) override;
  void OnShowMoveToAccountBubble(
      std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_move)
      override;
  void OnBiometricAuthenticationForFilling(PrefService* prefs) override;
  void ShowBiometricActivationConfirmation() override;
  void ShowMovePasswordBubble(
      const password_manager::PasswordForm& form) override;
  void OnBiometricAuthBeforeFillingDeclined() override;
  void OnAddUsernameSaveClicked(
      const std::u16string& username,
      const password_manager::PasswordForm& form_to_update) override;
  void OnKeychainError() override;
  void OnPasskeySaved(bool gpm_pin_created, std::string passkey_rp_id) override;
  void OnPasskeyDeleted() override;
  void OnPasskeyUpdated(std::string passkey_rp_id) override;
  void OnPasskeyNotAccepted(std::string passkey_rp_id) override;
  void OnPasskeyUpgrade(std::string passkey_rp_id) override;

  virtual void NotifyUnsyncedCredentialsWillBeDeleted(
      std::vector<password_manager::PasswordForm> unsynced_credentials);

  // PasswordStoreInterface::Observer:
  void OnLoginsChanged(
      password_manager::PasswordStoreInterface* store,
      const password_manager::PasswordStoreChangeList& changes) override;
  void OnLoginsRetained(password_manager::PasswordStoreInterface* store,
                        const std::vector<password_manager::PasswordForm>&
                            retained_passwords) override;

  // Set the state of the Omnibox icon, and possibly show the associated bubble
  // without user interaction.
  virtual void UpdateIconAndBubbleState(ManagePasswordsIconView* icon);

  // Called if the password change flow finishes successfully. It ensures the
  // correct state after the flow.
  void OnPasswordChangeFinishedSuccessfully();

  // True iff the bubble is to be opened automatically.
  bool IsAutomaticallyOpeningBubble() const {
    return bubble_status_ == BubbleStatus::SHOULD_POP_UP;
  }

  // virtual to be overridden in tests.
  virtual base::WeakPtr<PasswordsModelDelegate> GetModelDelegateProxy();

  // PasswordsModelDelegate:
  content::WebContents* GetWebContents() const override;
  url::Origin GetOrigin() const override;
  password_manager::PasswordFormMetricsRecorder*
  GetPasswordFormMetricsRecorder() override;
  password_manager::PasswordFeatureManager* GetPasswordFeatureManager()
      override;
  password_manager::ui::State GetState() const override;
  const password_manager::PasswordForm& GetPendingPassword() const override;
  const std::vector<password_manager::PasswordForm>& GetUnsyncedCredentials()
      const override;
  password_manager::metrics_util::CredentialSourceType GetCredentialSource()
      const override;
  const std::vector<std::unique_ptr<password_manager::PasswordForm>>&
  GetCurrentForms() const override;
  const std::optional<password_manager::PasswordForm>&
  GetManagePasswordsSingleCredentialDetailsModeCredential() const override;
  const password_manager::InteractionsStats* GetCurrentInteractionStats()
      const override;
  size_t GetTotalNumberCompromisedPasswords() const override;
  bool BubbleIsManualFallbackForSaving() const override;
  bool GpmPinCreatedDuringRecentPasskeyCreation() const override;
  const std::string& PasskeyRpId() const override;
  void OnBubbleShown() override;
  void OnBubbleHidden() override;
  void OnNoInteraction() override;
  void OnNopeUpdateClicked() override;
  void NeverSavePassword() override;
  void OnNotNowClicked() override;
  void OnPasswordsRevealed() override;
  void SavePassword(const std::u16string& username,
                    const std::u16string& password) override;
  void SaveUnsyncedCredentialsInProfileStore(
      const std::vector<password_manager::PasswordForm>& selected_credentials)
      override;
  void DiscardUnsyncedCredentials() override;
  void MovePasswordToAccountStore() override;
  void MovePendingPasswordToAccountStoreUsingHelper(
      const password_manager::PasswordForm& form,
      password_manager::metrics_util::MoveToAccountStoreTrigger trigger)
      override;
  void BlockMovingPasswordToAccountStore() override;
  void ChooseCredential(
      const password_manager::PasswordForm& form,
      password_manager::CredentialType credential_type) override;
  void NavigateToPasswordManagerSettingsPage(
      password_manager::ManagePasswordsReferrer referrer) override;
  void NavigateToPasswordDetailsPageInPasswordManager(
      const std::string& password_domain_name,
      password_manager::ManagePasswordsReferrer referrer) override;
  void OnDialogHidden() override;
  void AuthenticateUserWithMessage(const std::u16string& message,
                                   AvailabilityCallback callback) override;
  void MaybeShowIOSPasswordPromo() override;
  void RelaunchChrome() override;
  void NavigateToPasswordChangeSettings() override;
  // Skips user os level authentication during the life time of the returned
  // object. To be used in tests of flows that require user authentication.
  [[nodiscard]] std::unique_ptr<base::AutoReset<bool>>
  BypassUserAuthtForTesting();
#if defined(UNIT_TEST)
  // Overwrites the client for |passwords_data_|.
  void set_client(password_manager::PasswordManagerClient* client) {
    passwords_data_.set_client(client);
  }
#endif  // defined(UNIT_TEST)

  // Hides/Shows the bubble if opened. Mocked in the tests.
  virtual void HidePasswordBubble();
  virtual void ShowChangePasswordBubble();

  bool IsShowingBubble() const {
    return bubble_status_ == BubbleStatus::SHOWN ||
           bubble_status_ == BubbleStatus::SHOWN_PENDING_ICON_UPDATE;
  }

 protected:
  explicit ManagePasswordsUIController(content::WebContents* web_contents);

  // Called when a PasswordForm is autofilled, when a new PasswordForm is
  // submitted, or when a navigation occurs to update the visibility of the
  // manage passwords icon and bubble.
  virtual void UpdateBubbleAndIconVisibility();

  // Called to create the account chooser dialog. Mocked in tests.
  virtual AccountChooserPrompt* CreateAccountChooser(
      CredentialManagerDialogController* controller);

  // Called to create the account chooser dialog. Mocked in tests.
  virtual AutoSigninFirstRunPrompt* CreateAutoSigninPrompt(
      CredentialManagerDialogController* controller);

  // Called to create the credentials leaked dialog.
  virtual std::unique_ptr<CredentialLeakPrompt> CreateCredentialLeakPrompt(
      CredentialLeakDialogController* controller);

  // Check if |web_contents()| is attached to some Browser. Mocked in tests.
  virtual bool HasBrowserWindow() const;

  // Creates new MovePasswordToAccountStoreHelper object and thus starts the
  // moving process for the pending password.
  virtual std::unique_ptr<password_manager::MovePasswordToAccountStoreHelper>
  CreateMovePasswordToAccountStoreHelper(
      const password_manager::PasswordForm& form,
      password_manager::metrics_util::MoveToAccountStoreTrigger trigger,
      base::OnceCallback<void()> on_move_finished);

  // Returns whether the bubble is currently open.
  bool IsShowingBubbleForTest() const { return IsShowingBubble(); }

  // content::WebContentsObserver:
  void PrimaryPageChanged(content::Page& page) override;
  void OnVisibilityChanged(content::Visibility visibility) override;

  PasswordChangeDelegate* GetPasswordChangeDelegate() const override;

  PasswordsLeakDialogDelegate* GetPasswordsLeakDialogDelegate() override;

 private:
  friend class content::WebContentsUserData<ManagePasswordsUIController>;

  void OnReauthCompleted();

  // PasswordsLeakDialogDelegate:
  void NavigateToPasswordCheckup(
      password_manager::PasswordCheckReferrer referrer) override;
  void OnLeakDialogHidden() override;

  enum class BubbleStatus {
    NOT_SHOWN,
    // The bubble is to be popped up in the next call to
    // UpdateBubbleAndIconVisibility().
    SHOULD_POP_UP,
    SHOWN,
    // Same as SHOWN but the icon is to be updated when the bubble is closed.
    SHOWN_PENDING_ICON_UPDATE,
    // The bubble is to be popped up in the next call to
    // UpdateBubbleAndIconVisibility() and will be focused automatically.
    SHOULD_POP_UP_WITH_FOCUS,
  };

  // The status of the saving prompt.
  enum class SavingPromptStatus {
    // The prompt can show.
    kCanShow,
    // The current site is explicitly blocklisted.
    kExplicitlyBlocklisted,
    // The bubble for the current site is implicitly blocked.
    kImplicitlyBlocked
  };

  // Returns whether saving credentials prompts for the current form in
  // |passwords_data_| is blocked due to explicit action of the user asking to
  // never save passwords for this form, or because the user ignored the bubble
  // multiple times that the browser will automatically suppress further save
  // prompts.
  SavingPromptStatus GetSavingPromptStatus() const;

  // Returns whether the current site is explicitly blocklisted.
  bool IsExplicitlyBlocklisted() const;

  // Returns the timeout for the manual save fallback.
  static base::TimeDelta GetTimeoutForSaveFallback();

  // Shows the password bubble without user interaction.
  void ShowBubbleWithoutUserInteraction();

  // Resets |bubble_status_| signalling that if the bubble was due to pop up,
  // it shouldn't anymore.
  void ClearPopUpFlagForBubble();

  // Closes the account chooser gracefully so the callback is called. Closes the
  // password bubble. Then sets the state to MANAGE_STATE.
  void DestroyPopups();

  // content::WebContentsObserver:
  void WebContentsDestroyed() override;

  void OnTriggerPostSaveCompromisedBubble(
      password_manager::PostSaveCompromisedHelper::BubbleType type,
      size_t count_compromised_passwords_);

  void OnMovePasswordToAccountStoreComplete(
      std::list<std::unique_ptr<
          password_manager::MovePasswordToAccountStoreHelper>>::iterator
          done_helper_it);

  // Cancels current authentication and releases |biometric_authenticator_|.
  void CancelAnyOngoingBiometricAuth();

  // Returns true if the password that is about to be changed was previously
  // phished.
  bool IsPendingPasswordPhished() const;

  // Returns true if password changing is currently running.
  bool IsPasswordChangeOngoing() const;

  // Timeout in seconds for the manual fallback for saving.
  static int save_fallback_timeout_in_seconds_;

  // The wrapper around current state and data.
  ManagePasswordsState passwords_data_;

  // The controller for the blocking dialogs.
  std::unique_ptr<PasswordBaseDialogController> dialog_controller_;

  // The helper to pop up a reminder about compromised passwords.
  std::unique_ptr<password_manager::PostSaveCompromisedHelper>
      post_save_compromised_helper_;

  BubbleStatus bubble_status_ = BubbleStatus::NOT_SHOWN;

  // The timer that controls whether the fallback for saving should be
  // available. Should be reset once the fallback is not needed (an automatic
  // popup will be shown or the user saved/updated the password with the
  // fallback).
  base::OneShotTimer save_fallback_timer_;

  // Contains the helpers currently executing moving tasks. This will almost
  // always contain either 0 or 1 items.
  std::list<std::unique_ptr<password_manager::MovePasswordToAccountStoreHelper>>
      move_to_account_store_helpers_;

  std::unique_ptr<device_reauth::DeviceAuthenticator> biometric_authenticator_;

  // Used to bypass user authentication in integration tests.
  bool bypass_user_auth_for_testing_ = false;

#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
  bool was_biometric_authentication_for_filling_promo_shown_ = false;
#endif

  // The bubbles of different types can pop up unpredictably superseding each
  // other. However, closing the bubble may affect the state of
  // ManagePasswordsUIController internally. This is undesired if
  // ManagePasswordsUIController is in the process of opening a new bubble. The
  // situation is worse on Windows where the bubble is destroyed asynchronously.
  // Thus, OnBubbleHidden() can be called after the new one is shown. By that
  // time the internal state of ManagePasswordsUIController has nothing to do
  // with the old bubble.
  // Invalidating all the weak pointers will detach the current bubble.
  base::WeakPtrFactory<ManagePasswordsUIController> weak_ptr_factory_{this};

  WEB_CONTENTS_USER_DATA_KEY_DECL();
};

#endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_