Commit a8fa4cae authored by rsimha@chromium.org's avatar rsimha@chromium.org

[sync] Auto-heal sync credential cache on startup, and no longer rely on NOTIFICATION_PREF_CHANGED

CredentialCacheService listens for initial sync configuration during
sign in by directly observing sync preferences in the pref store. This
is not good because sync preferences are not always re-written
during sign in, and we cannot rely on NOTIFICATION_PREF_CHANGED.

In addition, if during startup, we find an older version of a credential
cache with some fields missing (like the last_updated_time), we could
run into bugs due to the missing fields.

This patch does the following:

1) Makes CredentialCacheService listen to the notification
   NOTIFICATION_SYNC_CONFIGURE_START for sign-in, restart and
   reconfigure scenarios.
2) No longer relies on NOTIFICATION_PREF_CHANGED for detecting
   changes to sync datatype preferences.
2) Freshly writes any missing sync credentials during startup to
   auto-heal the cache in case chrome crashed during a previous run,
   or if a signed-in user upgraded chrome from an older version that
   didn't support credential caching or was missing some newer fields.
3) Adds caching support for both sync encryption tokens:
   kSyncEncryptionBootstrapToken and kSyncKeystoreEncryptionBootstrapToken,
   and makes the required logic changes to sign in / reconfigure with
   one or the other.
4) Modifies PackAndUpdateStringPref and UpdateBooleanPref to only
   update the cache if the new value being written is different from the
   existing value.
5) Other misc. changes to support the design described above.

BUG=142550, 143214
TEST=Sign in to sync, sign out, exit chrome, delete the credential cache from the profile directory or merely delete some fields, and sign in again. All sync preferences must get written to the credential cache.

Review URL: https://chromiumcodereview.appspot.com/10829310

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152157 0039d316-1c4b-4281-b951-d872f2087c98
parent 3295f031
...@@ -56,12 +56,9 @@ class CredentialCacheService : public ProfileKeyedService, ...@@ -56,12 +56,9 @@ class CredentialCacheService : public ProfileKeyedService,
// to the local profile if the load was successful. // to the local profile if the load was successful.
void ReadCachedCredentialsFromAlternateProfile(); void ReadCachedCredentialsFromAlternateProfile();
// Populates a new local credential cache file if the user is already signed // Writes kSyncKeepEverythingSynced and the sync preferences for individual
// in to the local profile, and there is no existing local credential cache. // datatypes to the local cache.
// Used in scenarios where a user upgraded from an older version of Chrome void WriteSyncPrefsToLocalCache();
// that didn't support credential caching. This method is a no-op if local
// sync prefs have already been written to the local cache.
void WriteExistingSyncPrefsToLocalCache();
// Resets |alternate_store_| and schedules the next read from the alternate // Resets |alternate_store_| and schedules the next read from the alternate
// credential cache. // credential cache.
...@@ -87,12 +84,15 @@ class CredentialCacheService : public ProfileKeyedService, ...@@ -87,12 +84,15 @@ class CredentialCacheService : public ProfileKeyedService,
void WriteLastUpdatedTime(); void WriteLastUpdatedTime();
// Updates the value of |pref_name| to |new_value|, unless the user has signed // Updates the value of |pref_name| to |new_value|, unless the user has signed
// out, in which case we write an empty string value to |pref_name|. // out, in which case we write an empty string value to |pref_name|. This
// method is a no-op if |new_value| is the same as the value found in the
// local cache.
void PackAndUpdateStringPref(const std::string& pref_name, void PackAndUpdateStringPref(const std::string& pref_name,
const std::string& new_value); const std::string& new_value);
// Updates the value of |pref_name| to |new_value|, unless the user has signed // Updates the value of |pref_name| to |new_value|, unless the user has signed
// out, in which case we write "false" to |pref_name|. // out, in which case we write "false" to |pref_name|. This method is a no-op
// if |new_value| is the same as the value found in the local cache.
void UpdateBooleanPref(const std::string& pref_name, bool new_value); void UpdateBooleanPref(const std::string& pref_name, bool new_value);
// Returns the time at which the credential cache represented by |store| was // Returns the time at which the credential cache represented by |store| was
...@@ -181,6 +181,10 @@ class CredentialCacheService : public ProfileKeyedService, ...@@ -181,6 +181,10 @@ class CredentialCacheService : public ProfileKeyedService,
// Initializes the JsonPrefStore object for the local profile directory. // Initializes the JsonPrefStore object for the local profile directory.
void InitializeLocalCredentialCacheWriter(); void InitializeLocalCredentialCacheWriter();
// Registers for notifications for events like sync sign in, sign out,
// (re)configuration, encryption and changes to the token service credentials.
void StartListeningForSyncConfigChanges();
// Returns true if there is an empty value for kGoogleServicesUsername in the // Returns true if there is an empty value for kGoogleServicesUsername in the
// credential cache for the local profile (indicating that the user first // credential cache for the local profile (indicating that the user first
// signed in and then signed out). Returns false if there's no value at all // signed in and then signed out). Returns false if there's no value at all
...@@ -196,59 +200,76 @@ class CredentialCacheService : public ProfileKeyedService, ...@@ -196,59 +200,76 @@ class CredentialCacheService : public ProfileKeyedService,
// Initiates sync sign in using credentials read from the alternate profile by // Initiates sync sign in using credentials read from the alternate profile by
// persisting |google_services_username|, |encryption_bootstrap_token|, // persisting |google_services_username|, |encryption_bootstrap_token|,
// |keep_everything_synced| and |preferred_types| to the local pref store, and // |keystore_encryption_bootstrap_token|, |keep_everything_synced| and
// preparing ProfileSyncService for sign in. // |preferred_types| to the local pref store, and preparing ProfileSyncService
// for sign in.
void InitiateSignInWithCachedCredentials( void InitiateSignInWithCachedCredentials(
const std::string& google_services_username, const std::string& google_services_username,
const std::string& encryption_bootstrap_token, const std::string& encryption_bootstrap_token,
const std::string& keystore_encryption_bootstrap_token,
bool keep_everything_synced, bool keep_everything_synced,
ModelTypeSet preferred_types); ModelTypeSet preferred_types);
// Updates the TokenService credentials with |lsid| and |sid| and triggers the // Updates the TokenService credentials with |alternate_lsid| and
// minting of new tokens for all Chrome services. ProfileSyncService is // |alternate_sid| and triggers the minting of new tokens for all Chrome
// automatically notified when tokens are minted, and goes on to consume the // services. ProfileSyncService is automatically notified when tokens are
// updated credentials. // minted, and goes on to consume the updated credentials.
void UpdateTokenServiceCredentials(const std::string& lsid, void UpdateTokenServiceCredentials(const std::string& alternate_lsid,
const std::string& sid); const std::string& alternate_sid);
// Initiates a sign out of sync. Called when we notice that the user has // Initiates a sign out of sync. Called when we notice that the user has
// signed out from the alternate mode by reading its credential cache. // signed out from the alternate mode by reading its credential cache.
void InitiateSignOut(); void InitiateSignOut();
// Compares the sync preferences in the local profile with values that were // Compares the sync preferences in the local profile with values that were
// read from the alternate profile -- |keep_everything_synced| and // read from the alternate profile -- |alternate_keep_everything_synced| and
// |preferred_types|. Returns true if the prefs have changed, and false // |alternate_preferred_types|. Returns true if the prefs have changed, and
// otherwise. // false otherwise.
bool HaveSyncPrefsChanged(bool keep_everything_synced, bool HaveSyncPrefsChanged(bool alternate_keep_everything_synced,
ModelTypeSet preferred_types) const; ModelTypeSet alternate_preferred_types) const;
// Compares the sync encryption tokens in the local profile with values that
// were read from the alternate profile --
// |alternate_encryption_bootstrap_token| and
// |alternate_keystore_encryption_bootstrap_token|. Returns true if the tokens
// have changed, and false otherwise.
bool HaveSyncEncryptionTokensChanged(
const std::string& alternate_encryption_bootstrap_token,
const std::string& alternate_keystore_encryption_bootstrap_token);
// Compares the token service credentials in the local profile with values // Compares the token service credentials in the local profile with values
// that were read from the alternate profile -- |lsid| and |sid|. Returns true // that were read from the alternate profile -- |alternate_lsid| and
// if the credentials have changed, and false otherwise. // |alternate_sid|. Returns true if the credentials have changed, and false
bool HaveTokenServiceCredentialsChanged(const std::string& lsid, // otherwise.
const std::string& sid); bool HaveTokenServiceCredentialsChanged(const std::string& alternate_lsid,
const std::string& alternate_sid);
// Determines if the user must be signed out of the local profile or not. // Determines if the user must be signed out of the local profile or not.
// Called when updated settings are noticed in the alternate credential cache // Called when updated settings are noticed in the alternate credential cache
// for |google_services_username|. Returns true if we should sign out, and // for |alternate_google_services_username|. Returns true if we should sign
// false if not. // out, and false if not.
bool ShouldSignOutOfSync(const std::string& google_services_username); bool ShouldSignOutOfSync(
const std::string& alternate_google_services_username);
// Determines if sync settings may be reconfigured or not. Called when // Determines if sync settings may be reconfigured or not. Called when
// updated settings are noticed in the alternate credential cache for // updated settings are noticed in the alternate credential cache for
// |google_services_username|. Returns true if we may reconfigure, and false // |alternate_google_services_username|. Returns true if we may reconfigure,
// if not. // and false if not.
bool MayReconfigureSync(const std::string& google_services_username); bool MayReconfigureSync(
const std::string& alternate_google_services_username);
// Determines if the user must be signed in to the local profile or not. // Determines if the user must be signed in to the local profile or not.
// Called when updated settings are noticed in the alternate credential cache // Called when updated settings are noticed in the alternate credential cache
// for |google_services_username|, with new values for |lsid|, |sid| and // for |alternate_google_services_username|, with new values for
// |encryption_bootstrap_token|. Returns true if we should sign in, and // |alternate_lsid|, |alternate_sid|, |alternate_encryption_bootstrap_token|
// false if not. // and |alternate_keystore_encryption_bootstrap_token|. Returns true if we
bool ShouldSignInToSync(const std::string& google_services_username, // should sign in, and false if not.
const std::string& lsid, bool ShouldSignInToSync(
const std::string& sid, const std::string& alternate_google_services_username,
const std::string& encryption_bootstrap_token); const std::string& alternate_lsid,
const std::string& alternate_sid,
const std::string& alternate_encryption_bootstrap_token,
const std::string& alternate_keystore_encryption_bootstrap_token);
// Profile for which credentials are being cached. // Profile for which credentials are being cached.
Profile* profile_; Profile* profile_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment