user_cloud_policy_token_forwarder.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2013 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_token_forwarder.h"
6
7#include "chrome/browser/chrome_notification_types.h"
8#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h"
9#include "chrome/browser/signin/profile_oauth2_token_service.h"
10#include "components/policy/core/common/cloud/cloud_policy_core.h"
11#include "content/public/browser/notification_source.h"
12#include "google_apis/gaia/gaia_constants.h"
13#include "google_apis/gaia/gaia_urls.h"
14
15namespace policy {
16
17UserCloudPolicyTokenForwarder::UserCloudPolicyTokenForwarder(
18    UserCloudPolicyManagerChromeOS* manager,
19    ProfileOAuth2TokenService* token_service)
20    : OAuth2TokenService::Consumer("policy_token_forwarder"),
21      manager_(manager),
22      token_service_(token_service) {
23  // Start by waiting for the CloudPolicyService to be initialized, so that
24  // we can check if it already has a DMToken or not.
25  if (manager_->core()->service()->IsInitializationComplete()) {
26    Initialize();
27  } else {
28    manager_->core()->service()->AddObserver(this);
29  }
30}
31
32UserCloudPolicyTokenForwarder::~UserCloudPolicyTokenForwarder() {}
33
34void UserCloudPolicyTokenForwarder::Shutdown() {
35  request_.reset();
36  token_service_->RemoveObserver(this);
37  manager_->core()->service()->RemoveObserver(this);
38}
39
40void UserCloudPolicyTokenForwarder::OnRefreshTokenAvailable(
41    const std::string& account_id) {
42  RequestAccessToken();
43}
44
45void UserCloudPolicyTokenForwarder::OnGetTokenSuccess(
46    const OAuth2TokenService::Request* request,
47    const std::string& access_token,
48    const base::Time& expiration_time) {
49  manager_->OnAccessTokenAvailable(access_token);
50  // All done here.
51  Shutdown();
52}
53
54void UserCloudPolicyTokenForwarder::OnGetTokenFailure(
55    const OAuth2TokenService::Request* request,
56    const GoogleServiceAuthError& error) {
57  // This should seldom happen: if the user is signing in for the first time
58  // then this was an online signin and network errors are unlikely; if the
59  // user had already signed in before then he should have policy cached, and
60  // RequestAccessToken() wouldn't have been invoked.
61  // Still, something just went wrong (server 500, or something). Currently
62  // we don't recover in this case, and we'll just try to register for policy
63  // again on the next signin.
64  // TODO(joaodasilva, atwilson): consider blocking signin when this happens,
65  // so that the user has to try again before getting into the session. That
66  // would guarantee that a session always has fresh policy, or at least
67  // enforces a cached policy.
68  Shutdown();
69}
70
71void UserCloudPolicyTokenForwarder::OnInitializationCompleted(
72    CloudPolicyService* service) {
73  Initialize();
74}
75
76void UserCloudPolicyTokenForwarder::Initialize() {
77  // TODO(mnissler): Once a better way to reconfirm whether a user is on the
78  // login whitelist is available, there is no reason to fetch the OAuth2 token
79  // here if the client is already registered, so check and bail out here.
80
81  if (token_service_->RefreshTokenIsAvailable(
82          token_service_->GetPrimaryAccountId()))
83    RequestAccessToken();
84  else
85    token_service_->AddObserver(this);
86}
87
88void UserCloudPolicyTokenForwarder::RequestAccessToken() {
89  OAuth2TokenService::ScopeSet scopes;
90  scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
91  scopes.insert(GaiaUrls::GetInstance()->oauth_wrap_bridge_user_info_scope());
92  request_ = token_service_->StartRequest(
93      token_service_->GetPrimaryAccountId(), scopes, this);
94}
95
96}  // namespace policy
97