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/chromeos/login/signin/auth_sync_observer.h"
7 #include "base/metrics/user_metrics.h"
8 #include "base/metrics/user_metrics_action.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/chromeos/login/reauth_stats.h"
11 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
12 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
13 #include "chrome/browser/chromeos/profiles/profile_helper.h"
14 #include "chrome/browser/sync/profile_sync_service.h"
15 #include "chrome/browser/sync/profile_sync_service_factory.h"
16 #include "components/user_manager/user_manager.h"
17 #include "components/user_manager/user_type.h"
18 #include "content/public/browser/user_metrics.h"
19 #include "google_apis/gaia/gaia_auth_util.h"
22 class ProfileSyncService
;
26 AuthSyncObserver::AuthSyncObserver(Profile
* profile
)
30 AuthSyncObserver::~AuthSyncObserver() {
33 void AuthSyncObserver::StartObserving() {
34 ProfileSyncService
* sync_service
=
35 ProfileSyncServiceFactory::GetForProfile(profile_
);
37 sync_service
->AddObserver(this);
40 void AuthSyncObserver::Shutdown() {
41 ProfileSyncService
* sync_service
=
42 ProfileSyncServiceFactory::GetForProfile(profile_
);
44 sync_service
->RemoveObserver(this);
47 void AuthSyncObserver::OnStateChanged() {
48 DCHECK(user_manager::UserManager::Get()->IsLoggedInAsUserWithGaiaAccount() ||
49 user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser());
50 ProfileSyncService
* sync_service
=
51 ProfileSyncServiceFactory::GetForProfile(profile_
);
52 const user_manager::User
* user
=
53 ProfileHelper::Get()->GetUserByProfile(profile_
);
54 GoogleServiceAuthError::State state
=
55 sync_service
->GetAuthError().state();
56 if (state
!= GoogleServiceAuthError::NONE
&&
57 state
!= GoogleServiceAuthError::CONNECTION_FAILED
&&
58 state
!= GoogleServiceAuthError::SERVICE_UNAVAILABLE
&&
59 state
!= GoogleServiceAuthError::REQUEST_CANCELED
) {
60 // Invalidate OAuth2 refresh token to force Gaia sign-in flow. This is
61 // needed because sign-out/sign-in solution is suggested to the user.
62 // TODO(nkostylev): Remove after crosbug.com/25978 is implemented.
63 LOG(WARNING
) << "Invalidate OAuth token because of a sync error: "
64 << sync_service
->GetAuthError().ToString();
65 std::string email
= user
->email();
66 DCHECK(!email
.empty());
67 // TODO(nkostyelv): Change observer after active user has changed.
68 user_manager::User::OAuthTokenStatus old_status
=
69 user
->oauth_token_status();
70 user_manager::UserManager::Get()->SaveUserOAuthStatus(
71 email
, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID
);
72 RecordReauthReason(email
, ReauthReason::SYNC_FAILED
);
73 if (user
->GetType() == user_manager::USER_TYPE_SUPERVISED
&&
74 old_status
!= user_manager::User::OAUTH2_TOKEN_STATUS_INVALID
) {
75 // Attempt to restore token from file.
76 ChromeUserManager::Get()
77 ->GetSupervisedUserManager()
78 ->LoadSupervisedUserToken(
80 base::Bind(&AuthSyncObserver::OnSupervisedTokenLoaded
,
81 base::Unretained(this)));
82 content::RecordAction(
83 base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Invalidated"));
85 } else if (state
== GoogleServiceAuthError::NONE
) {
86 if (user
->GetType() == user_manager::USER_TYPE_SUPERVISED
&&
87 user
->oauth_token_status() ==
88 user_manager::User::OAUTH2_TOKEN_STATUS_INVALID
) {
90 "Got an incorrectly invalidated token case, restoring token status.";
91 user_manager::UserManager::Get()->SaveUserOAuthStatus(
92 user
->email(), user_manager::User::OAUTH2_TOKEN_STATUS_VALID
);
93 content::RecordAction(
94 base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Recovered"));
99 void AuthSyncObserver::OnSupervisedTokenLoaded(const std::string
& token
) {
100 ChromeUserManager::Get()->GetSupervisedUserManager()->ConfigureSyncWithToken(
104 } // namespace chromeos