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