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_sync_service.h"
19 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/signin/profile_oauth2_token_service.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager.h"
24 #include "chrome/browser/signin/signin_manager_factory.h"
25 #include "chrome/browser/sync/glue/device_info.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h"
28 #include "google_apis/gaia/gaia_urls.h"
29 #include "google_apis/gaia/google_service_auth_error.h"
31 using base::DictionaryValue;
35 ManagedUserRegistrationUtility* g_instance_for_tests = NULL;
37 // Actual implementation of ManagedUserRegistrationUtility.
38 class ManagedUserRegistrationUtilityImpl
39 : public ManagedUserRegistrationUtility,
40 public ManagedUserSyncServiceObserver {
42 ManagedUserRegistrationUtilityImpl(
44 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
45 ManagedUserSyncService* service,
46 ManagedUserSharedSettingsService* shared_settings_service);
48 virtual ~ManagedUserRegistrationUtilityImpl();
50 // Registers a new managed user with the server. |managed_user_id| is a new
51 // unique ID for the new managed user. If its value is the same as that of
52 // of one of the existing managed users, then the same user will be created
53 // on this machine (and if he has no avatar in sync, his avatar will
54 // be updated). |info| contains necessary information like
55 // the display name of the user and his avatar. |callback| is called
56 // with the result of the registration. We use the info here and not the
57 // profile, because on Chrome OS the profile of the managed user does not
59 virtual void Register(const std::string& managed_user_id,
60 const ManagedUserRegistrationInfo& info,
61 const RegistrationCallback& callback) OVERRIDE;
63 // ManagedUserSyncServiceObserver:
64 virtual void OnManagedUserAcknowledged(const std::string& managed_user_id)
66 virtual void OnManagedUsersSyncingStopped() OVERRIDE;
67 virtual void OnManagedUsersChanged() OVERRIDE;
70 // Fetches the managed user token when we have the device name.
71 void FetchToken(const std::string& client_name);
73 // Called when we have received a token for the managed user.
74 void OnReceivedToken(const GoogleServiceAuthError& error,
75 const std::string& token);
77 // Dispatches the callback and cleans up if all the conditions have been met.
78 void CompleteRegistrationIfReady();
80 // Aborts any registration currently in progress. If |run_callback| is true,
81 // calls the callback specified in Register() with the given |error|.
82 void AbortPendingRegistration(bool run_callback,
83 const GoogleServiceAuthError& error);
85 // If |run_callback| is true, dispatches the callback with the saved token
86 // (which may be empty) and the given |error|. In any case, resets internal
87 // variables to be ready for the next registration.
88 void CompleteRegistration(bool run_callback,
89 const GoogleServiceAuthError& error);
91 // Cancels any registration currently in progress, without calling the
92 // callback or reporting an error.
93 void CancelPendingRegistration();
96 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
98 // A |BrowserContextKeyedService| owned by the custodian profile.
99 ManagedUserSyncService* managed_user_sync_service_;
101 // A |BrowserContextKeyedService| owned by the custodian profile.
102 ManagedUserSharedSettingsService* managed_user_shared_settings_service_;
104 std::string pending_managed_user_id_;
105 std::string pending_managed_user_token_;
106 bool pending_managed_user_acknowledged_;
107 bool is_existing_managed_user_;
108 bool avatar_updated_;
109 RegistrationCallback callback_;
111 base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_;
113 DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl);
118 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(
119 const base::string16& name,
121 : avatar_index(avatar_index),
125 ScopedTestingManagedUserRegistrationUtility::
126 ScopedTestingManagedUserRegistrationUtility(
127 ManagedUserRegistrationUtility* instance) {
128 ManagedUserRegistrationUtility::SetUtilityForTests(instance);
131 ScopedTestingManagedUserRegistrationUtility::
132 ~ScopedTestingManagedUserRegistrationUtility() {
133 ManagedUserRegistrationUtility::SetUtilityForTests(NULL);
137 scoped_ptr<ManagedUserRegistrationUtility>
138 ManagedUserRegistrationUtility::Create(Profile* profile) {
139 if (g_instance_for_tests) {
140 ManagedUserRegistrationUtility* result = g_instance_for_tests;
141 g_instance_for_tests = NULL;
142 return make_scoped_ptr(result);
145 ProfileOAuth2TokenService* token_service =
146 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
147 SigninManagerBase* signin_manager =
148 SigninManagerFactory::GetForProfile(profile);
149 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher =
150 ManagedUserRefreshTokenFetcher::Create(
152 signin_manager->GetAuthenticatedAccountId(),
153 profile->GetRequestContext());
154 ManagedUserSyncService* managed_user_sync_service =
155 ManagedUserSyncServiceFactory::GetForProfile(profile);
156 ManagedUserSharedSettingsService* managed_user_shared_settings_service =
157 ManagedUserSharedSettingsServiceFactory::GetForBrowserContext(profile);
158 return make_scoped_ptr(ManagedUserRegistrationUtility::CreateImpl(
160 token_fetcher.Pass(),
161 managed_user_sync_service,
162 managed_user_shared_settings_service));
166 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() {
167 std::string new_managed_user_id;
168 base::Base64Encode(base::RandBytesAsString(8), &new_managed_user_id);
169 return new_managed_user_id;
173 void ManagedUserRegistrationUtility::SetUtilityForTests(
174 ManagedUserRegistrationUtility* utility) {
175 if (g_instance_for_tests)
176 delete g_instance_for_tests;
177 g_instance_for_tests = utility;
181 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl(
183 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
184 ManagedUserSyncService* service,
185 ManagedUserSharedSettingsService* shared_settings_service) {
186 return new ManagedUserRegistrationUtilityImpl(prefs,
187 token_fetcher.Pass(),
189 shared_settings_service);
194 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl(
196 scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
197 ManagedUserSyncService* service,
198 ManagedUserSharedSettingsService* shared_settings_service)
200 token_fetcher_(token_fetcher.Pass()),
201 managed_user_sync_service_(service),
202 managed_user_shared_settings_service_(shared_settings_service),
203 pending_managed_user_acknowledged_(false),
204 is_existing_managed_user_(false),
205 avatar_updated_(false),
206 weak_ptr_factory_(this) {
207 managed_user_sync_service_->AddObserver(this);
210 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() {
211 managed_user_sync_service_->RemoveObserver(this);
212 CancelPendingRegistration();
215 void ManagedUserRegistrationUtilityImpl::Register(
216 const std::string& managed_user_id,
217 const ManagedUserRegistrationInfo& info,
218 const RegistrationCallback& callback) {
219 DCHECK(pending_managed_user_id_.empty());
220 callback_ = callback;
221 pending_managed_user_id_ = managed_user_id;
223 const base::DictionaryValue* dict =
224 prefs_->GetDictionary(prefs::kManagedUsers);
225 is_existing_managed_user_ = dict->HasKey(managed_user_id);
226 if (!is_existing_managed_user_) {
227 managed_user_sync_service_->AddManagedUser(pending_managed_user_id_,
228 base::UTF16ToUTF8(info.name),
233 managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded(
237 // User already exists, don't wait for acknowledgment.
238 OnManagedUserAcknowledged(managed_user_id);
240 #if defined(OS_CHROMEOS)
241 const char* kAvatarKey = managed_users::kChromeOSAvatarIndex;
243 const char* kAvatarKey = managed_users::kChromeAvatarIndex;
245 managed_user_shared_settings_service_->SetValue(
246 pending_managed_user_id_, kAvatarKey,
247 base::FundamentalValue(info.avatar_index));
249 browser_sync::DeviceInfo::GetClientName(
250 base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken,
251 weak_ptr_factory_.GetWeakPtr()));
254 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
255 AbortPendingRegistration(
256 false, // Don't run the callback. The error will be ignored.
257 GoogleServiceAuthError(GoogleServiceAuthError::NONE));
260 void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged(
261 const std::string& managed_user_id) {
262 DCHECK_EQ(pending_managed_user_id_, managed_user_id);
263 DCHECK(!pending_managed_user_acknowledged_);
264 pending_managed_user_acknowledged_ = true;
265 CompleteRegistrationIfReady();
268 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
269 AbortPendingRegistration(
270 true, // Run the callback.
271 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
274 void ManagedUserRegistrationUtilityImpl::OnManagedUsersChanged() {}
276 void ManagedUserRegistrationUtilityImpl::FetchToken(
277 const std::string& client_name) {
278 token_fetcher_->Start(
279 pending_managed_user_id_, client_name,
280 base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken,
281 weak_ptr_factory_.GetWeakPtr()));
284 void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
285 const GoogleServiceAuthError& error,
286 const std::string& token) {
287 if (error.state() != GoogleServiceAuthError::NONE) {
288 CompleteRegistration(true, error);
292 DCHECK(!token.empty());
293 pending_managed_user_token_ = token;
294 CompleteRegistrationIfReady();
297 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
298 bool require_acknowledgment =
299 !pending_managed_user_acknowledged_ &&
300 !CommandLine::ForCurrentProcess()->HasSwitch(
301 switches::kNoManagedUserAcknowledgmentCheck);
302 if (require_acknowledgment || pending_managed_user_token_.empty())
305 GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
306 CompleteRegistration(true, error);
309 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
311 const GoogleServiceAuthError& error) {
312 pending_managed_user_token_.clear();
313 CompleteRegistration(run_callback, error);
316 void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
318 const GoogleServiceAuthError& error) {
319 if (callback_.is_null())
322 if (pending_managed_user_token_.empty()) {
323 DCHECK(!pending_managed_user_id_.empty());
325 if (!is_existing_managed_user_) {
326 // Remove the pending managed user if we weren't successful.
327 // However, check that we are not importing a managed user
328 // before deleting it from sync to avoid accidental deletion of
329 // existing managed users by just canceling the registration for example.
330 managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_);
331 } else if (avatar_updated_) {
332 // Canceling (or failing) a managed user import that did set the avatar
333 // should undo this change.
334 managed_user_sync_service_->ClearManagedUserAvatar(
335 pending_managed_user_id_);
340 callback_.Run(error, pending_managed_user_token_);