user_cloud_policy_manager_chromeos.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
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
21namespace em = enterprise_management;
22
23namespace policy {
24
25UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
26    scoped_ptr<CloudPolicyStore> store,
27    scoped_ptr<ResourceCache> resource_cache,
28    bool wait_for_policy_fetch)
29    : CloudPolicyManager(
30          PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
31          store.get()),
32      store_(store.Pass()),
33      wait_for_policy_fetch_(wait_for_policy_fetch) {
34  if (resource_cache) {
35    component_policy_service_.reset(new ComponentCloudPolicyService(
36        this, store_.get(), resource_cache.Pass()));
37  }
38}
39
40UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
41
42void UserCloudPolicyManagerChromeOS::Connect(
43    PrefService* local_state,
44    DeviceManagementService* device_management_service,
45    scoped_refptr<net::URLRequestContextGetter> request_context,
46    UserAffiliation user_affiliation) {
47  DCHECK(device_management_service);
48  DCHECK(local_state);
49  local_state_ = local_state;
50  scoped_ptr<CloudPolicyClient> cloud_policy_client(
51      new CloudPolicyClient(std::string(), std::string(), user_affiliation,
52                            NULL, device_management_service));
53  core()->Connect(cloud_policy_client.Pass());
54  client()->AddObserver(this);
55
56  if (component_policy_service_)
57    component_policy_service_->Connect(client(), request_context);
58
59  // Determine the next step after the CloudPolicyService initializes.
60  if (service()->IsInitializationComplete()) {
61    OnInitializationCompleted(service());
62  } else {
63    service()->AddObserver(this);
64  }
65}
66
67void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
68    const std::string& access_token) {
69  access_token_ = access_token;
70  if (service() && service()->IsInitializationComplete() &&
71      client() && !client()->is_registered()) {
72    OnOAuth2PolicyTokenFetched(
73        access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
74  }
75}
76
77bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const {
78  return client() && client()->is_registered();
79}
80
81void UserCloudPolicyManagerChromeOS::Shutdown() {
82  if (client())
83    client()->RemoveObserver(this);
84  if (service())
85    service()->RemoveObserver(this);
86  token_fetcher_.reset();
87  component_policy_service_.reset();
88  CloudPolicyManager::Shutdown();
89}
90
91bool UserCloudPolicyManagerChromeOS::IsInitializationComplete(
92    PolicyDomain domain) const {
93  if (!CloudPolicyManager::IsInitializationComplete(domain))
94    return false;
95  if (domain == POLICY_DOMAIN_CHROME)
96    return !wait_for_policy_fetch_;
97  if (ComponentCloudPolicyService::SupportsDomain(domain) &&
98      component_policy_service_) {
99    return component_policy_service_->is_initialized();
100  }
101  return true;
102}
103
104void UserCloudPolicyManagerChromeOS::RegisterPolicyDomain(
105    scoped_refptr<const PolicyDomainDescriptor> descriptor) {
106  if (ComponentCloudPolicyService::SupportsDomain(descriptor->domain()) &&
107      component_policy_service_) {
108    component_policy_service_->RegisterPolicyDomain(descriptor);
109  }
110}
111
112scoped_ptr<PolicyBundle> UserCloudPolicyManagerChromeOS::CreatePolicyBundle() {
113  scoped_ptr<PolicyBundle> bundle = CloudPolicyManager::CreatePolicyBundle();
114  if (component_policy_service_)
115    bundle->MergeFrom(component_policy_service_->policy());
116  return bundle.Pass();
117}
118
119void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
120    CloudPolicyService* cloud_policy_service) {
121  DCHECK_EQ(service(), cloud_policy_service);
122  cloud_policy_service->RemoveObserver(this);
123  // If the CloudPolicyClient isn't registered at this stage then it needs an
124  // OAuth token for the initial registration.
125  //
126  // If |wait_for_policy_fetch_| is true then Profile initialization is blocking
127  // on the initial policy fetch, so the token must be fetched immediately.
128  // In that case, the signin Profile is used to authenticate a Gaia request to
129  // fetch a refresh token, and then the policy token is fetched.
130  //
131  // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder
132  // service will eventually call OnAccessTokenAvailable() once an access token
133  // is available. That call may have already happened while waiting for
134  // initialization of the CloudPolicyService, so in that case check if an
135  // access token is already available.
136  if (!client()->is_registered()) {
137    if (wait_for_policy_fetch_) {
138      FetchPolicyOAuthTokenUsingSigninProfile();
139    } else if (!access_token_.empty()) {
140      OnOAuth2PolicyTokenFetched(
141          access_token_, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
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    StartRefreshSchedulerIfReady();
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  StartRefreshSchedulerIfReady();
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.get()) {
200    LOG(ERROR) << "No signin Profile for policy oauth token fetch!";
201    OnOAuth2PolicyTokenFetched(
202        std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE));
203    return;
204  }
205
206  token_fetcher_.reset(new PolicyOAuth2TokenFetcher(
207      signin_context.get(),
208      g_browser_process->system_request_context(),
209      base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
210                 base::Unretained(this))));
211  token_fetcher_->Start();
212}
213
214void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
215    const std::string& policy_token,
216    const GoogleServiceAuthError& error) {
217  DCHECK(!client()->is_registered());
218  if (error.state() == GoogleServiceAuthError::NONE) {
219    // Start client registration. Either OnRegistrationStateChanged() or
220    // OnClientError() will be called back.
221    client()->Register(em::DeviceRegisterRequest::USER,
222                       policy_token, std::string(), false, std::string());
223  } else {
224    // Failed to get a token, stop waiting and use an empty policy.
225    CancelWaitForPolicyFetch();
226  }
227
228  token_fetcher_.reset();
229}
230
231void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
232    bool success) {
233  CancelWaitForPolicyFetch();
234}
235
236void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
237  wait_for_policy_fetch_ = false;
238  CheckAndPublishPolicy();
239  // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
240  // can be started.
241  StartRefreshSchedulerIfReady();
242}
243
244void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() {
245  if (core()->refresh_scheduler())
246    return;  // Already started.
247
248  if (wait_for_policy_fetch_)
249    return;  // Still waiting for the initial, blocking fetch.
250
251  if (!service() || !local_state_)
252    return;  // Not connected.
253
254  if (component_policy_service_ &&
255      !component_policy_service_->is_initialized()) {
256    // If the client doesn't have the list of components to fetch yet then don't
257    // start the scheduler. The |component_policy_service_| will call back into
258    // OnComponentCloudPolicyUpdated() once it's ready.
259    return;
260  }
261
262  StartRefreshScheduler();
263  core()->TrackRefreshDelayPref(local_state_, prefs::kUserPolicyRefreshRate);
264}
265
266}  // namespace policy
267