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_refresh_token_fetcher.h" 15 #include "chrome/browser/managed_mode/managed_user_sync_service.h" 16 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/signin/profile_oauth2_token_service.h" 19 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 20 #include "chrome/browser/sync/glue/device_info.h" 21 #include "chrome/common/chrome_switches.h" 22 #include "chrome/common/pref_names.h" 23 #include "google_apis/gaia/gaia_urls.h" 24 #include "google_apis/gaia/google_service_auth_error.h" 25 26 using base::DictionaryValue; 27 28 namespace { 29 30 ManagedUserRegistrationUtility* g_instance_for_tests = NULL; 31 32 // Actual implementation of ManagedUserRegistrationUtility. 33 class ManagedUserRegistrationUtilityImpl 34 : public ManagedUserRegistrationUtility, 35 public ManagedUserSyncServiceObserver { 36 public: 37 ManagedUserRegistrationUtilityImpl( 38 PrefService* prefs, 39 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, 40 ManagedUserSyncService* service); 41 42 virtual ~ManagedUserRegistrationUtilityImpl(); 43 44 // Registers a new managed user with the server. |managed_user_id| is a new 45 // unique ID for the new managed user. If its value is the same as that of 46 // of one of the existing managed users, then the same user will be created 47 // on this machine (and if he has no avatar in sync, his avatar will 48 // be updated). |info| contains necessary information like 49 // the display name of the user and his avatar. |callback| is called 50 // with the result of the registration. We use the info here and not the 51 // profile, because on Chrome OS the profile of the managed user does not 52 // yet exist. 53 virtual void Register(const std::string& managed_user_id, 54 const ManagedUserRegistrationInfo& info, 55 const RegistrationCallback& callback) OVERRIDE; 56 57 // ManagedUserSyncServiceObserver: 58 virtual void OnManagedUserAcknowledged(const std::string& managed_user_id) 59 OVERRIDE; 60 virtual void OnManagedUsersSyncingStopped() OVERRIDE; 61 62 private: 63 // Fetches the managed user token when we have the device name. 64 void FetchToken(const std::string& client_name); 65 66 // Called when we have received a token for the managed user. 67 void OnReceivedToken(const GoogleServiceAuthError& error, 68 const std::string& token); 69 70 // Dispatches the callback and cleans up if all the conditions have been met. 71 void CompleteRegistrationIfReady(); 72 73 // Aborts any registration currently in progress. If |run_callback| is true, 74 // calls the callback specified in Register() with the given |error|. 75 void AbortPendingRegistration(bool run_callback, 76 const GoogleServiceAuthError& error); 77 78 // If |run_callback| is true, dispatches the callback with the saved token 79 // (which may be empty) and the given |error|. In any case, resets internal 80 // variables to be ready for the next registration. 81 void CompleteRegistration(bool run_callback, 82 const GoogleServiceAuthError& error); 83 84 // Cancels any registration currently in progress, without calling the 85 // callback or reporting an error. 86 void CancelPendingRegistration(); 87 88 PrefService* prefs_; 89 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_; 90 91 // A |BrowserContextKeyedService| owned by the custodian profile. 92 ManagedUserSyncService* managed_user_sync_service_; 93 94 std::string pending_managed_user_id_; 95 std::string pending_managed_user_token_; 96 bool pending_managed_user_acknowledged_; 97 bool is_existing_managed_user_; 98 bool avatar_updated_; 99 RegistrationCallback callback_; 100 101 base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_; 102 103 DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl); 104 }; 105 106 } // namespace 107 108 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo( 109 const base::string16& name, 110 int avatar_index) 111 : avatar_index(avatar_index), 112 name(name) { 113 } 114 115 ScopedTestingManagedUserRegistrationUtility:: 116 ScopedTestingManagedUserRegistrationUtility( 117 ManagedUserRegistrationUtility* instance) { 118 ManagedUserRegistrationUtility::SetUtilityForTests(instance); 119 } 120 121 ScopedTestingManagedUserRegistrationUtility:: 122 ~ScopedTestingManagedUserRegistrationUtility() { 123 ManagedUserRegistrationUtility::SetUtilityForTests(NULL); 124 } 125 126 // static 127 scoped_ptr<ManagedUserRegistrationUtility> 128 ManagedUserRegistrationUtility::Create(Profile* profile) { 129 if (g_instance_for_tests) { 130 ManagedUserRegistrationUtility* result = g_instance_for_tests; 131 g_instance_for_tests = NULL; 132 return make_scoped_ptr(result); 133 } 134 135 ProfileOAuth2TokenService* token_service = 136 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 137 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher = 138 ManagedUserRefreshTokenFetcher::Create( 139 token_service, 140 token_service->GetPrimaryAccountId(), 141 profile->GetRequestContext()); 142 ManagedUserSyncService* managed_user_sync_service = 143 ManagedUserSyncServiceFactory::GetForProfile(profile); 144 return make_scoped_ptr(ManagedUserRegistrationUtility::CreateImpl( 145 profile->GetPrefs(), 146 token_fetcher.Pass(), 147 managed_user_sync_service)); 148 } 149 150 // static 151 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() { 152 std::string new_managed_user_id; 153 base::Base64Encode(base::RandBytesAsString(8), &new_managed_user_id); 154 return new_managed_user_id; 155 } 156 157 // static 158 void ManagedUserRegistrationUtility::SetUtilityForTests( 159 ManagedUserRegistrationUtility* utility) { 160 if (g_instance_for_tests) 161 delete g_instance_for_tests; 162 g_instance_for_tests = utility; 163 } 164 165 // static 166 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl( 167 PrefService* prefs, 168 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, 169 ManagedUserSyncService* service) { 170 return new ManagedUserRegistrationUtilityImpl(prefs, 171 token_fetcher.Pass(), 172 service); 173 } 174 175 namespace { 176 177 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl( 178 PrefService* prefs, 179 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, 180 ManagedUserSyncService* service) 181 : prefs_(prefs), 182 token_fetcher_(token_fetcher.Pass()), 183 managed_user_sync_service_(service), 184 pending_managed_user_acknowledged_(false), 185 is_existing_managed_user_(false), 186 avatar_updated_(false), 187 weak_ptr_factory_(this) { 188 managed_user_sync_service_->AddObserver(this); 189 } 190 191 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() { 192 managed_user_sync_service_->RemoveObserver(this); 193 CancelPendingRegistration(); 194 } 195 196 void ManagedUserRegistrationUtilityImpl::Register( 197 const std::string& managed_user_id, 198 const ManagedUserRegistrationInfo& info, 199 const RegistrationCallback& callback) { 200 DCHECK(pending_managed_user_id_.empty()); 201 callback_ = callback; 202 pending_managed_user_id_ = managed_user_id; 203 204 const DictionaryValue* dict = prefs_->GetDictionary(prefs::kManagedUsers); 205 is_existing_managed_user_ = dict->HasKey(managed_user_id); 206 if (!is_existing_managed_user_) { 207 managed_user_sync_service_->AddManagedUser(pending_managed_user_id_, 208 base::UTF16ToUTF8(info.name), 209 info.master_key, 210 info.avatar_index); 211 } else { 212 avatar_updated_ = 213 managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded( 214 managed_user_id, 215 info.avatar_index); 216 217 // User already exists, don't wait for acknowledgment. 218 OnManagedUserAcknowledged(managed_user_id); 219 } 220 221 browser_sync::DeviceInfo::GetClientName( 222 base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken, 223 weak_ptr_factory_.GetWeakPtr())); 224 } 225 226 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() { 227 AbortPendingRegistration( 228 false, // Don't run the callback. The error will be ignored. 229 GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 230 } 231 232 void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged( 233 const std::string& managed_user_id) { 234 DCHECK_EQ(pending_managed_user_id_, managed_user_id); 235 DCHECK(!pending_managed_user_acknowledged_); 236 pending_managed_user_acknowledged_ = true; 237 CompleteRegistrationIfReady(); 238 } 239 240 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() { 241 AbortPendingRegistration( 242 true, // Run the callback. 243 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); 244 } 245 246 void ManagedUserRegistrationUtilityImpl::FetchToken( 247 const std::string& client_name) { 248 token_fetcher_->Start( 249 pending_managed_user_id_, client_name, 250 base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken, 251 weak_ptr_factory_.GetWeakPtr())); 252 } 253 254 void ManagedUserRegistrationUtilityImpl::OnReceivedToken( 255 const GoogleServiceAuthError& error, 256 const std::string& token) { 257 if (error.state() != GoogleServiceAuthError::NONE) { 258 CompleteRegistration(true, error); 259 return; 260 } 261 262 DCHECK(!token.empty()); 263 pending_managed_user_token_ = token; 264 CompleteRegistrationIfReady(); 265 } 266 267 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() { 268 bool require_acknowledgment = 269 !pending_managed_user_acknowledged_ && 270 !CommandLine::ForCurrentProcess()->HasSwitch( 271 switches::kNoManagedUserAcknowledgmentCheck); 272 if (require_acknowledgment || pending_managed_user_token_.empty()) 273 return; 274 275 GoogleServiceAuthError error(GoogleServiceAuthError::NONE); 276 CompleteRegistration(true, error); 277 } 278 279 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration( 280 bool run_callback, 281 const GoogleServiceAuthError& error) { 282 pending_managed_user_token_.clear(); 283 CompleteRegistration(run_callback, error); 284 } 285 286 void ManagedUserRegistrationUtilityImpl::CompleteRegistration( 287 bool run_callback, 288 const GoogleServiceAuthError& error) { 289 if (callback_.is_null()) 290 return; 291 292 if (pending_managed_user_token_.empty()) { 293 DCHECK(!pending_managed_user_id_.empty()); 294 295 if (!is_existing_managed_user_) { 296 // Remove the pending managed user if we weren't successful. 297 // However, check that we are not importing a managed user 298 // before deleting it from sync to avoid accidental deletion of 299 // existing managed users by just canceling the registration for example. 300 managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_); 301 } else if (avatar_updated_) { 302 // Canceling (or failing) a managed user import that did set the avatar 303 // should undo this change. 304 managed_user_sync_service_->ClearManagedUserAvatar( 305 pending_managed_user_id_); 306 } 307 } 308 309 if (run_callback) 310 callback_.Run(error, pending_managed_user_token_); 311 callback_.Reset(); 312 } 313 314 } // namespace 315