| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "chrome/browser/managed_mode/managed_user_registration_utility.h" | |
| 6 | |
| 7 #include "base/base64.h" | |
| 8 #include "base/bind.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_facto
ry.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" | |
| 31 | |
| 32 using base::DictionaryValue; | |
| 33 | |
| 34 namespace { | |
| 35 | |
| 36 ManagedUserRegistrationUtility* g_instance_for_tests = NULL; | |
| 37 | |
| 38 // Actual implementation of ManagedUserRegistrationUtility. | |
| 39 class ManagedUserRegistrationUtilityImpl | |
| 40 : public ManagedUserRegistrationUtility, | |
| 41 public ManagedUserSyncServiceObserver { | |
| 42 public: | |
| 43 ManagedUserRegistrationUtilityImpl( | |
| 44 PrefService* prefs, | |
| 45 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, | |
| 46 ManagedUserSyncService* service, | |
| 47 ManagedUserSharedSettingsService* shared_settings_service); | |
| 48 | |
| 49 virtual ~ManagedUserRegistrationUtilityImpl(); | |
| 50 | |
| 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 | |
| 59 // yet exist. | |
| 60 virtual void Register(const std::string& managed_user_id, | |
| 61 const ManagedUserRegistrationInfo& info, | |
| 62 const RegistrationCallback& callback) OVERRIDE; | |
| 63 | |
| 64 // ManagedUserSyncServiceObserver: | |
| 65 virtual void OnManagedUserAcknowledged(const std::string& managed_user_id) | |
| 66 OVERRIDE; | |
| 67 virtual void OnManagedUsersSyncingStopped() OVERRIDE; | |
| 68 virtual void OnManagedUsersChanged() OVERRIDE; | |
| 69 | |
| 70 private: | |
| 71 // Fetches the managed user token when we have the device name. | |
| 72 void FetchToken(const std::string& client_name); | |
| 73 | |
| 74 // Called when we have received a token for the managed user. | |
| 75 void OnReceivedToken(const GoogleServiceAuthError& error, | |
| 76 const std::string& token); | |
| 77 | |
| 78 // Dispatches the callback and cleans up if all the conditions have been met. | |
| 79 void CompleteRegistrationIfReady(); | |
| 80 | |
| 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); | |
| 85 | |
| 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); | |
| 91 | |
| 92 // Cancels any registration currently in progress, without calling the | |
| 93 // callback or reporting an error. | |
| 94 void CancelPendingRegistration(); | |
| 95 | |
| 96 // ManagedUserSharedSettingsUpdate acknowledgment callback for password data | |
| 97 // in shared settings. | |
| 98 void OnPasswordChangeAcknowledged(bool success); | |
| 99 | |
| 100 PrefService* prefs_; | |
| 101 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_; | |
| 102 | |
| 103 // A |KeyedService| owned by the custodian profile. | |
| 104 ManagedUserSyncService* managed_user_sync_service_; | |
| 105 | |
| 106 // A |KeyedService| owned by the custodian profile. | |
| 107 ManagedUserSharedSettingsService* managed_user_shared_settings_service_; | |
| 108 | |
| 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_; | |
| 116 | |
| 117 base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_; | |
| 118 | |
| 119 DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl); | |
| 120 }; | |
| 121 | |
| 122 } // namespace | |
| 123 | |
| 124 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo( | |
| 125 const base::string16& name, | |
| 126 int avatar_index) | |
| 127 : avatar_index(avatar_index), | |
| 128 name(name) { | |
| 129 } | |
| 130 | |
| 131 ManagedUserRegistrationInfo::~ManagedUserRegistrationInfo() {} | |
| 132 | |
| 133 ScopedTestingManagedUserRegistrationUtility:: | |
| 134 ScopedTestingManagedUserRegistrationUtility( | |
| 135 ManagedUserRegistrationUtility* instance) { | |
| 136 ManagedUserRegistrationUtility::SetUtilityForTests(instance); | |
| 137 } | |
| 138 | |
| 139 ScopedTestingManagedUserRegistrationUtility:: | |
| 140 ~ScopedTestingManagedUserRegistrationUtility() { | |
| 141 ManagedUserRegistrationUtility::SetUtilityForTests(NULL); | |
| 142 } | |
| 143 | |
| 144 // static | |
| 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); | |
| 151 } | |
| 152 | |
| 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( | |
| 159 token_service, | |
| 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( | |
| 167 profile->GetPrefs(), | |
| 168 token_fetcher.Pass(), | |
| 169 managed_user_sync_service, | |
| 170 managed_user_shared_settings_service)); | |
| 171 } | |
| 172 | |
| 173 // static | |
| 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; | |
| 178 } | |
| 179 | |
| 180 // static | |
| 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; | |
| 186 } | |
| 187 | |
| 188 // static | |
| 189 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl( | |
| 190 PrefService* prefs, | |
| 191 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, | |
| 192 ManagedUserSyncService* service, | |
| 193 ManagedUserSharedSettingsService* shared_settings_service) { | |
| 194 return new ManagedUserRegistrationUtilityImpl(prefs, | |
| 195 token_fetcher.Pass(), | |
| 196 service, | |
| 197 shared_settings_service); | |
| 198 } | |
| 199 | |
| 200 namespace { | |
| 201 | |
| 202 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl( | |
| 203 PrefService* prefs, | |
| 204 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, | |
| 205 ManagedUserSyncService* service, | |
| 206 ManagedUserSharedSettingsService* shared_settings_service) | |
| 207 : prefs_(prefs), | |
| 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); | |
| 216 } | |
| 217 | |
| 218 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() { | |
| 219 managed_user_sync_service_->RemoveObserver(this); | |
| 220 CancelPendingRegistration(); | |
| 221 } | |
| 222 | |
| 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; | |
| 230 | |
| 231 bool need_password_update = !info.password_data.empty(); | |
| 232 const base::DictionaryValue* dict = | |
| 233 prefs_->GetDictionary(prefs::kSupervisedUsers); | |
| 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), | |
| 238 info.master_key, | |
| 239 info.password_signature_key, | |
| 240 info.password_encryption_key, | |
| 241 info.avatar_index); | |
| 242 } else { | |
| 243 const base::DictionaryValue* value = NULL; | |
| 244 bool success = | |
| 245 dict->GetDictionaryWithoutPathExpansion(managed_user_id, &value); | |
| 246 DCHECK(success); | |
| 247 std::string key; | |
| 248 bool need_keys = !info.password_signature_key.empty() || | |
| 249 !info.password_encryption_key.empty(); | |
| 250 bool have_keys = | |
| 251 value->GetString(ManagedUserSyncService::kPasswordSignatureKey, &key) && | |
| 252 !key.empty() && | |
| 253 value->GetString(ManagedUserSyncService::kPasswordEncryptionKey, | |
| 254 &key) && | |
| 255 !key.empty(); | |
| 256 | |
| 257 bool keys_need_update = need_keys && !have_keys; | |
| 258 | |
| 259 if (keys_need_update) { | |
| 260 managed_user_sync_service_->UpdateManagedUser( | |
| 261 pending_managed_user_id_, | |
| 262 base::UTF16ToUTF8(info.name), | |
| 263 info.master_key, | |
| 264 info.password_signature_key, | |
| 265 info.password_encryption_key, | |
| 266 info.avatar_index); | |
| 267 } else { | |
| 268 // The user already exists and does not need to be updated. | |
| 269 need_password_update = false; | |
| 270 OnManagedUserAcknowledged(managed_user_id); | |
| 271 } | |
| 272 avatar_updated_ = | |
| 273 managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded( | |
| 274 managed_user_id, | |
| 275 info.avatar_index); | |
| 276 } | |
| 277 #if defined(OS_CHROMEOS) | |
| 278 const char* kAvatarKey = managed_users::kChromeOSAvatarIndex; | |
| 279 #else | |
| 280 const char* kAvatarKey = managed_users::kChromeAvatarIndex; | |
| 281 #endif | |
| 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()), | |
| 291 base::Bind( | |
| 292 &ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged, | |
| 293 weak_ptr_factory_.GetWeakPtr()))); | |
| 294 } | |
| 295 | |
| 296 browser_sync::DeviceInfo::GetClientName( | |
| 297 base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken, | |
| 298 weak_ptr_factory_.GetWeakPtr())); | |
| 299 } | |
| 300 | |
| 301 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() { | |
| 302 AbortPendingRegistration( | |
| 303 false, // Don't run the callback. The error will be ignored. | |
| 304 GoogleServiceAuthError(GoogleServiceAuthError::NONE)); | |
| 305 } | |
| 306 | |
| 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(); | |
| 313 } | |
| 314 | |
| 315 void ManagedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged( | |
| 316 bool success) { | |
| 317 DCHECK(password_update_); | |
| 318 DCHECK(success); | |
| 319 password_update_.reset(); | |
| 320 CompleteRegistrationIfReady(); | |
| 321 } | |
| 322 | |
| 323 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() { | |
| 324 AbortPendingRegistration( | |
| 325 true, // Run the callback. | |
| 326 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); | |
| 327 } | |
| 328 | |
| 329 void ManagedUserRegistrationUtilityImpl::OnManagedUsersChanged() {} | |
| 330 | |
| 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())); | |
| 337 } | |
| 338 | |
| 339 void ManagedUserRegistrationUtilityImpl::OnReceivedToken( | |
| 340 const GoogleServiceAuthError& error, | |
| 341 const std::string& token) { | |
| 342 if (error.state() != GoogleServiceAuthError::NONE) { | |
| 343 CompleteRegistration(true, error); | |
| 344 return; | |
| 345 } | |
| 346 | |
| 347 DCHECK(!token.empty()); | |
| 348 pending_managed_user_token_ = token; | |
| 349 CompleteRegistrationIfReady(); | |
| 350 } | |
| 351 | |
| 352 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() { | |
| 353 bool skip_check = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 354 switches::kNoSupervisedUserAcknowledgmentCheck); | |
| 355 | |
| 356 if (!pending_managed_user_acknowledged_ && !skip_check) | |
| 357 return; | |
| 358 if (password_update_ && !skip_check) | |
| 359 return; | |
| 360 if (pending_managed_user_token_.empty()) | |
| 361 return; | |
| 362 | |
| 363 GoogleServiceAuthError error(GoogleServiceAuthError::NONE); | |
| 364 CompleteRegistration(true, error); | |
| 365 } | |
| 366 | |
| 367 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration( | |
| 368 bool run_callback, | |
| 369 const GoogleServiceAuthError& error) { | |
| 370 pending_managed_user_token_.clear(); | |
| 371 CompleteRegistration(run_callback, error); | |
| 372 } | |
| 373 | |
| 374 void ManagedUserRegistrationUtilityImpl::CompleteRegistration( | |
| 375 bool run_callback, | |
| 376 const GoogleServiceAuthError& error) { | |
| 377 if (callback_.is_null()) | |
| 378 return; | |
| 379 | |
| 380 if (pending_managed_user_token_.empty()) { | |
| 381 DCHECK(!pending_managed_user_id_.empty()); | |
| 382 | |
| 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_); | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 if (run_callback) | |
| 398 callback_.Run(error, pending_managed_user_token_); | |
| 399 callback_.Reset(); | |
| 400 } | |
| 401 | |
| 402 } // namespace | |
| OLD | NEW |