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 "chrome/browser/browser_process.h" 11 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h" 12 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" 13 #include "chrome/browser/chromeos/profiles/profile_helper.h" 14 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 15 #include "chrome/browser/policy/cloud/resource_cache.h" 16 #include "chrome/browser/policy/policy_bundle.h" 17 #include "chrome/browser/policy/policy_domain_descriptor.h" 18 #include "chrome/common/pref_names.h" 19 #include "net/url_request/url_request_context_getter.h" 20 21 namespace em = enterprise_management; 22 23 namespace policy { 24 25 UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS( 26 scoped_ptr<CloudPolicyStore> store, 27 scoped_ptr<ResourceCache> resource_cache, 28 bool wait_for_policy_fetch, 29 base::TimeDelta initial_policy_fetch_timeout) 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 policy_fetch_timeout_(false, false) { 36 if (wait_for_policy_fetch_) { 37 policy_fetch_timeout_.Start( 38 FROM_HERE, 39 initial_policy_fetch_timeout, 40 base::Bind(&UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch, 41 base::Unretained(this))); 42 } 43 if (resource_cache) { 44 component_policy_service_.reset(new ComponentCloudPolicyService( 45 this, store_.get(), resource_cache.Pass())); 46 } 47 } 48 49 UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {} 50 51 void UserCloudPolicyManagerChromeOS::Connect( 52 PrefService* local_state, 53 DeviceManagementService* device_management_service, 54 scoped_refptr<net::URLRequestContextGetter> request_context, 55 UserAffiliation user_affiliation) { 56 DCHECK(device_management_service); 57 DCHECK(local_state); 58 local_state_ = local_state; 59 scoped_ptr<CloudPolicyClient> cloud_policy_client( 60 new CloudPolicyClient(std::string(), std::string(), user_affiliation, 61 NULL, device_management_service)); 62 core()->Connect(cloud_policy_client.Pass()); 63 client()->AddObserver(this); 64 65 if (component_policy_service_) 66 component_policy_service_->Connect(client(), request_context); 67 68 // Determine the next step after the CloudPolicyService initializes. 69 if (service()->IsInitializationComplete()) { 70 OnInitializationCompleted(service()); 71 } else { 72 service()->AddObserver(this); 73 } 74 } 75 76 void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable( 77 const std::string& access_token) { 78 access_token_ = access_token; 79 if (service() && service()->IsInitializationComplete() && 80 client() && !client()->is_registered()) { 81 OnOAuth2PolicyTokenFetched( 82 access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 83 } 84 } 85 86 bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const { 87 return client() && client()->is_registered(); 88 } 89 90 void UserCloudPolicyManagerChromeOS::Shutdown() { 91 if (client()) 92 client()->RemoveObserver(this); 93 if (service()) 94 service()->RemoveObserver(this); 95 token_fetcher_.reset(); 96 component_policy_service_.reset(); 97 CloudPolicyManager::Shutdown(); 98 } 99 100 bool UserCloudPolicyManagerChromeOS::IsInitializationComplete( 101 PolicyDomain domain) const { 102 if (!CloudPolicyManager::IsInitializationComplete(domain)) 103 return false; 104 if (domain == POLICY_DOMAIN_CHROME) 105 return !wait_for_policy_fetch_; 106 if (ComponentCloudPolicyService::SupportsDomain(domain) && 107 component_policy_service_) { 108 return component_policy_service_->is_initialized(); 109 } 110 return true; 111 } 112 113 void UserCloudPolicyManagerChromeOS::RegisterPolicyDomain( 114 scoped_refptr<const PolicyDomainDescriptor> descriptor) { 115 if (ComponentCloudPolicyService::SupportsDomain(descriptor->domain()) && 116 component_policy_service_) { 117 component_policy_service_->RegisterPolicyDomain(descriptor); 118 } 119 } 120 121 scoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() { 122 scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle(); 123 if (component_policy_service_) 124 bundle->MergeFrom(component_policy_service_->policy()); 125 return bundle.Pass(); 126 } 127 128 void UserCloudPolicyManagerChromeOS::OnInitializationCompleted( 129 CloudPolicyService* cloud_policy_service) { 130 DCHECK_EQ(service(), cloud_policy_service); 131 cloud_policy_service->RemoveObserver(this); 132 // If the CloudPolicyClient isn't registered at this stage then it needs an 133 // OAuth token for the initial registration. 134 // 135 // If |wait_for_policy_fetch_| is true then Profile initialization is blocking 136 // on the initial policy fetch, so the token must be fetched immediately. 137 // In that case, the signin Profile is used to authenticate a Gaia request to 138 // fetch a refresh token, and then the policy token is fetched. 139 // 140 // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder 141 // service will eventually call OnAccessTokenAvailable() once an access token 142 // is available. That call may have already happened while waiting for 143 // initialization of the CloudPolicyService, so in that case check if an 144 // access token is already available. 145 if (!client()->is_registered()) { 146 if (wait_for_policy_fetch_) { 147 FetchPolicyOAuthTokenUsingSigninProfile(); 148 } else if (!access_token_.empty()) { 149 OnOAuth2PolicyTokenFetched( 150 access_token_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 151 } 152 } 153 154 if (!wait_for_policy_fetch_) { 155 // If this isn't blocking on a policy fetch then 156 // CloudPolicyManager::OnStoreLoaded() already published the cached policy. 157 // Start the refresh scheduler now, which will eventually refresh the 158 // cached policy or make the first fetch once the OAuth2 token is 159 // available. 160 StartRefreshSchedulerIfReady(); 161 } 162 } 163 164 void UserCloudPolicyManagerChromeOS::OnPolicyFetched( 165 CloudPolicyClient* client) { 166 // No action required. If we're blocked on a policy fetch, we'll learn about 167 // completion of it through OnInitialPolicyFetchComplete(). 168 } 169 170 void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged( 171 CloudPolicyClient* cloud_policy_client) { 172 DCHECK_EQ(client(), cloud_policy_client); 173 if (wait_for_policy_fetch_) { 174 // If we're blocked on the policy fetch, now is a good time to issue it. 175 if (client()->is_registered()) { 176 service()->RefreshPolicy( 177 base::Bind( 178 &UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete, 179 base::Unretained(this))); 180 } else { 181 // If the client has switched to not registered, we bail out as this 182 // indicates the cloud policy setup flow has been aborted. 183 CancelWaitForPolicyFetch(); 184 } 185 } 186 } 187 188 void UserCloudPolicyManagerChromeOS::OnClientError( 189 CloudPolicyClient* cloud_policy_client) { 190 DCHECK_EQ(client(), cloud_policy_client); 191 CancelWaitForPolicyFetch(); 192 } 193 194 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyRefreshNeeded() { 195 core()->RefreshSoon(); 196 } 197 198 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() { 199 CheckAndPublishPolicy(); 200 StartRefreshSchedulerIfReady(); 201 } 202 203 void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() { 204 scoped_refptr<net::URLRequestContextGetter> signin_context; 205 Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile(); 206 if (signin_profile) 207 signin_context = signin_profile->GetRequestContext(); 208 if (!signin_context.get()) { 209 LOG(ERROR) << "No signin Profile for policy oauth token fetch!"; 210 OnOAuth2PolicyTokenFetched( 211 std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 212 return; 213 } 214 215 token_fetcher_.reset(new PolicyOAuth2TokenFetcher( 216 signin_context.get(), 217 g_browser_process->system_request_context(), 218 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched, 219 base::Unretained(this)))); 220 token_fetcher_->Start(); 221 } 222 223 void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched( 224 const std::string& policy_token, 225 const GoogleServiceAuthError& error) { 226 DCHECK(!client()->is_registered()); 227 if (error.state() == GoogleServiceAuthError::NONE) { 228 // Start client registration. Either OnRegistrationStateChanged() or 229 // OnClientError() will be called back. 230 client()->Register(em::DeviceRegisterRequest::USER, 231 policy_token, std::string(), false, std::string()); 232 } else { 233 // Failed to get a token, stop waiting and use an empty policy. 234 CancelWaitForPolicyFetch(); 235 } 236 237 token_fetcher_.reset(); 238 } 239 240 void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete( 241 bool success) { 242 CancelWaitForPolicyFetch(); 243 } 244 245 void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() { 246 if (!wait_for_policy_fetch_) 247 return; 248 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 StartRefreshSchedulerIfReady(); 254 } 255 256 void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() { 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 StartRefreshScheduler(); 275 core()->TrackRefreshDelayPref(local_state_, prefs::kUserPolicyRefreshRate); 276 } 277 278 } // namespace policy 279