Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / user_cloud_policy_manager_chromeos.cc
blob466fd019e5ce527328a5f41c4d537234756900cc
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.
5 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
7 #include <set>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/logging.h"
12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/values.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chromeos/login/helper.h"
18 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
19 #include "chrome/browser/chromeos/login/users/affiliation.h"
20 #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
21 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
22 #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h"
23 #include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
24 #include "chrome/browser/lifetime/application_lifetime.h"
25 #include "chrome/common/chrome_content_client.h"
26 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
27 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
28 #include "components/policy/core/common/cloud/device_management_service.h"
29 #include "components/policy/core/common/cloud/system_policy_request_context.h"
30 #include "components/policy/core/common/policy_map.h"
31 #include "components/policy/core/common/policy_pref_names.h"
32 #include "components/policy/core/common/policy_types.h"
33 #include "components/user_manager/user_manager.h"
34 #include "net/url_request/url_request_context_getter.h"
35 #include "policy/policy_constants.h"
36 #include "url/gurl.h"
38 namespace em = enterprise_management;
40 namespace policy {
42 namespace {
44 // UMA histogram names.
45 const char kUMADelayInitialization[] =
46 "Enterprise.UserPolicyChromeOS.DelayInitialization";
47 const char kUMAInitialFetchClientError[] =
48 "Enterprise.UserPolicyChromeOS.InitialFetch.ClientError";
49 const char kUMAInitialFetchDelayClientRegister[] =
50 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayClientRegister";
51 const char kUMAInitialFetchDelayOAuth2Token[] =
52 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayOAuth2Token";
53 const char kUMAInitialFetchDelayPolicyFetch[] =
54 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayPolicyFetch";
55 const char kUMAInitialFetchDelayTotal[] =
56 "Enterprise.UserPolicyChromeOS.InitialFetch.DelayTotal";
57 const char kUMAInitialFetchOAuth2Error[] =
58 "Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2Error";
59 const char kUMAInitialFetchOAuth2NetworkError[] =
60 "Enterprise.UserPolicyChromeOS.InitialFetch.OAuth2NetworkError";
62 void OnWildcardCheckCompleted(const std::string& username,
63 WildcardLoginChecker::Result result) {
64 if (result == WildcardLoginChecker::RESULT_BLOCKED) {
65 LOG(ERROR) << "Online wildcard login check failed, terminating session.";
67 // TODO(mnissler): This only removes the user pod from the login screen, but
68 // the cryptohome remains. This is because deleting the cryptohome for a
69 // logged-in session is not possible. Fix this either by delaying the
70 // cryptohome deletion operation or by getting rid of the in-session
71 // wildcard check.
72 user_manager::UserManager::Get()->RemoveUserFromList(username);
73 chrome::AttemptUserExit();
77 } // namespace
79 UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
80 scoped_ptr<CloudPolicyStore> store,
81 scoped_ptr<CloudExternalDataManager> external_data_manager,
82 const base::FilePath& component_policy_cache_path,
83 bool wait_for_policy_fetch,
84 base::TimeDelta initial_policy_fetch_timeout,
85 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
86 const scoped_refptr<base::SequencedTaskRunner>& file_task_runner,
87 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner)
88 : CloudPolicyManager(dm_protocol::kChromeUserPolicyType,
89 std::string(),
90 store.get(),
91 task_runner,
92 file_task_runner,
93 io_task_runner),
94 store_(store.Pass()),
95 external_data_manager_(external_data_manager.Pass()),
96 component_policy_cache_path_(component_policy_cache_path),
97 wait_for_policy_fetch_(wait_for_policy_fetch),
98 policy_fetch_timeout_(false, false) {
99 time_init_started_ = base::Time::Now();
100 if (wait_for_policy_fetch_ && !initial_policy_fetch_timeout.is_max()) {
101 policy_fetch_timeout_.Start(
102 FROM_HERE,
103 initial_policy_fetch_timeout,
104 base::Bind(&UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout,
105 base::Unretained(this)));
109 UserCloudPolicyManagerChromeOS::~UserCloudPolicyManagerChromeOS() {}
111 void UserCloudPolicyManagerChromeOS::Connect(
112 PrefService* local_state,
113 DeviceManagementService* device_management_service,
114 scoped_refptr<net::URLRequestContextGetter> system_request_context) {
115 DCHECK(device_management_service);
116 DCHECK(local_state);
117 local_state_ = local_state;
118 scoped_refptr<net::URLRequestContextGetter> request_context;
119 if (system_request_context.get()) {
120 // |system_request_context| can be null for tests.
121 // Use the system request context here instead of a context derived
122 // from the Profile because Connect() is called before the profile is
123 // fully initialized (required so we can perform the initial policy load).
124 // TODO(atwilson): Change this to use a UserPolicyRequestContext once
125 // Connect() is called after profile initialization. http://crbug.com/323591
126 request_context = new SystemPolicyRequestContext(
127 system_request_context, GetUserAgent());
129 scoped_ptr<CloudPolicyClient> cloud_policy_client(new CloudPolicyClient(
130 std::string(), std::string(), kPolicyVerificationKeyHash,
131 device_management_service, request_context));
132 CreateComponentCloudPolicyService(component_policy_cache_path_,
133 request_context, cloud_policy_client.get());
134 core()->Connect(cloud_policy_client.Pass());
135 client()->AddObserver(this);
137 external_data_manager_->Connect(request_context);
139 // Determine the next step after the CloudPolicyService initializes.
140 if (service()->IsInitializationComplete()) {
141 OnInitializationCompleted(service());
142 } else {
143 service()->AddObserver(this);
147 void UserCloudPolicyManagerChromeOS::OnAccessTokenAvailable(
148 const std::string& access_token) {
149 access_token_ = access_token;
151 if (!wildcard_username_.empty()) {
152 wildcard_login_checker_.reset(new WildcardLoginChecker());
153 wildcard_login_checker_->StartWithAccessToken(
154 access_token,
155 base::Bind(&OnWildcardCheckCompleted, wildcard_username_));
158 if (service() && service()->IsInitializationComplete() &&
159 client() && !client()->is_registered()) {
160 OnOAuth2PolicyTokenFetched(
161 access_token, GoogleServiceAuthError(GoogleServiceAuthError::NONE));
165 bool UserCloudPolicyManagerChromeOS::IsClientRegistered() const {
166 return client() && client()->is_registered();
169 void UserCloudPolicyManagerChromeOS::EnableWildcardLoginCheck(
170 const std::string& username) {
171 DCHECK(access_token_.empty());
172 wildcard_username_ = username;
175 void UserCloudPolicyManagerChromeOS::Shutdown() {
176 if (client())
177 client()->RemoveObserver(this);
178 if (service())
179 service()->RemoveObserver(this);
180 token_fetcher_.reset();
181 external_data_manager_->Disconnect();
182 CloudPolicyManager::Shutdown();
185 bool UserCloudPolicyManagerChromeOS::IsInitializationComplete(
186 PolicyDomain domain) const {
187 if (!CloudPolicyManager::IsInitializationComplete(domain))
188 return false;
189 if (domain == POLICY_DOMAIN_CHROME)
190 return !wait_for_policy_fetch_;
191 return true;
194 void UserCloudPolicyManagerChromeOS::OnInitializationCompleted(
195 CloudPolicyService* cloud_policy_service) {
196 DCHECK_EQ(service(), cloud_policy_service);
197 cloud_policy_service->RemoveObserver(this);
199 time_init_completed_ = base::Time::Now();
200 UMA_HISTOGRAM_MEDIUM_TIMES(kUMADelayInitialization,
201 time_init_completed_ - time_init_started_);
203 // If the CloudPolicyClient isn't registered at this stage then it needs an
204 // OAuth token for the initial registration.
206 // If |wait_for_policy_fetch_| is true then Profile initialization is blocking
207 // on the initial policy fetch, so the token must be fetched immediately.
208 // In that case, the signin Profile is used to authenticate a Gaia request to
209 // fetch a refresh token, and then the policy token is fetched.
211 // If |wait_for_policy_fetch_| is false then the UserCloudPolicyTokenForwarder
212 // service will eventually call OnAccessTokenAvailable() once an access token
213 // is available. That call may have already happened while waiting for
214 // initialization of the CloudPolicyService, so in that case check if an
215 // access token is already available.
216 if (!client()->is_registered()) {
217 if (wait_for_policy_fetch_) {
218 FetchPolicyOAuthToken();
219 } else if (!access_token_.empty()) {
220 OnAccessTokenAvailable(access_token_);
224 if (!wait_for_policy_fetch_) {
225 // If this isn't blocking on a policy fetch then
226 // CloudPolicyManager::OnStoreLoaded() already published the cached policy.
227 // Start the refresh scheduler now, which will eventually refresh the
228 // cached policy or make the first fetch once the OAuth2 token is
229 // available.
230 StartRefreshSchedulerIfReady();
234 void UserCloudPolicyManagerChromeOS::OnPolicyFetched(
235 CloudPolicyClient* client) {
236 // No action required. If we're blocked on a policy fetch, we'll learn about
237 // completion of it through OnInitialPolicyFetchComplete().
240 void UserCloudPolicyManagerChromeOS::OnRegistrationStateChanged(
241 CloudPolicyClient* cloud_policy_client) {
242 DCHECK_EQ(client(), cloud_policy_client);
244 if (wait_for_policy_fetch_) {
245 time_client_registered_ = base::Time::Now();
246 if (!time_token_available_.is_null()) {
247 UMA_HISTOGRAM_MEDIUM_TIMES(
248 kUMAInitialFetchDelayClientRegister,
249 time_client_registered_ - time_token_available_);
252 // If we're blocked on the policy fetch, now is a good time to issue it.
253 if (client()->is_registered()) {
254 service()->RefreshPolicy(
255 base::Bind(
256 &UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete,
257 base::Unretained(this)));
258 } else {
259 // If the client has switched to not registered, we bail out as this
260 // indicates the cloud policy setup flow has been aborted.
261 CancelWaitForPolicyFetch();
266 void UserCloudPolicyManagerChromeOS::OnClientError(
267 CloudPolicyClient* cloud_policy_client) {
268 DCHECK_EQ(client(), cloud_policy_client);
269 if (wait_for_policy_fetch_) {
270 UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchClientError,
271 cloud_policy_client->status());
273 CancelWaitForPolicyFetch();
276 void UserCloudPolicyManagerChromeOS::OnComponentCloudPolicyUpdated() {
277 CloudPolicyManager::OnComponentCloudPolicyUpdated();
278 StartRefreshSchedulerIfReady();
281 void UserCloudPolicyManagerChromeOS::OnStoreLoaded(
282 CloudPolicyStore* cloud_policy_store) {
283 CloudPolicyManager::OnStoreLoaded(cloud_policy_store);
285 em::PolicyData const* const policy_data = cloud_policy_store->policy();
287 if (policy_data) {
288 chromeos::AffiliationIDSet set_of_user_affiliation_ids(
289 policy_data->user_affiliation_ids().begin(),
290 policy_data->user_affiliation_ids().end());
292 chromeos::ChromeUserManager::Get()->SetUserAffiliation(
293 policy_data->username(), set_of_user_affiliation_ids);
297 void UserCloudPolicyManagerChromeOS::GetChromePolicy(PolicyMap* policy_map) {
298 CloudPolicyManager::GetChromePolicy(policy_map);
300 // If the store has a verified policy blob received from the server then apply
301 // the defaults for policies that haven't been configured by the administrator
302 // given that this is an enterprise user.
303 if (!store()->has_policy())
304 return;
305 SetEnterpriseUsersDefaults(policy_map);
308 void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthToken() {
309 const std::string& refresh_token = chromeos::UserSessionManager::GetInstance()
310 ->user_context()
311 .GetRefreshToken();
312 if (!refresh_token.empty()) {
313 token_fetcher_.reset(new PolicyOAuth2TokenFetcher());
314 token_fetcher_->StartWithRefreshToken(
315 refresh_token, g_browser_process->system_request_context(),
316 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
317 base::Unretained(this)));
318 return;
321 scoped_refptr<net::URLRequestContextGetter> signin_context =
322 chromeos::login::GetSigninContext();
323 if (!signin_context.get()) {
324 LOG(ERROR) << "No signin context for policy oauth token fetch!";
325 OnOAuth2PolicyTokenFetched(
326 std::string(), GoogleServiceAuthError(GoogleServiceAuthError::NONE));
327 return;
330 token_fetcher_.reset(new PolicyOAuth2TokenFetcher());
331 token_fetcher_->StartWithSigninContext(
332 signin_context.get(), g_browser_process->system_request_context(),
333 base::Bind(&UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched,
334 base::Unretained(this)));
337 void UserCloudPolicyManagerChromeOS::OnOAuth2PolicyTokenFetched(
338 const std::string& policy_token,
339 const GoogleServiceAuthError& error) {
340 DCHECK(!client()->is_registered());
341 time_token_available_ = base::Time::Now();
342 if (wait_for_policy_fetch_) {
343 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayOAuth2Token,
344 time_token_available_ - time_init_completed_);
347 if (error.state() == GoogleServiceAuthError::NONE) {
348 // Start client registration. Either OnRegistrationStateChanged() or
349 // OnClientError() will be called back.
350 client()->Register(em::DeviceRegisterRequest::USER,
351 em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
352 policy_token, std::string(), std::string(),
353 std::string());
354 } else {
355 // Failed to get a token, stop waiting and use an empty policy.
356 CancelWaitForPolicyFetch();
358 UMA_HISTOGRAM_ENUMERATION(kUMAInitialFetchOAuth2Error,
359 error.state(),
360 GoogleServiceAuthError::NUM_STATES);
361 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) {
362 // Network errors are negative in the code, but the histogram data type
363 // expects the corresponding positive value.
364 UMA_HISTOGRAM_SPARSE_SLOWLY(kUMAInitialFetchOAuth2NetworkError,
365 -error.network_error());
369 token_fetcher_.reset();
372 void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
373 bool success) {
374 const base::Time now = base::Time::Now();
375 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayPolicyFetch,
376 now - time_client_registered_);
377 UMA_HISTOGRAM_MEDIUM_TIMES(kUMAInitialFetchDelayTotal,
378 now - time_init_started_);
379 CancelWaitForPolicyFetch();
382 void UserCloudPolicyManagerChromeOS::OnBlockingFetchTimeout() {
383 if (!wait_for_policy_fetch_)
384 return;
385 LOG(WARNING) << "Timed out while waiting for the initial policy fetch. "
386 << "The first session will start without policy.";
387 CancelWaitForPolicyFetch();
390 void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
391 if (!wait_for_policy_fetch_)
392 return;
394 wait_for_policy_fetch_ = false;
395 policy_fetch_timeout_.Stop();
396 CheckAndPublishPolicy();
397 // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
398 // can be started.
399 StartRefreshSchedulerIfReady();
402 void UserCloudPolicyManagerChromeOS::StartRefreshSchedulerIfReady() {
403 if (core()->refresh_scheduler())
404 return; // Already started.
406 if (wait_for_policy_fetch_)
407 return; // Still waiting for the initial, blocking fetch.
409 if (!service() || !local_state_)
410 return; // Not connected.
412 if (component_policy_service() &&
413 !component_policy_service()->is_initialized()) {
414 // If the client doesn't have the list of components to fetch yet then don't
415 // start the scheduler. The |component_policy_service_| will call back into
416 // OnComponentCloudPolicyUpdated() once it's ready.
417 return;
420 core()->StartRefreshScheduler();
421 core()->TrackRefreshDelayPref(local_state_,
422 policy_prefs::kUserPolicyRefreshRate);
425 } // namespace policy