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