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