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