user_policy_signin_service.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1// Copyright (c) 2012 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/policy/cloud/user_policy_signin_service.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/callback.h" 10#include "base/prefs/pref_service.h" 11#include "chrome/browser/browser_process.h" 12#include "chrome/browser/chrome_notification_types.h" 13#include "chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h" 14#include "chrome/browser/policy/cloud/user_cloud_policy_manager.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/profiles/profile_manager.h" 17#include "chrome/browser/signin/signin_manager.h" 18#include "chrome/browser/signin/signin_manager_factory.h" 19#include "chrome/browser/signin/token_service.h" 20#include "chrome/browser/signin/token_service_factory.h" 21#include "chrome/common/pref_names.h" 22#include "content/public/browser/notification_details.h" 23#include "google_apis/gaia/gaia_constants.h" 24 25#if defined(ENABLE_MANAGED_USERS) 26#include "chrome/browser/managed_mode/managed_user_service.h" 27#endif 28 29namespace policy { 30 31UserPolicySigninService::UserPolicySigninService( 32 Profile* profile) : UserPolicySigninServiceBase(profile) { 33 if (profile->GetPrefs()->GetBoolean(prefs::kDisableCloudPolicyOnSignin)) 34 return; 35 36 // Listen for an OAuth token to become available so we can register a client 37 // if for some reason the client is not already registered (for example, if 38 // the policy load failed during initial signin). 39 registrar()->Add(this, 40 chrome::NOTIFICATION_TOKEN_AVAILABLE, 41 content::Source<TokenService>( 42 TokenServiceFactory::GetForProfile(profile))); 43 44 // TokenService should not yet have loaded its tokens since this happens in 45 // the background after PKS initialization - so this service should always be 46 // created before the oauth token is available. 47 DCHECK(!TokenServiceFactory::GetForProfile(profile)->HasOAuthLoginToken()); 48 49 // Register a listener for the import finished notification in a first run 50 // scenario, which indicates the profile is ready to be further initialized. 51 registrar()->Add(this, 52 chrome::NOTIFICATION_IMPORT_FINISHED, 53 content::Source<Profile>(profile)); 54} 55 56UserPolicySigninService::~UserPolicySigninService() {} 57 58void UserPolicySigninService::Shutdown() { 59 // Stop any pending registration helper activity. We do this here instead of 60 // in the destructor because we want to shutdown the registration helper 61 // before UserCloudPolicyManager shuts down the CloudPolicyClient. 62 registration_helper_.reset(); 63 UserPolicySigninServiceBase::Shutdown(); 64} 65 66void UserPolicySigninService::RegisterPolicyClient( 67 const std::string& username, 68 const std::string& oauth2_refresh_token, 69 const PolicyRegistrationCallback& callback) { 70 DCHECK(!oauth2_refresh_token.empty()); 71 72 // Create a new CloudPolicyClient for fetching the DMToken. 73 scoped_ptr<CloudPolicyClient> policy_client = PrepareToRegister(username); 74 if (!policy_client) { 75 callback.Run(policy_client.Pass()); 76 return; 77 } 78 79 // Fire off the registration process. Callback keeps the CloudPolicyClient 80 // alive for the length of the registration process. 81 registration_helper_.reset(new CloudPolicyClientRegistrationHelper( 82 profile()->GetRequestContext(), 83 policy_client.get(), 84 ShouldForceLoadPolicy(), 85 enterprise_management::DeviceRegisterRequest::BROWSER)); 86 registration_helper_->StartRegistrationWithLoginToken( 87 oauth2_refresh_token, 88 base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback, 89 base::Unretained(this), 90 base::Passed(&policy_client), 91 callback)); 92} 93 94void UserPolicySigninService::CallPolicyRegistrationCallback( 95 scoped_ptr<CloudPolicyClient> client, 96 PolicyRegistrationCallback callback) { 97 registration_helper_.reset(); 98 if (!client->is_registered()) { 99 // Registration failed, so free the client and pass NULL to the callback. 100 client.reset(); 101 } 102 callback.Run(client.Pass()); 103} 104 105void UserPolicySigninService::Observe( 106 int type, 107 const content::NotificationSource& source, 108 const content::NotificationDetails& details) { 109 // If an import process is running, wait for NOTIFICATION_IMPORT_FINISHED 110 // before potentially creating the SigninManager. Its dependencies can access 111 // databases that the import process is also accessing, causing conflicts. 112 // Note that the profile manager is NULL in unit tests. 113 if (g_browser_process->profile_manager() && 114 g_browser_process->profile_manager()->will_import()) { 115 return; 116 } 117 118#if defined(ENABLE_MANAGED_USERS) 119 if (ManagedUserService::ProfileIsManaged(profile())) { 120 registrar()->RemoveAll(); 121 return; 122 } 123#endif 124 125 // If using a TestingProfile with no SigninManager or UserCloudPolicyManager, 126 // skip initialization. 127 if (!GetManager() || !SigninManagerFactory::GetForProfile(profile())) { 128 DVLOG(1) << "Skipping initialization for tests due to missing components."; 129 return; 130 } 131 132 switch (type) { 133 case chrome::NOTIFICATION_IMPORT_FINISHED: 134 InitializeOnProfileReady(); 135 break; 136 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 137 const TokenService::TokenAvailableDetails& token_details = 138 *(content::Details<const TokenService::TokenAvailableDetails>( 139 details).ptr()); 140 if (token_details.service() == 141 GaiaConstants::kGaiaOAuth2LoginRefreshToken) { 142 SigninManager* signin_manager = 143 SigninManagerFactory::GetForProfile(profile()); 144 std::string username = signin_manager->GetAuthenticatedUsername(); 145 // Should not have GAIA tokens if the user isn't signed in. 146 DCHECK(!username.empty()); 147 // TokenService now has a refresh token (implying that the user is 148 // signed in) so initialize the UserCloudPolicyManager. 149 InitializeForSignedInUser(username); 150 } 151 break; 152 } 153 default: 154 UserPolicySigninServiceBase::Observe(type, source, details); 155 } 156} 157 158void UserPolicySigninService::InitializeUserCloudPolicyManager( 159 scoped_ptr<CloudPolicyClient> client) { 160 UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(client.Pass()); 161 ProhibitSignoutIfNeeded(); 162} 163 164void UserPolicySigninService::ShutdownUserCloudPolicyManager() { 165 UserCloudPolicyManager* manager = GetManager(); 166 if (manager) { 167 // Allow the user to signout again. 168 SigninManagerFactory::GetForProfile(profile())->ProhibitSignout(false); 169 } 170 UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager(); 171} 172 173void UserPolicySigninService::OnInitializationCompleted( 174 CloudPolicyService* service) { 175 UserCloudPolicyManager* manager = GetManager(); 176 DCHECK_EQ(service, manager->core()->service()); 177 DCHECK(service->IsInitializationComplete()); 178 // The service is now initialized - if the client is not yet registered, then 179 // it means that there is no cached policy and so we need to initiate a new 180 // client registration. 181 DVLOG_IF(1, manager->IsClientRegistered()) 182 << "Client already registered - not fetching DMToken"; 183 if (!manager->IsClientRegistered()) { 184 std::string token = TokenServiceFactory::GetForProfile(profile())-> 185 GetOAuth2LoginRefreshToken(); 186 if (token.empty()) { 187 // No token yet - this class listens for NOTIFICATION_TOKEN_AVAILABLE 188 // and will re-attempt registration once the token is available. 189 DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download"; 190 return; 191 } 192 RegisterCloudPolicyService(token); 193 } 194 // If client is registered now, prohibit signout. 195 ProhibitSignoutIfNeeded(); 196} 197 198void UserPolicySigninService::RegisterCloudPolicyService( 199 const std::string& login_token) { 200 DCHECK(!GetManager()->IsClientRegistered()); 201 DVLOG(1) << "Fetching new DM Token"; 202 // Do nothing if already starting the registration process. 203 if (registration_helper_) 204 return; 205 206 // Start the process of registering the CloudPolicyClient. Once it completes, 207 // policy fetch will automatically happen. 208 registration_helper_.reset(new CloudPolicyClientRegistrationHelper( 209 profile()->GetRequestContext(), 210 GetManager()->core()->client(), 211 ShouldForceLoadPolicy(), 212 enterprise_management::DeviceRegisterRequest::BROWSER)); 213 registration_helper_->StartRegistrationWithLoginToken( 214 login_token, 215 base::Bind(&UserPolicySigninService::OnRegistrationComplete, 216 base::Unretained(this))); 217} 218 219void UserPolicySigninService::OnRegistrationComplete() { 220 ProhibitSignoutIfNeeded(); 221 registration_helper_.reset(); 222} 223 224void UserPolicySigninService::ProhibitSignoutIfNeeded() { 225 if (GetManager()->IsClientRegistered()) { 226 DVLOG(1) << "User is registered for policy - prohibiting signout"; 227 SigninManager* signin_manager = 228 SigninManagerFactory::GetForProfile(profile()); 229 signin_manager->ProhibitSignout(true); 230 } 231} 232 233} // namespace policy 234