Home | History | Annotate | Download | only in managed_mode
      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_refresh_token_fetcher.h"
     15 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
     16 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
     17 #include "chrome/browser/profiles/profile.h"
     18 #include "chrome/browser/signin/profile_oauth2_token_service.h"
     19 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     20 #include "chrome/browser/sync/glue/device_info.h"
     21 #include "chrome/common/chrome_switches.h"
     22 #include "chrome/common/pref_names.h"
     23 #include "google_apis/gaia/gaia_urls.h"
     24 #include "google_apis/gaia/google_service_auth_error.h"
     25 
     26 using base::DictionaryValue;
     27 
     28 namespace {
     29 
     30 ManagedUserRegistrationUtility* g_instance_for_tests = NULL;
     31 
     32 // Actual implementation of ManagedUserRegistrationUtility.
     33 class ManagedUserRegistrationUtilityImpl
     34     : public ManagedUserRegistrationUtility,
     35       public ManagedUserSyncServiceObserver {
     36  public:
     37   ManagedUserRegistrationUtilityImpl(
     38       PrefService* prefs,
     39       scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
     40       ManagedUserSyncService* service);
     41 
     42   virtual ~ManagedUserRegistrationUtilityImpl();
     43 
     44   // Registers a new managed user with the server. |managed_user_id| is a new
     45   // unique ID for the new managed user. If its value is the same as that of
     46   // of one of the existing managed users, then the same user will be created
     47   // on this machine (and if he has no avatar in sync, his avatar will
     48   // be updated). |info| contains necessary information like
     49   // the display name of the user and his avatar. |callback| is called
     50   // with the result of the registration. We use the info here and not the
     51   // profile, because on Chrome OS the profile of the managed user does not
     52   // yet exist.
     53   virtual void Register(const std::string& managed_user_id,
     54                         const ManagedUserRegistrationInfo& info,
     55                         const RegistrationCallback& callback) OVERRIDE;
     56 
     57   // ManagedUserSyncServiceObserver:
     58   virtual void OnManagedUserAcknowledged(const std::string& managed_user_id)
     59       OVERRIDE;
     60   virtual void OnManagedUsersSyncingStopped() OVERRIDE;
     61 
     62  private:
     63   // Fetches the managed user token when we have the device name.
     64   void FetchToken(const std::string& client_name);
     65 
     66   // Called when we have received a token for the managed user.
     67   void OnReceivedToken(const GoogleServiceAuthError& error,
     68                        const std::string& token);
     69 
     70   // Dispatches the callback and cleans up if all the conditions have been met.
     71   void CompleteRegistrationIfReady();
     72 
     73   // Aborts any registration currently in progress. If |run_callback| is true,
     74   // calls the callback specified in Register() with the given |error|.
     75   void AbortPendingRegistration(bool run_callback,
     76                                 const GoogleServiceAuthError& error);
     77 
     78   // If |run_callback| is true, dispatches the callback with the saved token
     79   // (which may be empty) and the given |error|. In any case, resets internal
     80   // variables to be ready for the next registration.
     81   void CompleteRegistration(bool run_callback,
     82                             const GoogleServiceAuthError& error);
     83 
     84   // Cancels any registration currently in progress, without calling the
     85   // callback or reporting an error.
     86   void CancelPendingRegistration();
     87 
     88   PrefService* prefs_;
     89   scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;
     90 
     91   // A |BrowserContextKeyedService| owned by the custodian profile.
     92   ManagedUserSyncService* managed_user_sync_service_;
     93 
     94   std::string pending_managed_user_id_;
     95   std::string pending_managed_user_token_;
     96   bool pending_managed_user_acknowledged_;
     97   bool is_existing_managed_user_;
     98   bool avatar_updated_;
     99   RegistrationCallback callback_;
    100 
    101   base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_;
    102 
    103   DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl);
    104 };
    105 
    106 } // namespace
    107 
    108 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(
    109     const base::string16& name,
    110     int avatar_index)
    111     : avatar_index(avatar_index),
    112       name(name) {
    113 }
    114 
    115 ScopedTestingManagedUserRegistrationUtility::
    116     ScopedTestingManagedUserRegistrationUtility(
    117         ManagedUserRegistrationUtility* instance) {
    118   ManagedUserRegistrationUtility::SetUtilityForTests(instance);
    119 }
    120 
    121 ScopedTestingManagedUserRegistrationUtility::
    122     ~ScopedTestingManagedUserRegistrationUtility() {
    123   ManagedUserRegistrationUtility::SetUtilityForTests(NULL);
    124 }
    125 
    126 // static
    127 scoped_ptr<ManagedUserRegistrationUtility>
    128 ManagedUserRegistrationUtility::Create(Profile* profile) {
    129   if (g_instance_for_tests) {
    130     ManagedUserRegistrationUtility* result = g_instance_for_tests;
    131     g_instance_for_tests = NULL;
    132     return make_scoped_ptr(result);
    133   }
    134 
    135   ProfileOAuth2TokenService* token_service =
    136       ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
    137   scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher =
    138       ManagedUserRefreshTokenFetcher::Create(
    139           token_service,
    140           token_service->GetPrimaryAccountId(),
    141           profile->GetRequestContext());
    142   ManagedUserSyncService* managed_user_sync_service =
    143       ManagedUserSyncServiceFactory::GetForProfile(profile);
    144   return make_scoped_ptr(ManagedUserRegistrationUtility::CreateImpl(
    145       profile->GetPrefs(),
    146       token_fetcher.Pass(),
    147       managed_user_sync_service));
    148 }
    149 
    150 // static
    151 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() {
    152   std::string new_managed_user_id;
    153   base::Base64Encode(base::RandBytesAsString(8), &new_managed_user_id);
    154   return new_managed_user_id;
    155 }
    156 
    157 // static
    158 void ManagedUserRegistrationUtility::SetUtilityForTests(
    159     ManagedUserRegistrationUtility* utility) {
    160   if (g_instance_for_tests)
    161     delete g_instance_for_tests;
    162   g_instance_for_tests = utility;
    163 }
    164 
    165 // static
    166 ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl(
    167       PrefService* prefs,
    168       scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
    169       ManagedUserSyncService* service) {
    170   return new ManagedUserRegistrationUtilityImpl(prefs,
    171                                                 token_fetcher.Pass(),
    172                                                 service);
    173 }
    174 
    175 namespace {
    176 
    177 ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl(
    178     PrefService* prefs,
    179     scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
    180     ManagedUserSyncService* service)
    181     : prefs_(prefs),
    182       token_fetcher_(token_fetcher.Pass()),
    183       managed_user_sync_service_(service),
    184       pending_managed_user_acknowledged_(false),
    185       is_existing_managed_user_(false),
    186       avatar_updated_(false),
    187       weak_ptr_factory_(this) {
    188   managed_user_sync_service_->AddObserver(this);
    189 }
    190 
    191 ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() {
    192   managed_user_sync_service_->RemoveObserver(this);
    193   CancelPendingRegistration();
    194 }
    195 
    196 void ManagedUserRegistrationUtilityImpl::Register(
    197     const std::string& managed_user_id,
    198     const ManagedUserRegistrationInfo& info,
    199     const RegistrationCallback& callback) {
    200   DCHECK(pending_managed_user_id_.empty());
    201   callback_ = callback;
    202   pending_managed_user_id_ = managed_user_id;
    203 
    204   const DictionaryValue* dict = prefs_->GetDictionary(prefs::kManagedUsers);
    205   is_existing_managed_user_ = dict->HasKey(managed_user_id);
    206   if (!is_existing_managed_user_) {
    207     managed_user_sync_service_->AddManagedUser(pending_managed_user_id_,
    208                                                base::UTF16ToUTF8(info.name),
    209                                                info.master_key,
    210                                                info.avatar_index);
    211   } else {
    212     avatar_updated_ =
    213         managed_user_sync_service_->UpdateManagedUserAvatarIfNeeded(
    214             managed_user_id,
    215             info.avatar_index);
    216 
    217     // User already exists, don't wait for acknowledgment.
    218     OnManagedUserAcknowledged(managed_user_id);
    219   }
    220 
    221   browser_sync::DeviceInfo::GetClientName(
    222       base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken,
    223                  weak_ptr_factory_.GetWeakPtr()));
    224 }
    225 
    226 void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
    227   AbortPendingRegistration(
    228       false,  // Don't run the callback. The error will be ignored.
    229       GoogleServiceAuthError(GoogleServiceAuthError::NONE));
    230 }
    231 
    232 void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged(
    233     const std::string& managed_user_id) {
    234   DCHECK_EQ(pending_managed_user_id_, managed_user_id);
    235   DCHECK(!pending_managed_user_acknowledged_);
    236   pending_managed_user_acknowledged_ = true;
    237   CompleteRegistrationIfReady();
    238 }
    239 
    240 void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
    241   AbortPendingRegistration(
    242       true,  // Run the callback.
    243       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
    244 }
    245 
    246 void ManagedUserRegistrationUtilityImpl::FetchToken(
    247     const std::string& client_name) {
    248   token_fetcher_->Start(
    249       pending_managed_user_id_, client_name,
    250       base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken,
    251                  weak_ptr_factory_.GetWeakPtr()));
    252 }
    253 
    254 void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
    255     const GoogleServiceAuthError& error,
    256     const std::string& token) {
    257   if (error.state() != GoogleServiceAuthError::NONE) {
    258     CompleteRegistration(true, error);
    259     return;
    260   }
    261 
    262   DCHECK(!token.empty());
    263   pending_managed_user_token_ = token;
    264   CompleteRegistrationIfReady();
    265 }
    266 
    267 void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
    268   bool require_acknowledgment =
    269       !pending_managed_user_acknowledged_ &&
    270       !CommandLine::ForCurrentProcess()->HasSwitch(
    271           switches::kNoManagedUserAcknowledgmentCheck);
    272   if (require_acknowledgment || pending_managed_user_token_.empty())
    273     return;
    274 
    275   GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
    276   CompleteRegistration(true, error);
    277 }
    278 
    279 void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
    280     bool run_callback,
    281     const GoogleServiceAuthError& error) {
    282   pending_managed_user_token_.clear();
    283   CompleteRegistration(run_callback, error);
    284 }
    285 
    286 void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
    287     bool run_callback,
    288     const GoogleServiceAuthError& error) {
    289   if (callback_.is_null())
    290     return;
    291 
    292   if (pending_managed_user_token_.empty()) {
    293     DCHECK(!pending_managed_user_id_.empty());
    294 
    295     if (!is_existing_managed_user_) {
    296       // Remove the pending managed user if we weren't successful.
    297       // However, check that we are not importing a managed user
    298       // before deleting it from sync to avoid accidental deletion of
    299       // existing managed users by just canceling the registration for example.
    300       managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_);
    301     } else if (avatar_updated_) {
    302       // Canceling (or failing) a managed user import that did set the avatar
    303       // should undo this change.
    304       managed_user_sync_service_->ClearManagedUserAvatar(
    305           pending_managed_user_id_);
    306     }
    307   }
    308 
    309   if (run_callback)
    310     callback_.Run(error, pending_managed_user_token_);
    311   callback_.Reset();
    312 }
    313 
    314 } // namespace
    315