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