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 const base::DictionaryValue
* dict
=
232 prefs_
->GetDictionary(prefs::kManagedUsers
);
233 is_existing_managed_user_
= dict
->HasKey(managed_user_id
);
234 if (!is_existing_managed_user_
) {
235 managed_user_sync_service_
->AddManagedUser(pending_managed_user_id_
,
236 base::UTF16ToUTF8(info
.name
),
238 info
.password_signature_key
,
239 info
.password_encryption_key
,
242 const base::DictionaryValue
* value
= NULL
;
244 dict
->GetDictionaryWithoutPathExpansion(managed_user_id
, &value
);
247 bool need_keys
= !info
.password_signature_key
.empty() ||
248 !info
.password_encryption_key
.empty();
250 value
->GetString(ManagedUserSyncService::kPasswordSignatureKey
, &key
) &&
252 value
->GetString(ManagedUserSyncService::kPasswordEncryptionKey
,
256 bool keys_need_update
= need_keys
&& !have_keys
;
258 if (keys_need_update
) {
259 managed_user_sync_service_
->UpdateManagedUser(
260 pending_managed_user_id_
,
261 base::UTF16ToUTF8(info
.name
),
263 info
.password_signature_key
,
264 info
.password_encryption_key
,
267 // The user already exists and does not need to be updated.
268 OnManagedUserAcknowledged(managed_user_id
);
271 managed_user_sync_service_
->UpdateManagedUserAvatarIfNeeded(
275 #if defined(OS_CHROMEOS)
276 const char* kAvatarKey
= managed_users::kChromeOSAvatarIndex
;
278 const char* kAvatarKey
= managed_users::kChromeAvatarIndex
;
280 managed_user_shared_settings_service_
->SetValue(
281 pending_managed_user_id_
, kAvatarKey
,
282 base::FundamentalValue(info
.avatar_index
));
283 if (!info
.password_data
.empty()) {
284 password_update_
.reset(new ManagedUserSharedSettingsUpdate(
285 managed_user_shared_settings_service_
,
286 pending_managed_user_id_
,
287 managed_users::kChromeOSPasswordData
,
288 scoped_ptr
<base::Value
>(info
.password_data
.DeepCopy()),
290 &ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged
,
291 weak_ptr_factory_
.GetWeakPtr())));
294 browser_sync::DeviceInfo::GetClientName(
295 base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken
,
296 weak_ptr_factory_
.GetWeakPtr()));
299 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
300 AbortPendingRegistration(
301 false, // Don't run the callback. The error will be ignored.
302 GoogleServiceAuthError(GoogleServiceAuthError::NONE
));
305 void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged(
306 const std::string
& managed_user_id
) {
307 DCHECK_EQ(pending_managed_user_id_
, managed_user_id
);
308 DCHECK(!pending_managed_user_acknowledged_
);
309 pending_managed_user_acknowledged_
= true;
310 CompleteRegistrationIfReady();
313 void ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged(
315 DCHECK(password_update_
);
317 password_update_
.reset();
318 CompleteRegistrationIfReady();
321 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
322 AbortPendingRegistration(
323 true, // Run the callback.
324 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED
));
327 void ManagedUserRegistrationUtilityImpl::OnManagedUsersChanged() {}
329 void ManagedUserRegistrationUtilityImpl::FetchToken(
330 const std::string
& client_name
) {
331 token_fetcher_
->Start(
332 pending_managed_user_id_
, client_name
,
333 base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken
,
334 weak_ptr_factory_
.GetWeakPtr()));
337 void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
338 const GoogleServiceAuthError
& error
,
339 const std::string
& token
) {
340 if (error
.state() != GoogleServiceAuthError::NONE
) {
341 CompleteRegistration(true, error
);
345 DCHECK(!token
.empty());
346 pending_managed_user_token_
= token
;
347 CompleteRegistrationIfReady();
350 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
351 bool skip_check
= CommandLine::ForCurrentProcess()->HasSwitch(
352 switches::kNoManagedUserAcknowledgmentCheck
);
354 if (!pending_managed_user_acknowledged_
&& !skip_check
)
356 if (password_update_
&& !skip_check
)
358 if (pending_managed_user_token_
.empty())
361 GoogleServiceAuthError
error(GoogleServiceAuthError::NONE
);
362 CompleteRegistration(true, error
);
365 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
367 const GoogleServiceAuthError
& error
) {
368 pending_managed_user_token_
.clear();
369 CompleteRegistration(run_callback
, error
);
372 void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
374 const GoogleServiceAuthError
& error
) {
375 if (callback_
.is_null())
378 if (pending_managed_user_token_
.empty()) {
379 DCHECK(!pending_managed_user_id_
.empty());
381 if (!is_existing_managed_user_
) {
382 // Remove the pending managed user if we weren't successful.
383 // However, check that we are not importing a managed user
384 // before deleting it from sync to avoid accidental deletion of
385 // existing managed users by just canceling the registration for example.
386 managed_user_sync_service_
->DeleteManagedUser(pending_managed_user_id_
);
387 } else if (avatar_updated_
) {
388 // Canceling (or failing) a managed user import that did set the avatar
389 // should undo this change.
390 managed_user_sync_service_
->ClearManagedUserAvatar(
391 pending_managed_user_id_
);
396 callback_
.Run(error
, pending_managed_user_token_
);