Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / supervised_user / supervised_user_registration_utility.cc
1 // Copyright 2014 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/supervised_user/supervised_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/profiles/profile.h"
15 #include "chrome/browser/signin/chrome_signin_client_factory.h"
16 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/browser/supervised_user/supervised_user_constants.h"
19 #include "chrome/browser/supervised_user/supervised_user_refresh_token_fetcher.h"
20 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h"
21 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
22 #include "chrome/browser/supervised_user/supervised_user_shared_settings_update.h"
23 #include "chrome/browser/supervised_user/supervised_user_sync_service.h"
24 #include "chrome/browser/supervised_user/supervised_user_sync_service_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 "components/signin/core/browser/profile_oauth2_token_service.h"
29 #include "components/signin/core/browser/signin_client.h"
30 #include "components/signin/core/browser/signin_manager.h"
31 #include "google_apis/gaia/gaia_urls.h"
32 #include "google_apis/gaia/google_service_auth_error.h"
33
34 using base::DictionaryValue;
35
36 namespace {
37
38 SupervisedUserRegistrationUtility* g_instance_for_tests = NULL;
39
40 // Actual implementation of SupervisedUserRegistrationUtility.
41 class SupervisedUserRegistrationUtilityImpl
42     : public SupervisedUserRegistrationUtility,
43       public SupervisedUserSyncServiceObserver {
44  public:
45   SupervisedUserRegistrationUtilityImpl(
46       PrefService* prefs,
47       scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher,
48       SupervisedUserSyncService* service,
49       SupervisedUserSharedSettingsService* shared_settings_service);
50
51   virtual ~SupervisedUserRegistrationUtilityImpl();
52
53   // Registers a new supervised user with the server. |supervised_user_id| is a
54   // new unique ID for the new supervised user. If its value is the same as that
55   // of one of the existing supervised users, then the same user will be created
56   // on this machine (and if he has no avatar in sync, his avatar will be
57   // updated). |info| contains necessary information like the display name of
58   // the user and his avatar. |callback| is called with the result of the
59   // registration. We use the info here and not the profile, because on Chrome
60   // OS the profile of the supervised user does not yet exist.
61   virtual void Register(const std::string& supervised_user_id,
62                         const SupervisedUserRegistrationInfo& info,
63                         const RegistrationCallback& callback) OVERRIDE;
64
65   // SupervisedUserSyncServiceObserver:
66   virtual void OnSupervisedUserAcknowledged(
67       const std::string& supervised_user_id) OVERRIDE;
68   virtual void OnSupervisedUsersSyncingStopped() OVERRIDE;
69   virtual void OnSupervisedUsersChanged() OVERRIDE;
70
71  private:
72   // Fetches the supervised user token when we have the device name.
73   void FetchToken(const std::string& client_name);
74
75   // Called when we have received a token for the supervised user.
76   void OnReceivedToken(const GoogleServiceAuthError& error,
77                        const std::string& token);
78
79   // Dispatches the callback and cleans up if all the conditions have been met.
80   void CompleteRegistrationIfReady();
81
82   // Aborts any registration currently in progress. If |run_callback| is true,
83   // calls the callback specified in Register() with the given |error|.
84   void AbortPendingRegistration(bool run_callback,
85                                 const GoogleServiceAuthError& error);
86
87   // If |run_callback| is true, dispatches the callback with the saved token
88   // (which may be empty) and the given |error|. In any case, resets internal
89   // variables to be ready for the next registration.
90   void CompleteRegistration(bool run_callback,
91                             const GoogleServiceAuthError& error);
92
93   // Cancels any registration currently in progress, without calling the
94   // callback or reporting an error.
95   void CancelPendingRegistration();
96
97   // SupervisedUserSharedSettingsUpdate acknowledgment callback for password
98   // data in shared settings.
99   void OnPasswordChangeAcknowledged(bool success);
100
101   PrefService* prefs_;
102   scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher_;
103
104   // A |KeyedService| owned by the custodian profile.
105   SupervisedUserSyncService* supervised_user_sync_service_;
106
107   // A |KeyedService| owned by the custodian profile.
108   SupervisedUserSharedSettingsService* supervised_user_shared_settings_service_;
109
110   std::string pending_supervised_user_id_;
111   std::string pending_supervised_user_token_;
112   bool pending_supervised_user_acknowledged_;
113   bool is_existing_supervised_user_;
114   bool avatar_updated_;
115   RegistrationCallback callback_;
116   scoped_ptr<SupervisedUserSharedSettingsUpdate> password_update_;
117
118   base::WeakPtrFactory<SupervisedUserRegistrationUtilityImpl> weak_ptr_factory_;
119
120   DISALLOW_COPY_AND_ASSIGN(SupervisedUserRegistrationUtilityImpl);
121 };
122
123 } // namespace
124
125 SupervisedUserRegistrationInfo::SupervisedUserRegistrationInfo(
126     const base::string16& name,
127     int avatar_index)
128     : avatar_index(avatar_index),
129       name(name) {
130 }
131
132 SupervisedUserRegistrationInfo::~SupervisedUserRegistrationInfo() {}
133
134 ScopedTestingSupervisedUserRegistrationUtility::
135     ScopedTestingSupervisedUserRegistrationUtility(
136         SupervisedUserRegistrationUtility* instance) {
137   SupervisedUserRegistrationUtility::SetUtilityForTests(instance);
138 }
139
140 ScopedTestingSupervisedUserRegistrationUtility::
141     ~ScopedTestingSupervisedUserRegistrationUtility() {
142   SupervisedUserRegistrationUtility::SetUtilityForTests(NULL);
143 }
144
145 // static
146 scoped_ptr<SupervisedUserRegistrationUtility>
147 SupervisedUserRegistrationUtility::Create(Profile* profile) {
148   if (g_instance_for_tests) {
149     SupervisedUserRegistrationUtility* result = g_instance_for_tests;
150     g_instance_for_tests = NULL;
151     return make_scoped_ptr(result);
152   }
153
154   ProfileOAuth2TokenService* token_service =
155       ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
156   SigninManagerBase* signin_manager =
157       SigninManagerFactory::GetForProfile(profile);
158   SigninClient* signin_client =
159       ChromeSigninClientFactory::GetForProfile(profile);
160   std::string signin_scoped_device_id =
161       signin_client->GetSigninScopedDeviceId();
162   scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher =
163       SupervisedUserRefreshTokenFetcher::Create(
164           token_service,
165           signin_manager->GetAuthenticatedAccountId(),
166           signin_scoped_device_id,
167           profile->GetRequestContext());
168   SupervisedUserSyncService* supervised_user_sync_service =
169       SupervisedUserSyncServiceFactory::GetForProfile(profile);
170   SupervisedUserSharedSettingsService* supervised_user_shared_settings_service =
171       SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(profile);
172   return make_scoped_ptr(SupervisedUserRegistrationUtility::CreateImpl(
173       profile->GetPrefs(),
174       token_fetcher.Pass(),
175       supervised_user_sync_service,
176       supervised_user_shared_settings_service));
177 }
178
179 // static
180 std::string SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId() {
181   std::string new_supervised_user_id;
182   base::Base64Encode(base::RandBytesAsString(8), &new_supervised_user_id);
183   return new_supervised_user_id;
184 }
185
186 // static
187 void SupervisedUserRegistrationUtility::SetUtilityForTests(
188     SupervisedUserRegistrationUtility* utility) {
189   if (g_instance_for_tests)
190     delete g_instance_for_tests;
191   g_instance_for_tests = utility;
192 }
193
194 // static
195 SupervisedUserRegistrationUtility*
196 SupervisedUserRegistrationUtility::CreateImpl(
197       PrefService* prefs,
198       scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher,
199       SupervisedUserSyncService* service,
200       SupervisedUserSharedSettingsService* shared_settings_service) {
201   return new SupervisedUserRegistrationUtilityImpl(prefs,
202                                                    token_fetcher.Pass(),
203                                                    service,
204                                                    shared_settings_service);
205 }
206
207 namespace {
208
209 SupervisedUserRegistrationUtilityImpl::SupervisedUserRegistrationUtilityImpl(
210     PrefService* prefs,
211     scoped_ptr<SupervisedUserRefreshTokenFetcher> token_fetcher,
212     SupervisedUserSyncService* service,
213     SupervisedUserSharedSettingsService* shared_settings_service)
214     : prefs_(prefs),
215       token_fetcher_(token_fetcher.Pass()),
216       supervised_user_sync_service_(service),
217       supervised_user_shared_settings_service_(shared_settings_service),
218       pending_supervised_user_acknowledged_(false),
219       is_existing_supervised_user_(false),
220       avatar_updated_(false),
221       weak_ptr_factory_(this) {
222   supervised_user_sync_service_->AddObserver(this);
223 }
224
225 SupervisedUserRegistrationUtilityImpl::
226 ~SupervisedUserRegistrationUtilityImpl() {
227   supervised_user_sync_service_->RemoveObserver(this);
228   CancelPendingRegistration();
229 }
230
231 void SupervisedUserRegistrationUtilityImpl::Register(
232     const std::string& supervised_user_id,
233     const SupervisedUserRegistrationInfo& info,
234     const RegistrationCallback& callback) {
235   DCHECK(pending_supervised_user_id_.empty());
236   callback_ = callback;
237   pending_supervised_user_id_ = supervised_user_id;
238
239   bool need_password_update = !info.password_data.empty();
240   const base::DictionaryValue* dict =
241       prefs_->GetDictionary(prefs::kSupervisedUsers);
242   is_existing_supervised_user_ = dict->HasKey(supervised_user_id);
243   if (!is_existing_supervised_user_) {
244     supervised_user_sync_service_->AddSupervisedUser(
245         pending_supervised_user_id_,
246         base::UTF16ToUTF8(info.name),
247         info.master_key,
248         info.password_signature_key,
249         info.password_encryption_key,
250         info.avatar_index);
251   } else {
252     const base::DictionaryValue* value = NULL;
253     bool success =
254         dict->GetDictionaryWithoutPathExpansion(supervised_user_id, &value);
255     DCHECK(success);
256     std::string key;
257     bool need_keys = !info.password_signature_key.empty() ||
258                      !info.password_encryption_key.empty();
259     bool have_keys =
260         value->GetString(SupervisedUserSyncService::kPasswordSignatureKey,
261                          &key) &&
262         !key.empty() &&
263         value->GetString(SupervisedUserSyncService::kPasswordEncryptionKey,
264                          &key) &&
265         !key.empty();
266
267     bool keys_need_update = need_keys && !have_keys;
268
269     if (keys_need_update) {
270       supervised_user_sync_service_->UpdateSupervisedUser(
271           pending_supervised_user_id_,
272           base::UTF16ToUTF8(info.name),
273           info.master_key,
274           info.password_signature_key,
275           info.password_encryption_key,
276           info.avatar_index);
277     } else {
278       // The user already exists and does not need to be updated.
279       need_password_update = false;
280       OnSupervisedUserAcknowledged(supervised_user_id);
281     }
282     avatar_updated_ =
283         supervised_user_sync_service_->UpdateSupervisedUserAvatarIfNeeded(
284             supervised_user_id,
285             info.avatar_index);
286   }
287 #if defined(OS_CHROMEOS)
288   const char* kAvatarKey = supervised_users::kChromeOSAvatarIndex;
289 #else
290   const char* kAvatarKey = supervised_users::kChromeAvatarIndex;
291 #endif
292   supervised_user_shared_settings_service_->SetValue(
293       pending_supervised_user_id_, kAvatarKey,
294       base::FundamentalValue(info.avatar_index));
295   if (need_password_update) {
296     password_update_.reset(new SupervisedUserSharedSettingsUpdate(
297         supervised_user_shared_settings_service_,
298         pending_supervised_user_id_,
299         supervised_users::kChromeOSPasswordData,
300         scoped_ptr<base::Value>(info.password_data.DeepCopy()),
301         base::Bind(
302             &SupervisedUserRegistrationUtilityImpl::
303                 OnPasswordChangeAcknowledged,
304             weak_ptr_factory_.GetWeakPtr())));
305   }
306
307   browser_sync::DeviceInfo::GetClientName(
308       base::Bind(&SupervisedUserRegistrationUtilityImpl::FetchToken,
309                  weak_ptr_factory_.GetWeakPtr()));
310 }
311
312 void SupervisedUserRegistrationUtilityImpl::CancelPendingRegistration() {
313   AbortPendingRegistration(
314       false,  // Don't run the callback. The error will be ignored.
315       GoogleServiceAuthError(GoogleServiceAuthError::NONE));
316 }
317
318 void SupervisedUserRegistrationUtilityImpl::OnSupervisedUserAcknowledged(
319     const std::string& supervised_user_id) {
320   DCHECK_EQ(pending_supervised_user_id_, supervised_user_id);
321   DCHECK(!pending_supervised_user_acknowledged_);
322   pending_supervised_user_acknowledged_ = true;
323   CompleteRegistrationIfReady();
324 }
325
326 void SupervisedUserRegistrationUtilityImpl::OnPasswordChangeAcknowledged(
327     bool success) {
328   DCHECK(password_update_);
329   DCHECK(success);
330   password_update_.reset();
331   CompleteRegistrationIfReady();
332 }
333
334 void SupervisedUserRegistrationUtilityImpl::OnSupervisedUsersSyncingStopped() {
335   AbortPendingRegistration(
336       true,  // Run the callback.
337       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
338 }
339
340 void SupervisedUserRegistrationUtilityImpl::OnSupervisedUsersChanged() {}
341
342 void SupervisedUserRegistrationUtilityImpl::FetchToken(
343     const std::string& client_name) {
344   token_fetcher_->Start(
345       pending_supervised_user_id_, client_name,
346       base::Bind(&SupervisedUserRegistrationUtilityImpl::OnReceivedToken,
347                  weak_ptr_factory_.GetWeakPtr()));
348 }
349
350 void SupervisedUserRegistrationUtilityImpl::OnReceivedToken(
351     const GoogleServiceAuthError& error,
352     const std::string& token) {
353   if (error.state() != GoogleServiceAuthError::NONE) {
354     CompleteRegistration(true, error);
355     return;
356   }
357
358   DCHECK(!token.empty());
359   pending_supervised_user_token_ = token;
360   CompleteRegistrationIfReady();
361 }
362
363 void SupervisedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
364   bool skip_check = CommandLine::ForCurrentProcess()->HasSwitch(
365       switches::kNoSupervisedUserAcknowledgmentCheck);
366
367   if (!pending_supervised_user_acknowledged_ && !skip_check)
368     return;
369   if (password_update_ && !skip_check)
370     return;
371   if (pending_supervised_user_token_.empty())
372     return;
373
374   GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
375   CompleteRegistration(true, error);
376 }
377
378 void SupervisedUserRegistrationUtilityImpl::AbortPendingRegistration(
379     bool run_callback,
380     const GoogleServiceAuthError& error) {
381   pending_supervised_user_token_.clear();
382   CompleteRegistration(run_callback, error);
383 }
384
385 void SupervisedUserRegistrationUtilityImpl::CompleteRegistration(
386     bool run_callback,
387     const GoogleServiceAuthError& error) {
388   if (callback_.is_null())
389     return;
390
391   if (pending_supervised_user_token_.empty()) {
392     DCHECK(!pending_supervised_user_id_.empty());
393
394     if (!is_existing_supervised_user_) {
395       // Remove the pending supervised user if we weren't successful.
396       // However, check that we are not importing a supervised user
397       // before deleting it from sync to avoid accidental deletion of
398       // existing supervised users by just canceling the registration for
399       // example.
400       supervised_user_sync_service_->DeleteSupervisedUser(
401           pending_supervised_user_id_);
402     } else if (avatar_updated_) {
403       // Canceling (or failing) a supervised user import that did set the avatar
404       // should undo this change.
405       supervised_user_sync_service_->ClearSupervisedUserAvatar(
406           pending_supervised_user_id_);
407     }
408   }
409
410   if (run_callback)
411     callback_.Run(error, pending_supervised_user_token_);
412   callback_.Reset();
413 }
414
415 } // namespace