user_policy_signin_service.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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/policy/cloud/user_policy_signin_service.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/callback.h"
10#include "base/prefs/pref_service.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/policy/cloud/cloud_policy_client_registration_helper.h"
14#include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/profiles/profile_manager.h"
17#include "chrome/browser/signin/profile_oauth2_token_service.h"
18#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
19#include "chrome/browser/signin/signin_manager.h"
20#include "chrome/common/pref_names.h"
21#include "content/public/browser/notification_details.h"
22#include "content/public/browser/notification_source.h"
23#include "google_apis/gaia/gaia_constants.h"
24#include "net/url_request/url_request_context_getter.h"
25
26namespace policy {
27
28UserPolicySigninService::UserPolicySigninService(
29    Profile* profile,
30    PrefService* local_state,
31    scoped_refptr<net::URLRequestContextGetter> request_context,
32    DeviceManagementService* device_management_service,
33    ProfileOAuth2TokenService* token_service)
34    : UserPolicySigninServiceBase(profile,
35                                  local_state,
36                                  request_context,
37                                  device_management_service),
38      oauth2_token_service_(token_service) {
39  if (profile->GetPrefs()->GetBoolean(prefs::kDisableCloudPolicyOnSignin))
40    return;
41
42  // ProfileOAuth2TokenService should not yet have loaded its tokens since this
43  // happens in the background after PKS initialization - so this service
44  // should always be created before the oauth token is available.
45  DCHECK(!oauth2_token_service_->RefreshTokenIsAvailable());
46
47  // Listen for an OAuth token to become available so we can register a client
48  // if for some reason the client is not already registered (for example, if
49  // the policy load failed during initial signin).
50  oauth2_token_service_->AddObserver(this);
51}
52
53UserPolicySigninService::~UserPolicySigninService() {
54}
55
56void UserPolicySigninService::PrepareForUserCloudPolicyManagerShutdown() {
57  // Stop any pending registration helper activity. We do this here instead of
58  // in the destructor because we want to shutdown the registration helper
59  // before UserCloudPolicyManager shuts down the CloudPolicyClient.
60  registration_helper_.reset();
61
62  UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown();
63}
64
65void UserPolicySigninService::Shutdown() {
66  UserPolicySigninServiceBase::Shutdown();
67  oauth2_token_service_->RemoveObserver(this);
68}
69
70void UserPolicySigninService::RegisterPolicyClient(
71    const std::string& username,
72    const std::string& oauth2_refresh_token,
73    const PolicyRegistrationCallback& callback) {
74  DCHECK(!oauth2_refresh_token.empty());
75
76  // Create a new CloudPolicyClient for fetching the DMToken.
77  scoped_ptr<CloudPolicyClient> policy_client = PrepareToRegister(username);
78  if (!policy_client) {
79    callback.Run(policy_client.Pass());
80    return;
81  }
82
83  // Fire off the registration process. Callback keeps the CloudPolicyClient
84  // alive for the length of the registration process.
85  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
86      profile()->GetRequestContext(),
87      policy_client.get(),
88      ShouldForceLoadPolicy(),
89      enterprise_management::DeviceRegisterRequest::BROWSER));
90  registration_helper_->StartRegistrationWithLoginToken(
91      oauth2_refresh_token,
92      base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
93                 base::Unretained(this),
94                 base::Passed(&policy_client),
95                 callback));
96}
97
98void UserPolicySigninService::CallPolicyRegistrationCallback(
99    scoped_ptr<CloudPolicyClient> client,
100    PolicyRegistrationCallback callback) {
101  registration_helper_.reset();
102  if (!client->is_registered()) {
103    // Registration failed, so free the client and pass NULL to the callback.
104    client.reset();
105  }
106  callback.Run(client.Pass());
107}
108
109void UserPolicySigninService::OnRefreshTokenAvailable(
110    const std::string& account_id) {
111  // If using a TestingProfile with no UserCloudPolicyManager, skip
112  // initialization.
113  if (!GetManager()) {
114    DVLOG(1) << "Skipping initialization for tests due to missing components.";
115    return;
116  }
117
118  std::string username = GetSigninManager()->GetAuthenticatedUsername();
119  // Should not have OAuth tokens if the user isn't signed in.
120  DCHECK(!username.empty());
121  // ProfileOAuth2TokenService now has a refresh token so initialize the
122  // UserCloudPolicyManager.
123  InitializeForSignedInUser(username);
124}
125
126void UserPolicySigninService::InitializeUserCloudPolicyManager(
127    scoped_ptr<CloudPolicyClient> client) {
128  UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(client.Pass());
129  ProhibitSignoutIfNeeded();
130}
131
132void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
133  UserCloudPolicyManager* manager = GetManager();
134  // Allow the user to signout again.
135  if (manager)
136    GetSigninManager()->ProhibitSignout(false);
137  UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
138}
139
140void UserPolicySigninService::OnInitializationCompleted(
141    CloudPolicyService* service) {
142  UserCloudPolicyManager* manager = GetManager();
143  DCHECK_EQ(service, manager->core()->service());
144  DCHECK(service->IsInitializationComplete());
145  // The service is now initialized - if the client is not yet registered, then
146  // it means that there is no cached policy and so we need to initiate a new
147  // client registration.
148  DVLOG_IF(1, manager->IsClientRegistered())
149      << "Client already registered - not fetching DMToken";
150  if (!manager->IsClientRegistered()) {
151    if (!oauth2_token_service_->RefreshTokenIsAvailable()) {
152      // No token yet - this class listens for OnRefreshTokenAvailable()
153      // and will re-attempt registration once the token is available.
154      DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
155      return;
156    }
157    RegisterCloudPolicyService();
158  }
159  // If client is registered now, prohibit signout.
160  ProhibitSignoutIfNeeded();
161}
162
163void UserPolicySigninService::RegisterCloudPolicyService() {
164  DCHECK(!GetManager()->IsClientRegistered());
165  DVLOG(1) << "Fetching new DM Token";
166  // Do nothing if already starting the registration process.
167  if (registration_helper_)
168    return;
169
170  // Start the process of registering the CloudPolicyClient. Once it completes,
171  // policy fetch will automatically happen.
172  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
173      profile()->GetRequestContext(),
174      GetManager()->core()->client(),
175      ShouldForceLoadPolicy(),
176      enterprise_management::DeviceRegisterRequest::BROWSER));
177  registration_helper_->StartRegistration(
178      oauth2_token_service_,
179      GetSigninManager()->GetAuthenticatedUsername(),
180      base::Bind(&UserPolicySigninService::OnRegistrationComplete,
181                 base::Unretained(this)));
182}
183
184void UserPolicySigninService::OnRegistrationComplete() {
185  ProhibitSignoutIfNeeded();
186  registration_helper_.reset();
187}
188
189void UserPolicySigninService::ProhibitSignoutIfNeeded() {
190  if (GetManager()->IsClientRegistered()) {
191    DVLOG(1) << "User is registered for policy - prohibiting signout";
192    GetSigninManager()->ProhibitSignout(true);
193  }
194}
195
196}  // namespace policy
197