1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/signin/auth_sync_observer.h" 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics_action.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/prefs/pref_service.h" 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/profiles/profile_helper.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/pref_names.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_type.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class Profile; 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ProfileSyncService; 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace chromeos { 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)AuthSyncObserver::AuthSyncObserver(Profile* profile) 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : profile_(profile) { 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)AuthSyncObserver::~AuthSyncObserver() { 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AuthSyncObserver::StartObserving() { 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncService* sync_service = 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (sync_service) 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_service->AddObserver(this); 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AuthSyncObserver::Shutdown() { 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncService* sync_service = 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (sync_service) 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_service->RemoveObserver(this); 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AuthSyncObserver::OnStateChanged() { 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(user_manager::UserManager::Get()->IsLoggedInAsRegularUser() || 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()); 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncService* sync_service = 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile_); 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GoogleServiceAuthError::State state = 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_service->GetAuthError().state(); 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (state != GoogleServiceAuthError::NONE && 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) state != GoogleServiceAuthError::CONNECTION_FAILED && 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) state != GoogleServiceAuthError::SERVICE_UNAVAILABLE && 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) state != GoogleServiceAuthError::REQUEST_CANCELED) { 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Invalidate OAuth2 refresh token to force Gaia sign-in flow. This is 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // needed because sign-out/sign-in solution is suggested to the user. 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(nkostylev): Remove after crosbug.com/25978 is implemented. 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(WARNING) << "Invalidate OAuth token because of a sync error: " 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << sync_service->GetAuthError().ToString(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string email = user->email(); 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!email.empty()); 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(nkostyelv): Change observer after active user has changed. 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user_manager::User::OAuthTokenStatus old_status = 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user->oauth_token_status(); 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) user_manager::UserManager::Get()->SaveUserOAuthStatus( 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) email, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (user->GetType() == user_manager::USER_TYPE_SUPERVISED && 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_status != user_manager::User::OAUTH2_TOKEN_STATUS_INVALID) { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Attempt to restore token from file. 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChromeUserManager::Get() 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ->GetSupervisedUserManager() 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ->LoadSupervisedUserToken( 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) profile_, 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&AuthSyncObserver::OnSupervisedTokenLoaded, 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Unretained(this))); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RecordAction( 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Invalidated")); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (state == GoogleServiceAuthError::NONE) { 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (user->GetType() == user_manager::USER_TYPE_SUPERVISED && 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user->oauth_token_status() == 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user_manager::User::OAUTH2_TOKEN_STATUS_INVALID) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Got an incorrectly invalidated token case, restoring token status."; 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) user_manager::UserManager::Get()->SaveUserOAuthStatus( 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user->email(), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RecordAction( 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UserMetricsAction("ManagedUsers_Chromeos_Sync_Recovered")); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AuthSyncObserver::OnSupervisedTokenLoaded(const std::string& token) { 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChromeUserManager::Get()->GetSupervisedUserManager()->ConfigureSyncWithToken( 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_, token); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace chromeos 103