user_policy_signin_service.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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              oauth2_token_service_->GetPrimaryAccountId()));
47
48  // Listen for an OAuth token to become available so we can register a client
49  // if for some reason the client is not already registered (for example, if
50  // the policy load failed during initial signin).
51  oauth2_token_service_->AddObserver(this);
52}
53
54UserPolicySigninService::~UserPolicySigninService() {
55}
56
57void UserPolicySigninService::PrepareForUserCloudPolicyManagerShutdown() {
58  // Stop any pending registration helper activity. We do this here instead of
59  // in the destructor because we want to shutdown the registration helper
60  // before UserCloudPolicyManager shuts down the CloudPolicyClient.
61  registration_helper_.reset();
62
63  UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown();
64}
65
66void UserPolicySigninService::Shutdown() {
67  UserPolicySigninServiceBase::Shutdown();
68  oauth2_token_service_->RemoveObserver(this);
69}
70
71void UserPolicySigninService::RegisterPolicyClient(
72    const std::string& username,
73    const std::string& oauth2_refresh_token,
74    const PolicyRegistrationCallback& callback) {
75  DCHECK(!oauth2_refresh_token.empty());
76
77  // Create a new CloudPolicyClient for fetching the DMToken.
78  scoped_ptr<CloudPolicyClient> policy_client = PrepareToRegister(username);
79  if (!policy_client) {
80    callback.Run(policy_client.Pass());
81    return;
82  }
83
84  // Fire off the registration process. Callback keeps the CloudPolicyClient
85  // alive for the length of the registration process.
86  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
87      profile()->GetRequestContext(),
88      policy_client.get(),
89      ShouldForceLoadPolicy(),
90      enterprise_management::DeviceRegisterRequest::BROWSER));
91  registration_helper_->StartRegistrationWithLoginToken(
92      oauth2_refresh_token,
93      base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
94                 base::Unretained(this),
95                 base::Passed(&policy_client),
96                 callback));
97}
98
99void UserPolicySigninService::CallPolicyRegistrationCallback(
100    scoped_ptr<CloudPolicyClient> client,
101    PolicyRegistrationCallback callback) {
102  registration_helper_.reset();
103  if (!client->is_registered()) {
104    // Registration failed, so free the client and pass NULL to the callback.
105    client.reset();
106  }
107  callback.Run(client.Pass());
108}
109
110void UserPolicySigninService::OnRefreshTokenAvailable(
111    const std::string& account_id) {
112  // If using a TestingProfile with no UserCloudPolicyManager, skip
113  // initialization.
114  if (!GetManager()) {
115    DVLOG(1) << "Skipping initialization for tests due to missing components.";
116    return;
117  }
118
119  std::string username = GetSigninManager()->GetAuthenticatedUsername();
120  // Should not have OAuth tokens if the user isn't signed in.
121  DCHECK(!username.empty());
122  // ProfileOAuth2TokenService now has a refresh token so initialize the
123  // UserCloudPolicyManager.
124  InitializeForSignedInUser(username);
125}
126
127void UserPolicySigninService::InitializeUserCloudPolicyManager(
128    scoped_ptr<CloudPolicyClient> client) {
129  UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(client.Pass());
130  ProhibitSignoutIfNeeded();
131}
132
133void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
134  UserCloudPolicyManager* manager = GetManager();
135  // Allow the user to signout again.
136  if (manager)
137    GetSigninManager()->ProhibitSignout(false);
138  UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
139}
140
141void UserPolicySigninService::OnInitializationCompleted(
142    CloudPolicyService* service) {
143  UserCloudPolicyManager* manager = GetManager();
144  DCHECK_EQ(service, manager->core()->service());
145  DCHECK(service->IsInitializationComplete());
146  // The service is now initialized - if the client is not yet registered, then
147  // it means that there is no cached policy and so we need to initiate a new
148  // client registration.
149  DVLOG_IF(1, manager->IsClientRegistered())
150      << "Client already registered - not fetching DMToken";
151  if (!manager->IsClientRegistered()) {
152    if (!oauth2_token_service_->RefreshTokenIsAvailable(
153             oauth2_token_service_->GetPrimaryAccountId())) {
154      // No token yet - this class listens for OnRefreshTokenAvailable()
155      // and will re-attempt registration once the token is available.
156      DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download";
157      return;
158    }
159    RegisterCloudPolicyService();
160  }
161  // If client is registered now, prohibit signout.
162  ProhibitSignoutIfNeeded();
163}
164
165void UserPolicySigninService::RegisterCloudPolicyService() {
166  DCHECK(!GetManager()->IsClientRegistered());
167  DVLOG(1) << "Fetching new DM Token";
168  // Do nothing if already starting the registration process.
169  if (registration_helper_)
170    return;
171
172  // Start the process of registering the CloudPolicyClient. Once it completes,
173  // policy fetch will automatically happen.
174  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
175      profile()->GetRequestContext(),
176      GetManager()->core()->client(),
177      ShouldForceLoadPolicy(),
178      enterprise_management::DeviceRegisterRequest::BROWSER));
179  registration_helper_->StartRegistration(
180      oauth2_token_service_,
181      oauth2_token_service_->GetPrimaryAccountId(),
182      base::Bind(&UserPolicySigninService::OnRegistrationComplete,
183                 base::Unretained(this)));
184}
185
186void UserPolicySigninService::OnRegistrationComplete() {
187  ProhibitSignoutIfNeeded();
188  registration_helper_.reset();
189}
190
191void UserPolicySigninService::ProhibitSignoutIfNeeded() {
192  if (GetManager()->IsClientRegistered()) {
193    DVLOG(1) << "User is registered for policy - prohibiting signout";
194    GetSigninManager()->ProhibitSignout(true);
195  }
196}
197
198}  // namespace policy
199