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/memory/scoped_ptr.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/rand_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
     14 #include "chrome/browser/managed_mode/managed_user_service.h"
     15 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
     16 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
     17 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
     18 #include "chrome/browser/prefs/scoped_user_pref_update.h"
     19 #include "chrome/browser/signin/profile_oauth2_token_service.h"
     20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     21 #include "chrome/browser/sync/glue/device_info.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 const char kAcknowledged[] = "acknowledged";
     29 const char kName[] = "name";
     30 const char kMasterKey[] = "masterKey";
     31 
     32 ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(const string16& name)
     33     : name(name) {
     34 }
     35 
     36 ManagedUserRegistrationUtility::ManagedUserRegistrationUtility(
     37     PrefService* prefs,
     38     scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
     39     ManagedUserSyncService* service)
     40     : weak_ptr_factory_(this),
     41       prefs_(prefs),
     42       token_fetcher_(token_fetcher.Pass()),
     43       managed_user_sync_service_(service),
     44       pending_managed_user_acknowledged_(false),
     45       is_existing_managed_user_(false) {
     46   managed_user_sync_service_->AddObserver(this);
     47 }
     48 
     49 ManagedUserRegistrationUtility::~ManagedUserRegistrationUtility() {
     50   managed_user_sync_service_->RemoveObserver(this);
     51   CancelPendingRegistration();
     52 }
     53 
     54 // static
     55 scoped_ptr<ManagedUserRegistrationUtility>
     56 ManagedUserRegistrationUtility::Create(Profile* profile) {
     57   scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher =
     58       ManagedUserRefreshTokenFetcher::Create(
     59           ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
     60           profile->GetRequestContext());
     61   ManagedUserSyncService* managed_user_sync_service =
     62       ManagedUserSyncServiceFactory::GetForProfile(profile);
     63   return make_scoped_ptr(new ManagedUserRegistrationUtility(
     64       profile->GetPrefs(), token_fetcher.Pass(), managed_user_sync_service));
     65 }
     66 
     67 // static
     68 std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() {
     69   std::string new_managed_user_id;
     70   bool success = base::Base64Encode(base::RandBytesAsString(8),
     71                                     &new_managed_user_id);
     72   DCHECK(success);
     73   return new_managed_user_id;
     74 }
     75 
     76 void ManagedUserRegistrationUtility::Register(
     77     const std::string& managed_user_id,
     78     const ManagedUserRegistrationInfo& info,
     79     const RegistrationCallback& callback) {
     80   DCHECK(pending_managed_user_id_.empty());
     81   callback_ = callback;
     82   pending_managed_user_id_ = managed_user_id;
     83 
     84   const DictionaryValue* dict = prefs_->GetDictionary(prefs::kManagedUsers);
     85   is_existing_managed_user_ = dict->HasKey(managed_user_id);
     86   if (!is_existing_managed_user_) {
     87     managed_user_sync_service_->AddManagedUser(pending_managed_user_id_,
     88                                                base::UTF16ToUTF8(info.name),
     89                                                info.master_key);
     90   } else {
     91     // User already exists, don't wait for acknowledgment.
     92     OnManagedUserAcknowledged(managed_user_id);
     93   }
     94 
     95   browser_sync::DeviceInfo::GetClientName(
     96       base::Bind(&ManagedUserRegistrationUtility::FetchToken,
     97                  weak_ptr_factory_.GetWeakPtr()));
     98 }
     99 
    100 void ManagedUserRegistrationUtility::CancelPendingRegistration() {
    101   AbortPendingRegistration(
    102       false,  // Don't run the callback. The error will be ignored.
    103       GoogleServiceAuthError(GoogleServiceAuthError::NONE));
    104 }
    105 
    106 void ManagedUserRegistrationUtility::OnManagedUserAcknowledged(
    107     const std::string& managed_user_id) {
    108   DCHECK_EQ(pending_managed_user_id_, managed_user_id);
    109   DCHECK(!pending_managed_user_acknowledged_);
    110   pending_managed_user_acknowledged_ = true;
    111   CompleteRegistrationIfReady();
    112 }
    113 
    114 void ManagedUserRegistrationUtility::OnManagedUsersSyncingStopped() {
    115   AbortPendingRegistration(
    116       true,   // Run the callback.
    117       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
    118 }
    119 
    120 void ManagedUserRegistrationUtility::FetchToken(
    121     const std::string& client_name) {
    122   token_fetcher_->Start(
    123       pending_managed_user_id_, client_name,
    124       base::Bind(&ManagedUserRegistrationUtility::OnReceivedToken,
    125                  weak_ptr_factory_.GetWeakPtr()));
    126 }
    127 
    128 void ManagedUserRegistrationUtility::OnReceivedToken(
    129     const GoogleServiceAuthError& error,
    130     const std::string& token) {
    131   if (error.state() != GoogleServiceAuthError::NONE) {
    132     CompleteRegistration(true, error);
    133     return;
    134   }
    135 
    136   DCHECK(!token.empty());
    137   pending_managed_user_token_ = token;
    138   CompleteRegistrationIfReady();
    139 }
    140 
    141 void ManagedUserRegistrationUtility::CompleteRegistrationIfReady() {
    142   if (!pending_managed_user_acknowledged_ ||
    143       pending_managed_user_token_.empty()) {
    144     return;
    145   }
    146 
    147   GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
    148   CompleteRegistration(true, error);
    149 }
    150 
    151 void ManagedUserRegistrationUtility::AbortPendingRegistration(
    152     bool run_callback,
    153     const GoogleServiceAuthError& error) {
    154   pending_managed_user_token_.clear();
    155   CompleteRegistration(run_callback, error);
    156 }
    157 
    158 void ManagedUserRegistrationUtility::CompleteRegistration(
    159     bool run_callback,
    160     const GoogleServiceAuthError& error) {
    161   if (callback_.is_null())
    162     return;
    163 
    164   // We check that the user being registered is not an existing managed
    165   // user before deleting it from sync to avoid accidental deletion of
    166   // existing managed users by just canceling the registration for example.
    167   if (pending_managed_user_token_.empty() && !is_existing_managed_user_) {
    168     DCHECK(!pending_managed_user_id_.empty());
    169     // Remove the pending managed user if we weren't successful.
    170     DictionaryPrefUpdate update(prefs_, prefs::kManagedUsers);
    171     bool success =
    172         update->RemoveWithoutPathExpansion(pending_managed_user_id_, NULL);
    173     DCHECK(success);
    174     managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_);
    175   }
    176 
    177   if (run_callback)
    178     callback_.Run(error, pending_managed_user_token_);
    179   callback_.Reset();
    180 }
    181