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