Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / managed_mode / managed_user_registration_utility.cc
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_factory.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::kManagedUsers);
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::kNoManagedUserAcknowledgmentCheck);
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