1 // Copyright 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.
5 #include "chrome/browser/managed_mode/managed_user_registration_utility.h"
7 #include "base/base64.h"
9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/rand_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/managed_mode/managed_user_constants.h"
15 #include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
16 #include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
17 #include "chrome/browser/managed_mode/managed_user_shared_settings_service_factory.h"
18 #include "chrome/browser/managed_mode/managed_user_shared_settings_update.h"
19 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
20 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager_factory.h"
24 #include "chrome/browser/sync/glue/device_info.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "components/signin/core/browser/profile_oauth2_token_service.h"
28 #include "components/signin/core/browser/signin_manager.h"
29 #include "google_apis/gaia/gaia_urls.h"
30 #include "google_apis/gaia/google_service_auth_error.h"
32 using base::DictionaryValue;
36 ManagedUserRegistrationUtility* g_instance_for_tests = NULL;
38 // Actual implementation of ManagedUserRegistrationUtility.
39 class ManagedUserRegistrationUtilityImpl
40 : public ManagedUserRegistrationUtility,
41 public ManagedUserSyncServiceObserver {
43 ManagedUserRegistrationUtilityImpl(
45 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
46 ManagedUserSyncService* service,
47 ManagedUserSharedSettingsService* shared_settings_service);
49 virtual ~ManagedUserRegistrationUtilityImpl();
51 // Registers a new managed user with the server. |managed_user_id| is a new
52 // unique ID for the new managed user. If its value is the same as that of
53 // of one of the existing managed users, then the same user will be created
54 // on this machine (and if he has no avatar in sync, his avatar will
55 // be updated). |info| contains necessary information like
56 // the display name of the user and his avatar. |callback| is called
57 // with the result of the registration. We use the info here and not the
58 // profile, because on Chrome OS the profile of the managed user does not
60 virtual void Register(const std::string& managed_user_id,
61 const ManagedUserRegistrationInfo& info,
62 const RegistrationCallback& callback) OVERRIDE;
64 // ManagedUserSyncServiceObserver:
65 virtual void OnManagedUserAcknowledged(const std::string& managed_user_id)
67 virtual void OnManagedUsersSyncingStopped() OVERRIDE;
68 virtual void OnManagedUsersChanged() OVERRIDE;
71 // Fetches the managed user token when we have the device name.
72 void FetchToken(const std::string& client_name);
74 // Called when we have received a token for the managed user.
75 void OnReceivedToken(const GoogleServiceAuthError& error,
76 const std::string& token);
78 // Dispatches the callback and cleans up if all the conditions have been met.
79 void CompleteRegistrationIfReady();
81 // Aborts any registration currently in progress. If |run_callback| is true,
82 // calls the callback specified in Register() with the given |error|.
83 void AbortPendingRegistration(bool run_callback,
84 const GoogleServiceAuthError& error);
86 // If |run_callback| is true, dispatches the callback with the saved token
87 // (which may be empty) and the given |error|. In any case, resets internal
88 // variables to be ready for the next registration.
89 void CompleteRegistration(bool run_callback,
90 const GoogleServiceAuthError& error);
92 // Cancels any registration currently in progress, without calling the
93 // callback or reporting an error.
94 void CancelPendingRegistration();
96 // ManagedUserSharedSettingsUpdate acknowledgment callback for password data
97 // in shared settings.
98 void OnPasswordChangeAcknowledged(bool success);
101 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
103 // A |KeyedService| owned by the custodian profile.
104 ManagedUserSyncService* managed_user_sync_service_;
106 // A |KeyedService| owned by the custodian profile.
107 ManagedUserSharedSettingsService* managed_user_shared_settings_service_;
109 std::string pending_managed_user_id_;
110 std::string pending_managed_user_token_;
111 bool pending_managed_user_acknowledged_;
112 bool is_existing_managed_user_;
113 bool avatar_updated_;
114 RegistrationCallback callback_;
115 scoped_ptr<ManagedUserSharedSettingsUpdate> password_update_;
117 base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_;
119 DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl);
124 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(
125 const base::string16& name,
127 : avatar_index(avatar_index),
131 ManagedUserRegistrationInfo::~ManagedUserRegistrationInfo() {}
133 ScopedTestingManagedUserRegistrationUtility::
134 ScopedTestingManagedUserRegistrationUtility(
135 ManagedUserRegistrationUtility* instance) {
136 ManagedUserRegistrationUtility::SetUtilityForTests(instance);
139 ScopedTestingManagedUserRegistrationUtility::
140 ~ScopedTestingManagedUserRegistrationUtility() {
141 ManagedUserRegistrationUtility::SetUtilityForTests(NULL);
145 scoped_ptr<ManagedUserRegistrationUtility>
146 ManagedUserRegistrationUtility::Create(Profile* profile) {
147 if (g_instance_for_tests) {
148 ManagedUserRegistrationUtility* result = g_instance_for_tests;
149 g_instance_for_tests = NULL;
150 return make_scoped_ptr(result);
153 ProfileOAuth2TokenService* token_service =
154 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
155 SigninManagerBase* signin_manager =
156 SigninManagerFactory::GetForProfile(profile);
157 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher =
158 ManagedUserRefreshTokenFetcher::Create(
160 signin_manager->GetAuthenticatedAccountId(),
161 profile->GetRequestContext());
162 ManagedUserSyncService* managed_user_sync_service =
163 ManagedUserSyncServiceFactory::GetForProfile(profile);
164 ManagedUserSharedSettingsService* managed_user_shared_settings_service =
165 ManagedUserSharedSettingsServiceFactory::GetForBrowserContext(profile);
166 return make_scoped_ptr(ManagedUserRegistrationUtility::CreateImpl(
168 token_fetcher.Pass(),
169 managed_user_sync_service,
170 managed_user_shared_settings_service));
174 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() {
175 std::string new_managed_user_id;
176 base::Base64Encode(base::RandBytesAsString(8), &new_managed_user_id);
177 return new_managed_user_id;
181 void ManagedUserRegistrationUtility::SetUtilityForTests(
182 ManagedUserRegistrationUtility* utility) {
183 if (g_instance_for_tests)
184 delete g_instance_for_tests;
185 g_instance_for_tests = utility;
189 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl(
191 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
192 ManagedUserSyncService* service,
193 ManagedUserSharedSettingsService* shared_settings_service) {
194 return new ManagedUserRegistrationUtilityImpl(prefs,
195 token_fetcher.Pass(),
197 shared_settings_service);
202 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl(
204 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
205 ManagedUserSyncService* service,
206 ManagedUserSharedSettingsService* shared_settings_service)
208 token_fetcher_(token_fetcher.Pass()),
209 managed_user_sync_service_(service),
210 managed_user_shared_settings_service_(shared_settings_service),
211 pending_managed_user_acknowledged_(false),
212 is_existing_managed_user_(false),
213 avatar_updated_(false),
214 weak_ptr_factory_(this) {
215 managed_user_sync_service_->AddObserver(this);
218 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() {
219 managed_user_sync_service_->RemoveObserver(this);
220 CancelPendingRegistration();
223 void ManagedUserRegistrationUtilityImpl::Register(
224 const std::string& managed_user_id,
225 const ManagedUserRegistrationInfo& info,
226 const RegistrationCallback& callback) {
227 DCHECK(pending_managed_user_id_.empty());
228 callback_ = callback;
229 pending_managed_user_id_ = managed_user_id;
231 bool need_password_update = !info.password_data.empty();
232 const base::DictionaryValue* dict =
233 prefs_->GetDictionary(prefs::kManagedUsers);
234 is_existing_managed_user_ = dict->HasKey(managed_user_id);
235 if (!is_existing_managed_user_) {
236 managed_user_sync_service_->AddManagedUser(pending_managed_user_id_,
237 base::UTF16ToUTF8(info.name),
239 info.password_signature_key,
240 info.password_encryption_key,
243 const base::DictionaryValue* value = NULL;
245 dict->GetDictionaryWithoutPathExpansion(managed_user_id, &value);
248 bool need_keys = !info.password_signature_key.empty() ||
249 !info.password_encryption_key.empty();
251 value->GetString(ManagedUserSyncService::kPasswordSignatureKey, &key) &&
253 value->GetString(ManagedUserSyncService::kPasswordEncryptionKey,
257 bool keys_need_update = need_keys && !have_keys;
259 if (keys_need_update) {
260 managed_user_sync_service_->UpdateManagedUser(
261 pending_managed_user_id_,
262 base::UTF16ToUTF8(info.name),
264 info.password_signature_key,
265 info.password_encryption_key,
268 // The user already exists and does not need to be updated.
269 need_password_update = false;
270 OnManagedUserAcknowledged(managed_user_id);
273 managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded(
277 #if defined(OS_CHROMEOS)
278 const char* kAvatarKey = managed_users::kChromeOSAvatarIndex;
280 const char* kAvatarKey = managed_users::kChromeAvatarIndex;
282 managed_user_shared_settings_service_->SetValue(
283 pending_managed_user_id_, kAvatarKey,
284 base::FundamentalValue(info.avatar_index));
285 if (need_password_update) {
286 password_update_.reset(new ManagedUserSharedSettingsUpdate(
287 managed_user_shared_settings_service_,
288 pending_managed_user_id_,
289 managed_users::kChromeOSPasswordData,
290 scoped_ptr<base::Value>(info.password_data.DeepCopy()),
292 &ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged,
293 weak_ptr_factory_.GetWeakPtr())));
296 browser_sync::DeviceInfo::GetClientName(
297 base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken,
298 weak_ptr_factory_.GetWeakPtr()));
301 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
302 AbortPendingRegistration(
303 false, // Don't run the callback. The error will be ignored.
304 GoogleServiceAuthError(GoogleServiceAuthError::NONE));
307 void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged(
308 const std::string& managed_user_id) {
309 DCHECK_EQ(pending_managed_user_id_, managed_user_id);
310 DCHECK(!pending_managed_user_acknowledged_);
311 pending_managed_user_acknowledged_ = true;
312 CompleteRegistrationIfReady();
315 void ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged(
317 DCHECK(password_update_);
319 password_update_.reset();
320 CompleteRegistrationIfReady();
323 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
324 AbortPendingRegistration(
325 true, // Run the callback.
326 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
329 void ManagedUserRegistrationUtilityImpl::OnManagedUsersChanged() {}
331 void ManagedUserRegistrationUtilityImpl::FetchToken(
332 const std::string& client_name) {
333 token_fetcher_->Start(
334 pending_managed_user_id_, client_name,
335 base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken,
336 weak_ptr_factory_.GetWeakPtr()));
339 void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
340 const GoogleServiceAuthError& error,
341 const std::string& token) {
342 if (error.state() != GoogleServiceAuthError::NONE) {
343 CompleteRegistration(true, error);
347 DCHECK(!token.empty());
348 pending_managed_user_token_ = token;
349 CompleteRegistrationIfReady();
352 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
353 bool skip_check = CommandLine::ForCurrentProcess()->HasSwitch(
354 switches::kNoManagedUserAcknowledgmentCheck);
356 if (!pending_managed_user_acknowledged_ && !skip_check)
358 if (password_update_ && !skip_check)
360 if (pending_managed_user_token_.empty())
363 GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
364 CompleteRegistration(true, error);
367 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
369 const GoogleServiceAuthError& error) {
370 pending_managed_user_token_.clear();
371 CompleteRegistration(run_callback, error);
374 void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
376 const GoogleServiceAuthError& error) {
377 if (callback_.is_null())
380 if (pending_managed_user_token_.empty()) {
381 DCHECK(!pending_managed_user_id_.empty());
383 if (!is_existing_managed_user_) {
384 // Remove the pending managed user if we weren't successful.
385 // However, check that we are not importing a managed user
386 // before deleting it from sync to avoid accidental deletion of
387 // existing managed users by just canceling the registration for example.
388 managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_);
389 } else if (avatar_updated_) {
390 // Canceling (or failing) a managed user import that did set the avatar
391 // should undo this change.
392 managed_user_sync_service_->ClearManagedUserAvatar(
393 pending_managed_user_id_);
398 callback_.Run(error, pending_managed_user_token_);