user_cloud_policy_manager_chromeos.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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/chromeos/policy/user_cloud_policy_manager_chromeos.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/logging.h" 10#include "base/memory/ref_counted.h" 11#include "chrome/browser/browser_process.h" 12#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h" 13#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" 14#include "chrome/browser/chromeos/profiles/profile_helper.h" 15#include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 16#include "chrome/browser/policy/cloud/resource_cache.h" 17#include "chrome/browser/policy/policy_bundle.h" 18#include "chrome/browser/policy/policy_domain_descriptor.h" 19#include "chrome/common/pref_names.h" 20#include "net/url_request/url_request_context_getter.h" 21 22namespace em = enterprise_management; 23 24namespace policy { 25 26UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS( 27 scoped_ptr<CloudPolicyStore> store, 28 scoped_ptr<ResourceCache> resource_cache, 29 bool wait_for_policy_fetch) 30 : CloudPolicyManager( 31 PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()), 32 store.get()), 33 store_(store.Pass()), 34 wait_for_policy_fetch_(wait_for_policy_fetch) { 35 if (resource_cache) { 36 component_policy_service_.reset(new ComponentCloudPolicyService( 37 this, store_.get(), resource_cache.Pass())); 38 } 39} 40 41UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {} 42 43void UserCloudPolicyManagerChromeOS::Connect( 44 PrefService* local_state, 45 DeviceManagementService* device_management_service, 46 scoped_refptr<net::URLRequestContextGetter> request_context, 47 UserAffiliation user_affiliation) { 48 DCHECK(device_management_service); 49 DCHECK(local_state); 50 local_state_ = local_state; 51 scoped_ptr<CloudPolicyClient> cloud_policy_client( 52 new CloudPolicyClient(std::string(), std::string(), user_affiliation, 53 NULL, device_management_service)); 54 core()->Connect(cloud_policy_client.Pass()); 55 client()->AddObserver(this); 56 57 if (component_policy_service_) 58 component_policy_service_->Connect(client(), request_context); 59 60 // Determine the next step after the CloudPolicyService initializes. 61 if (service()->IsInitializationComplete()) { 62 OnInitializationCompleted(service()); 63 } else { 64 service()->AddObserver(this); 65 } 66} 67 68void UserCloudPolicyManagerChromeOS::OnRefreshTokenAvailable( 69 const std::string& refresh_token) { 70 oauth2_login_tokens_.refresh_token = refresh_token; 71 if (!oauth2_login_tokens_.refresh_token.empty() && 72 service() && service()->IsInitializationComplete() && 73 client() && !client()->is_registered()) { 74 FetchPolicyOAuthTokenUsingRefreshToken(); 75 } 76} 77 78bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const { 79 return client() && client()->is_registered(); 80} 81 82void UserCloudPolicyManagerChromeOS::Shutdown() { 83 if (client()) 84 client()->RemoveObserver(this); 85 if (service()) 86 service()->RemoveObserver(this); 87 token_fetcher_.reset(); 88 component_policy_service_.reset(); 89 CloudPolicyManager::Shutdown(); 90} 91 92bool UserCloudPolicyManagerChromeOS::IsInitializationComplete( 93 PolicyDomain domain) const { 94 if (!CloudPolicyManager::IsInitializationComplete(domain)) 95 return false; 96 if (domain == POLICY_DOMAIN_CHROME) 97 return !wait_for_policy_fetch_; 98 if (ComponentCloudPolicyService::SupportsDomain(domain) && 99 component_policy_service_) { 100 return component_policy_service_->is_initialized(); 101 } 102 return true; 103} 104 105void UserCloudPolicyManagerChromeOS::RegisterPolicyDomain( 106 scoped_refptr<const PolicyDomainDescriptor> descriptor) { 107 if (ComponentCloudPolicyService::SupportsDomain(descriptor->domain()) && 108 component_policy_service_) { 109 component_policy_service_->RegisterPolicyDomain(descriptor); 110 } 111} 112 113scoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() { 114 scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle(); 115 if (component_policy_service_) 116 bundle->MergeFrom(component_policy_service_->policy()); 117 return bundle.Pass(); 118} 119 120void UserCloudPolicyManagerChromeOS::OnInitializationCompleted( 121 CloudPolicyService* cloud_policy_service) { 122 DCHECK_EQ(service(), cloud_policy_service); 123 cloud_policy_service->RemoveObserver(this); 124 // If the CloudPolicyClient isn't registered at this stage then it needs an 125 // OAuth token for the initial registration. 126 // 127 // If |wait_for_policy_fetch_| is true then Profile initialization is blocking 128 // on the initial policy fetch, so the token must be fetched immediately. 129 // In that case, the signin Profile is used to authenticate a Gaia request to 130 // fetch a refresh token, and then the policy token is fetched. 131 // 132 // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder 133 // service will eventually call OnRefreshTokenAvailable() once the 134 // TokenService has one. That call may have already happened while waiting for 135 // 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, std::string()); 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