File: profile_picker_dice_reauth_provider.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 (144 lines) | stat: -rw-r--r-- 5,564 bytes parent folder | download | duplicates (3)
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
// Copyright 2023 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_VIEWS_PROFILES_PROFILE_PICKER_DICE_REAUTH_PROVIDER_H_
#define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_DICE_REAUTH_PROVIDER_H_

#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/ui/views/profiles/profile_management_types.h"
#include "chrome/browser/ui/webui/signin/signin_ui_error.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "content/public/browser/web_contents_observer.h"
#include "google_apis/gaia/gaia_id.h"

struct CoreAccountInfo;
class ForceSigninVerifier;
class Profile;
class ProfilePickerWebContentsHost;

namespace content {
class WebContents;
}

// Enum used to recorded histogram results for the reauth step.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class ProfilePickerReauthResult {
  kSuccess = 0,
  kSuccessTokenAlreadyValid = 1,
  kErrorUsedNewEmail = 2,
  kErrorUsedOtherSignedInEmail = 3,
  kTimeoutForceSigninVerifierCheck = 4,
  kTimeoutSigninError = 5,
  kMaxValue = kTimeoutSigninError
};

// This object handles the reauth of the main account of a Profile.
// The flow starts with the call to `SwitchToReauth()` and goes as follow:
// - Extract the primary account for which the reauth will be attempted.
// - Wait for the refresh tokens to be loaded.
// - Call to the ForceSigninVerifier to check the main account token status.
// - If the token is valid, there is no need to reauth, and we finish with
// success.
// - If it is not, we show the reauth gaia page and await for user to reauth.
// - Await a sign in event and a refersh token for the account that is being
// reauthed through `OnRefreshTokenUpdatedForAccount()`.
// - We finish the flow by replying to the callback based on the success of the
// last step (checking if the account that got reauthed matches with the
// original one).
class ProfilePickerDiceReauthProvider
    : public signin::IdentityManager::Observer,
      public content::WebContentsObserver {
 public:
  ProfilePickerDiceReauthProvider(
      ProfilePickerWebContentsHost* host,
      Profile* profile,
      const GaiaId& gaia_id_to_reauth,
      const std::string& email_to_reauth,
      base::OnceCallback<void(bool, const ForceSigninUIError&)>
          on_reauth_completed);
  ~ProfilePickerDiceReauthProvider() override;

  ProfilePickerDiceReauthProvider(const ProfilePickerDiceReauthProvider&) =
      delete;
  ProfilePickerDiceReauthProvider& operator=(
      const ProfilePickerDiceReauthProvider&) = delete;

  content::WebContents* contents() const { return contents_.get(); }

  // Start the reauth process.
  void SwitchToReauth(StepSwitchFinishedCallback step_switch_callback);

  // signin::IdentityManager::Observer:
  void OnRefreshTokensLoaded() override;
  void OnRefreshTokenUpdatedForAccount(
      const CoreAccountInfo& account_info) override;

  // content::WebContentsObserver:
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;

 private:
  // Attempt to create the ForceSigninVerifier, refresh tokens should be loaded.
  void TryCreateForceSigninVerifier();

  // Timeout callback if the ForceSigninVerifier timed out. Finishing the flow
  // with a failure.
  void OnForceSigninVerifierTimeOut();

  // Callback to the ForceSigninVerifier after fetching the tokens.
  void OnTokenFetchComplete(bool token_is_valid);

  // Display the reauth URL in `host_`.
  void ShowReauth();

  // Callback for the dice tab helper;
  //
  // When a successful sign in occurs.
  void OnDiceSigninHeaderReceived();
  // When a signin error occurs.
  void OnSigninError(Profile* profile,
                     content::WebContents* web_contents,
                     const SigninUIError& error);

  // Finish the reauth step on the Gaia side, and return to the caller
  // through the `on_reauth_completed_`.
  // Also records the result (success/errors) in a histogram.
  void Finish(bool success, ProfilePickerReauthResult result);

  const raw_ref<ProfilePickerWebContentsHost> host_;
  raw_ref<Profile> profile_;
  raw_ref<signin::IdentityManager> identity_manager_;
  const GaiaId gaia_id_to_reauth_;
  const std::string email_to_reauth_;
  base::OnceCallback<void(bool, const ForceSigninUIError&)>
      on_reauth_completed_;

  // This callback will only return once we know whether the step should be
  // shown or not.
  StepSwitchFinishedCallback step_switch_callback_;

  // Prevent `profile_` from being destroyed first.
  std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive_;

  // The web contents backed by `profile_`. This is used for displaying the
  // reauth flow.
  // Before displaying the reauth, this is used to display a loading screen
  // while the ForceSigninVerifier is performing a network call.
  std::unique_ptr<content::WebContents> contents_;
  std::unique_ptr<ForceSigninVerifier> force_signin_verifier_;

  bool signin_event_received_ = false;

  // The timer is used for a timeout delay for the ForceSigninVerifier.
  base::OneShotTimer timer_;

  base::ScopedObservation<signin::IdentityManager,
                          signin::IdentityManager::Observer>
      scoped_identity_manager_observation_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_PICKER_DICE_REAUTH_PROVIDER_H_