user_cloud_policy_manager_chromeos.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson// Use of this source code is governed by a BSD-style license that can be 32bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson// found in the LICENSE file. 42bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson 52bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" 62bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson 72bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "base/bind.h" 82bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "base/bind_helpers.h" 95217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson#include "base/logging.h" 105217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson#include "base/memory/ref_counted.h" 115217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson#include "chrome/browser/browser_process.h" 125217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h" 135217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" 142bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "chrome/browser/chromeos/profiles/profile_helper.h" 152bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 162bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "chrome/browser/policy/cloud/resource_cache.h" 172bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson#include "chrome/browser/policy/policy_bundle.h" 1848b2f3e4850cd27d54224cd42da8a160d6b95984Owen Anderson#include "chrome/common/pref_names.h" 19f53c371983908f02678b0e12c5d18466dcc70ffdOwen Anderson#include "net/url_request/url_request_context_getter.h" 20eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson 21f53c371983908f02678b0e12c5d18466dcc70ffdOwen Andersonnamespace em = enterprise_management; 22001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 23914e50c841bbc248ab94144c11813b5785b1292dOwen Andersonnamespace policy { 24001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 25001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen AndersonUserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS( 26ce032b483ca96093b84f69178cdb2d047e124332Owen Anderson scoped_ptr<CloudPolicyStore> store, 27aad3fb7362aff151e97ad457005ea3f2872fe868Owen Anderson scoped_ptr<ResourceCache> resource_cache, 28006c77df8cc7f6a9dac575600b797b8ba32b29ebOwen Anderson bool wait_for_policy_fetch) 2916e298f98024bcff5c7219a96cac216114c30dadOwen Anderson : CloudPolicyManager( 302bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()), 31eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson store.get()), 32001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson store_(store.Pass()), 33914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson wait_for_policy_fetch_(wait_for_policy_fetch) { 34aad3fb7362aff151e97ad457005ea3f2872fe868Owen Anderson if (resource_cache) { 35ce032b483ca96093b84f69178cdb2d047e124332Owen Anderson component_policy_service_.reset(new ComponentCloudPolicyService( 3648b2f3e4850cd27d54224cd42da8a160d6b95984Owen Anderson this, store_.get(), resource_cache.Pass())); 37001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson } 38ce032b483ca96093b84f69178cdb2d047e124332Owen Anderson} 39001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 40001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen AndersonUserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {} 41001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 42001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Andersonvoid UserCloudPolicyManagerChromeOS::Connect( 43001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson PrefService* local_state, 44001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson DeviceManagementService* device_management_service, 45001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson scoped_refptr<net::URLRequestContextGetter> request_context, 46001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson UserAffiliation user_affiliation) { 47001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson DCHECK(device_management_service); 48001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson DCHECK(local_state); 49001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson local_state_ = local_state; 50001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson scoped_ptr<CloudPolicyClient> cloud_policy_client( 51001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson new CloudPolicyClient(std::string(), std::string(), user_affiliation, 52001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson NULL, device_management_service)); 53001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson core()->Connect(cloud_policy_client.Pass()); 54001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson client()->AddObserver(this); 55001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 56001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson if (component_policy_service_) 57001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson component_policy_service_->Connect(client(), request_context); 58001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson 59001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson // Determine the next step after the CloudPolicyService initializes. 60001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson if (service()->IsInitializationComplete()) { 61001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson OnInitializationCompleted(service()); 62001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson } else { 63001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson service()->AddObserver(this); 64001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson } 65914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson} 66914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson 67914e50c841bbc248ab94144c11813b5785b1292dOwen Andersonvoid UserCloudPolicyManagerChromeOS::OnRefreshTokenAvailable( 68914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson const std::string& refresh_token) { 69914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson oauth2_login_tokens_.refresh_token = refresh_token; 70914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson if (!oauth2_login_tokens_.refresh_token.empty() && 71914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson service() && service()->IsInitializationComplete() && 72914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson client() && !client()->is_registered()) { 73914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson FetchPolicyOAuthTokenUsingRefreshToken(); 74914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson } 75914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson} 76914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson 77914e50c841bbc248ab94144c11813b5785b1292dOwen Andersonbool UserCloudPolicyManagerChromeOS::IsClientRegistered() const { 78914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson return client() && client()->is_registered(); 79914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson} 80914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson 81914e50c841bbc248ab94144c11813b5785b1292dOwen Andersonvoid UserCloudPolicyManagerChromeOS::Shutdown() { 82914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson if (client()) 83914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson client()->RemoveObserver(this); 84914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson if (service()) 85914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson service()->RemoveObserver(this); 86914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson token_fetcher_.reset(); 87914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson component_policy_service_.reset(); 88914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson CloudPolicyManager::Shutdown(); 89914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson} 90914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson 91914e50c841bbc248ab94144c11813b5785b1292dOwen Andersonbool UserCloudPolicyManagerChromeOS::IsInitializationComplete( 92d03eecd063a18ce0c505a87afcb04db26c035bc9Owen Anderson PolicyDomain domain) const { 93001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson if (!CloudPolicyManager::IsInitializationComplete(domain)) 94001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson return false; 95001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson if (domain == POLICY_DOMAIN_CHROME) 9648b2f3e4850cd27d54224cd42da8a160d6b95984Owen Anderson return !wait_for_policy_fetch_; 97001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson if (ComponentCloudPolicyService::SupportsDomain(domain) && 98001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson component_policy_service_) { 99914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson return component_policy_service_->is_initialized(); 10048b2f3e4850cd27d54224cd42da8a160d6b95984Owen Anderson } 101914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson return true; 102914e50c841bbc248ab94144c11813b5785b1292dOwen Anderson} 103aad3fb7362aff151e97ad457005ea3f2872fe868Owen Anderson 104aad3fb7362aff151e97ad457005ea3f2872fe868Owen Andersonvoid UserCloudPolicyManagerChromeOS::RegisterPolicyDomain( 105ce032b483ca96093b84f69178cdb2d047e124332Owen Anderson PolicyDomain domain, 106ce032b483ca96093b84f69178cdb2d047e124332Owen Anderson const std::set<std::string>& component_ids) { 107eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson if (ComponentCloudPolicyService::SupportsDomain(domain) && 108822ccd9974a17979d2cb9c6c118f94549055b7d4Owen Anderson component_policy_service_) { 109822ccd9974a17979d2cb9c6c118f94549055b7d4Owen Anderson component_policy_service_->RegisterPolicyDomain(domain, component_ids); 110822ccd9974a17979d2cb9c6c118f94549055b7d4Owen Anderson } 111eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson} 11216e298f98024bcff5c7219a96cac216114c30dadOwen Anderson 113006c77df8cc7f6a9dac575600b797b8ba32b29ebOwen Andersonscoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() { 114006c77df8cc7f6a9dac575600b797b8ba32b29ebOwen Anderson scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle(); 115eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson if (component_policy_service_) 116006c77df8cc7f6a9dac575600b797b8ba32b29ebOwen Anderson bundle->MergeFrom(component_policy_service_->policy()); 1175bd68393ed87bcedc53f5998f1af9c906f5a1b4eOwen Anderson return bundle.Pass(); 1185bd68393ed87bcedc53f5998f1af9c906f5a1b4eOwen Anderson} 119eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson 1205bd68393ed87bcedc53f5998f1af9c906f5a1b4eOwen Andersonvoid UserCloudPolicyManagerChromeOS::OnInitializationCompleted( 1217e3142b0126abc86dc4da350e8b84b001c3eeddeOwen Anderson CloudPolicyService* cloud_policy_service) { 1227e3142b0126abc86dc4da350e8b84b001c3eeddeOwen Anderson DCHECK_EQ(service(), cloud_policy_service); 1237e3142b0126abc86dc4da350e8b84b001c3eeddeOwen Anderson cloud_policy_service->RemoveObserver(this); 1247e3142b0126abc86dc4da350e8b84b001c3eeddeOwen Anderson // If the CloudPolicyClient isn't registered at this stage then it needs an 125d03eecd063a18ce0c505a87afcb04db26c035bc9Owen Anderson // OAuth token for the initial registration. 126d03eecd063a18ce0c505a87afcb04db26c035bc9Owen Anderson // 127f53c371983908f02678b0e12c5d18466dcc70ffdOwen Anderson // If |wait_for_policy_fetch_| is true then Profile initialization is blocking 128f53c371983908f02678b0e12c5d18466dcc70ffdOwen Anderson // on the initial policy fetch, so the token must be fetched immediately. 129f53c371983908f02678b0e12c5d18466dcc70ffdOwen Anderson // In that case, the signin Profile is used to authenticate a Gaia request to 13048b2f3e4850cd27d54224cd42da8a160d6b95984Owen Anderson // fetch a refresh token, and then the policy token is fetched. 1312bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson // 1322bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder 1332bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson // service will eventually call OnRefreshTokenAvailable() once the 1342bc29dc0bcb3c1441477a062e4a5cffff175c8caOwen Anderson // TokenService has one. That call may have already happened while waiting for 1355217007006e91fa4bbfe88fde5149f5db293b247Owen Anderson // initialization of the CloudPolicyService, so in that case check if a 136 // refresh token is already available. 137 if (!client()->is_registered()) { 138 if (wait_for_policy_fetch_) { 139 FetchPolicyOAuthTokenUsingSigninProfile(); 140 } else if (!oauth2_login_tokens_.refresh_token.empty()) { 141 FetchPolicyOAuthTokenUsingRefreshToken(); 142 } 143 } 144 145 if (!wait_for_policy_fetch_) { 146 // If this isn't blocking on a policy fetch then 147 // CloudPolicyManager::OnStoreLoaded() already published the cached policy. 148 // Start the refresh scheduler now, which will eventually refresh the 149 // cached policy or make the first fetch once the OAuth2 token is 150 // available. 151 StartRefreshScheduler(); 152 } 153} 154 155void UserCloudPolicyManagerChromeOS::OnPolicyFetched( 156 CloudPolicyClient* client) { 157 // No action required. If we're blocked on a policy fetch, we'll learn about 158 // completion of it through OnInitialPolicyFetchComplete(). 159} 160 161void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged( 162 CloudPolicyClient* cloud_policy_client) { 163 DCHECK_EQ(client(), cloud_policy_client); 164 if (wait_for_policy_fetch_) { 165 // If we're blocked on the policy fetch, now is a good time to issue it. 166 if (client()->is_registered()) { 167 service()->RefreshPolicy( 168 base::Bind( 169 &UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete, 170 base::Unretained(this))); 171 } else { 172 // If the client has switched to not registered, we bail out as this 173 // indicates the cloud policy setup flow has been aborted. 174 CancelWaitForPolicyFetch(); 175 } 176 } 177} 178 179void UserCloudPolicyManagerChromeOS::OnClientError( 180 CloudPolicyClient* cloud_policy_client) { 181 DCHECK_EQ(client(), cloud_policy_client); 182 CancelWaitForPolicyFetch(); 183} 184 185void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyRefreshNeeded() { 186 core()->RefreshSoon(); 187} 188 189void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() { 190 CheckAndPublishPolicy(); 191 StartRefreshScheduler(); 192} 193 194void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() { 195 scoped_refptr<net::URLRequestContextGetter> signin_context; 196 Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile(); 197 if (signin_profile) 198 signin_context = signin_profile->GetRequestContext(); 199 if (!signin_context) { 200 LOG(ERROR) << "No signin Profile for policy oauth token fetch!"; 201 OnOAuth2PolicyTokenFetched(std::string()); 202 return; 203 } 204 205 token_fetcher_.reset(new PolicyOAuth2TokenFetcher( 206 signin_context, 207 g_browser_process->system_request_context(), 208 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched, 209 base::Unretained(this)))); 210 token_fetcher_->Start(); 211} 212 213void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingRefreshToken() { 214 token_fetcher_.reset(new PolicyOAuth2TokenFetcher( 215 g_browser_process->system_request_context(), 216 oauth2_login_tokens_.refresh_token, 217 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched, 218 base::Unretained(this)))); 219 token_fetcher_->Start(); 220} 221 222void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched( 223 const std::string& policy_token) { 224 DCHECK(!client()->is_registered()); 225 // The TokenService will reuse the refresh token fetched by the 226 // |token_fetcher_|, if it fetched one. 227 if (token_fetcher_->has_oauth2_tokens()) 228 oauth2_login_tokens_ = token_fetcher_->oauth2_tokens(); 229 230 if (policy_token.empty()) { 231 // Failed to get a token, stop waiting and use an empty policy. 232 CancelWaitForPolicyFetch(); 233 } else { 234 // Start client registration. Either OnRegistrationStateChanged() or 235 // OnClientError() will be called back. 236 client()->Register(em::DeviceRegisterRequest::USER, 237 policy_token, std::string(), false); 238 } 239 240 token_fetcher_.reset(); 241} 242 243void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete( 244 bool success) { 245 CancelWaitForPolicyFetch(); 246} 247 248void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() { 249 wait_for_policy_fetch_ = false; 250 CheckAndPublishPolicy(); 251 // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler 252 // can be started. 253 StartRefreshScheduler(); 254} 255 256void UserCloudPolicyManagerChromeOS::StartRefreshScheduler() { 257 if (core()->refresh_scheduler()) 258 return; // Already started. 259 260 if (wait_for_policy_fetch_) 261 return; // Still waiting for the initial, blocking fetch. 262 263 if (!service() || !local_state_) 264 return; // Not connected. 265 266 if (component_policy_service_ && 267 !component_policy_service_->is_initialized()) { 268 // If the client doesn't have the list of components to fetch yet then don't 269 // start the scheduler. The |component_policy_service_| will call back into 270 // OnComponentCloudPolicyUpdated() once it's ready. 271 return; 272 } 273 274 core()->StartRefreshScheduler(); 275 core()->TrackRefreshDelayPref(local_state_, prefs::kUserPolicyRefreshRate); 276} 277 278} // namespace policy 279