Upstream version 5.34.104.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_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"
30
31 using base::DictionaryValue;
32
33 namespace {
34
35 ManagedUserRegistrationUtility* g_instance_for_tests = NULL;
36
37 // Actual implementation of ManagedUserRegistrationUtility.
38 class ManagedUserRegistrationUtilityImpl
39     : public ManagedUserRegistrationUtility,
40       public ManagedUserSyncServiceObserver {
41  public:
42   ManagedUserRegistrationUtilityImpl(
43       PrefService* prefs,
44       scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
45       ManagedUserSyncService* service,
46       ManagedUserSharedSettingsService* shared_settings_service);
47
48   virtual ~ManagedUserRegistrationUtilityImpl();
49
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
58   // yet exist.
59   virtual void Register(const std::string& managed_user_id,
60                         const ManagedUserRegistrationInfo& info,
61                         const RegistrationCallback& callback) OVERRIDE;
62
63   // ManagedUserSyncServiceObserver:
64   virtual void OnManagedUserAcknowledged(const std::string& managed_user_id)
65       OVERRIDE;
66   virtual void OnManagedUsersSyncingStopped() OVERRIDE;
67   virtual void OnManagedUsersChanged() OVERRIDE;
68
69  private:
70   // Fetches the managed user token when we have the device name.
71   void FetchToken(const std::string& client_name);
72
73   // Called when we have received a token for the managed user.
74   void OnReceivedToken(const GoogleServiceAuthError& error,
75                        const std::string& token);
76
77   // Dispatches the callback and cleans up if all the conditions have been met.
78   void CompleteRegistrationIfReady();
79
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);
84
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);
90
91   // Cancels any registration currently in progress, without calling the
92   // callback or reporting an error.
93   void CancelPendingRegistration();
94
95   PrefService* prefs_;
96   scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
97
98   // A |BrowserContextKeyedService| owned by the custodian profile.
99   ManagedUserSyncService* managed_user_sync_service_;
100
101   // A |BrowserContextKeyedService| owned by the custodian profile.
102   ManagedUserSharedSettingsService* managed_user_shared_settings_service_;
103
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_;
110
111   base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_;
112
113   DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl);
114 };
115
116 } // namespace
117
118 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(
119     const base::string16& name,
120     int avatar_index)
121     : avatar_index(avatar_index),
122       name(name) {
123 }
124
125 ScopedTestingManagedUserRegistrationUtility::
126     ScopedTestingManagedUserRegistrationUtility(
127         ManagedUserRegistrationUtility* instance) {
128   ManagedUserRegistrationUtility::SetUtilityForTests(instance);
129 }
130
131 ScopedTestingManagedUserRegistrationUtility::
132     ~ScopedTestingManagedUserRegistrationUtility() {
133   ManagedUserRegistrationUtility::SetUtilityForTests(NULL);
134 }
135
136 // static
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);
143   }
144
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(
151           token_service,
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(
159       profile->GetPrefs(),
160       token_fetcher.Pass(),
161       managed_user_sync_service,
162       managed_user_shared_settings_service));
163 }
164
165 // static
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;
170 }
171
172 // static
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;
178 }
179
180 // static
181 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl(
182       PrefService* prefs,
183       scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
184       ManagedUserSyncService* service,
185       ManagedUserSharedSettingsService* shared_settings_service) {
186   return new ManagedUserRegistrationUtilityImpl(prefs,
187                                                 token_fetcher.Pass(),
188                                                 service,
189                                                 shared_settings_service);
190 }
191
192 namespace {
193
194 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl(
195     PrefService* prefs,
196     scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
197     ManagedUserSyncService* service,
198     ManagedUserSharedSettingsService* shared_settings_service)
199     : prefs_(prefs),
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);
208 }
209
210 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() {
211   managed_user_sync_service_->RemoveObserver(this);
212   CancelPendingRegistration();
213 }
214
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;
222
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),
229                                                info.master_key,
230                                                info.avatar_index);
231   } else {
232     avatar_updated_ =
233         managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded(
234             managed_user_id,
235             info.avatar_index);
236
237     // User already exists, don't wait for acknowledgment.
238     OnManagedUserAcknowledged(managed_user_id);
239   }
240 #if defined(OS_CHROMEOS)
241   const char* kAvatarKey = managed_users::kChromeOSAvatarIndex;
242 #else
243   const char* kAvatarKey = managed_users::kChromeAvatarIndex;
244 #endif
245   managed_user_shared_settings_service_->SetValue(
246       pending_managed_user_id_, kAvatarKey,
247       base::FundamentalValue(info.avatar_index));
248
249   browser_sync::DeviceInfo::GetClientName(
250       base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken,
251                  weak_ptr_factory_.GetWeakPtr()));
252 }
253
254 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
255   AbortPendingRegistration(
256       false,  // Don't run the callback. The error will be ignored.
257       GoogleServiceAuthError(GoogleServiceAuthError::NONE));
258 }
259
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();
266 }
267
268 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
269   AbortPendingRegistration(
270       true,  // Run the callback.
271       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
272 }
273
274 void ManagedUserRegistrationUtilityImpl::OnManagedUsersChanged() {}
275
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()));
282 }
283
284 void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
285     const GoogleServiceAuthError& error,
286     const std::string& token) {
287   if (error.state() != GoogleServiceAuthError::NONE) {
288     CompleteRegistration(true, error);
289     return;
290   }
291
292   DCHECK(!token.empty());
293   pending_managed_user_token_ = token;
294   CompleteRegistrationIfReady();
295 }
296
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())
303     return;
304
305   GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
306   CompleteRegistration(true, error);
307 }
308
309 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
310     bool run_callback,
311     const GoogleServiceAuthError& error) {
312   pending_managed_user_token_.clear();
313   CompleteRegistration(run_callback, error);
314 }
315
316 void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
317     bool run_callback,
318     const GoogleServiceAuthError& error) {
319   if (callback_.is_null())
320     return;
321
322   if (pending_managed_user_token_.empty()) {
323     DCHECK(!pending_managed_user_id_.empty());
324
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_);
336     }
337   }
338
339   if (run_callback)
340     callback_.Run(error, pending_managed_user_token_);
341   callback_.Reset();
342 }
343
344 } // namespace