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/memory/scoped_ptr.h" 10 #include "base/prefs/pref_service.h" 11 #include "base/rand_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h" 14 #include "chrome/browser/managed_mode/managed_user_service.h" 15 #include "chrome/browser/managed_mode/managed_user_service_factory.h" 16 #include "chrome/browser/managed_mode/managed_user_sync_service.h" 17 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h" 18 #include "chrome/browser/prefs/scoped_user_pref_update.h" 19 #include "chrome/browser/signin/profile_oauth2_token_service.h" 20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 21 #include "chrome/browser/sync/glue/device_info.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 const char kAcknowledged[] = "acknowledged"; 29 const char kName[] = "name"; 30 const char kMasterKey[] = "masterKey"; 31 32 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(const string16& name) 33 : name(name) { 34 } 35 36 ManagedUserRegistrationUtility::ManagedUserRegistrationUtility( 37 PrefService* prefs, 38 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher, 39 ManagedUserSyncService* service) 40 : weak_ptr_factory_(this), 41 prefs_(prefs), 42 token_fetcher_(token_fetcher.Pass()), 43 managed_user_sync_service_(service), 44 pending_managed_user_acknowledged_(false), 45 is_existing_managed_user_(false) { 46 managed_user_sync_service_->AddObserver(this); 47 } 48 49 ManagedUserRegistrationUtility::~ManagedUserRegistrationUtility() { 50 managed_user_sync_service_->RemoveObserver(this); 51 CancelPendingRegistration(); 52 } 53 54 // static 55 scoped_ptr<ManagedUserRegistrationUtility> 56 ManagedUserRegistrationUtility::Create(Profile* profile) { 57 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher = 58 ManagedUserRefreshTokenFetcher::Create( 59 ProfileOAuth2TokenServiceFactory::GetForProfile(profile), 60 profile->GetRequestContext()); 61 ManagedUserSyncService* managed_user_sync_service = 62 ManagedUserSyncServiceFactory::GetForProfile(profile); 63 return make_scoped_ptr(new ManagedUserRegistrationUtility( 64 profile->GetPrefs(), token_fetcher.Pass(), managed_user_sync_service)); 65 } 66 67 // static 68 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() { 69 std::string new_managed_user_id; 70 bool success = base::Base64Encode(base::RandBytesAsString(8), 71 &new_managed_user_id); 72 DCHECK(success); 73 return new_managed_user_id; 74 } 75 76 void ManagedUserRegistrationUtility::Register( 77 const std::string& managed_user_id, 78 const ManagedUserRegistrationInfo& info, 79 const RegistrationCallback& callback) { 80 DCHECK(pending_managed_user_id_.empty()); 81 callback_ = callback; 82 pending_managed_user_id_ = managed_user_id; 83 84 const DictionaryValue* dict = prefs_->GetDictionary(prefs::kManagedUsers); 85 is_existing_managed_user_ = dict->HasKey(managed_user_id); 86 if (!is_existing_managed_user_) { 87 managed_user_sync_service_->AddManagedUser(pending_managed_user_id_, 88 base::UTF16ToUTF8(info.name), 89 info.master_key); 90 } else { 91 // User already exists, don't wait for acknowledgment. 92 OnManagedUserAcknowledged(managed_user_id); 93 } 94 95 browser_sync::DeviceInfo::GetClientName( 96 base::Bind(&ManagedUserRegistrationUtility::FetchToken, 97 weak_ptr_factory_.GetWeakPtr())); 98 } 99 100 void ManagedUserRegistrationUtility::CancelPendingRegistration() { 101 AbortPendingRegistration( 102 false, // Don't run the callback. The error will be ignored. 103 GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 104 } 105 106 void ManagedUserRegistrationUtility::OnManagedUserAcknowledged( 107 const std::string& managed_user_id) { 108 DCHECK_EQ(pending_managed_user_id_, managed_user_id); 109 DCHECK(!pending_managed_user_acknowledged_); 110 pending_managed_user_acknowledged_ = true; 111 CompleteRegistrationIfReady(); 112 } 113 114 void ManagedUserRegistrationUtility::OnManagedUsersSyncingStopped() { 115 AbortPendingRegistration( 116 true, // Run the callback. 117 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); 118 } 119 120 void ManagedUserRegistrationUtility::FetchToken( 121 const std::string& client_name) { 122 token_fetcher_->Start( 123 pending_managed_user_id_, client_name, 124 base::Bind(&ManagedUserRegistrationUtility::OnReceivedToken, 125 weak_ptr_factory_.GetWeakPtr())); 126 } 127 128 void ManagedUserRegistrationUtility::OnReceivedToken( 129 const GoogleServiceAuthError& error, 130 const std::string& token) { 131 if (error.state() != GoogleServiceAuthError::NONE) { 132 CompleteRegistration(true, error); 133 return; 134 } 135 136 DCHECK(!token.empty()); 137 pending_managed_user_token_ = token; 138 CompleteRegistrationIfReady(); 139 } 140 141 void ManagedUserRegistrationUtility::CompleteRegistrationIfReady() { 142 if (!pending_managed_user_acknowledged_ || 143 pending_managed_user_token_.empty()) { 144 return; 145 } 146 147 GoogleServiceAuthError error(GoogleServiceAuthError::NONE); 148 CompleteRegistration(true, error); 149 } 150 151 void ManagedUserRegistrationUtility::AbortPendingRegistration( 152 bool run_callback, 153 const GoogleServiceAuthError& error) { 154 pending_managed_user_token_.clear(); 155 CompleteRegistration(run_callback, error); 156 } 157 158 void ManagedUserRegistrationUtility::CompleteRegistration( 159 bool run_callback, 160 const GoogleServiceAuthError& error) { 161 if (callback_.is_null()) 162 return; 163 164 // We check that the user being registered is not an existing managed 165 // user before deleting it from sync to avoid accidental deletion of 166 // existing managed users by just canceling the registration for example. 167 if (pending_managed_user_token_.empty() && !is_existing_managed_user_) { 168 DCHECK(!pending_managed_user_id_.empty()); 169 // Remove the pending managed user if we weren't successful. 170 DictionaryPrefUpdate update(prefs_, prefs::kManagedUsers); 171 bool success = 172 update->RemoveWithoutPathExpansion(pending_managed_user_id_, NULL); 173 DCHECK(success); 174 managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_); 175 } 176 177 if (run_callback) 178 callback_.Run(error, pending_managed_user_token_); 179 callback_.Reset(); 180 } 181