Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: chrome/browser/sync/profile_sync_service.cc

Issue 6902101: Refactor sync passphrase setup flow and fix passphrase tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: de Morgan's law simplification. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/profile_sync_service.h" 5 #include "chrome/browser/sync/profile_sync_service.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <map> 8 #include <map>
9 #include <ostream> 9 #include <ostream>
10 #include <set> 10 #include <set>
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 const char* ProfileSyncService::kDevServerUrl = 62 const char* ProfileSyncService::kDevServerUrl =
63 "https://clients4.google.com/chrome-sync/dev"; 63 "https://clients4.google.com/chrome-sync/dev";
64 64
65 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. 65 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute.
66 66
67 ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory, 67 ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory,
68 Profile* profile, 68 Profile* profile,
69 const std::string& cros_user) 69 const std::string& cros_user)
70 : last_auth_error_(AuthError::None()), 70 : last_auth_error_(AuthError::None()),
71 observed_passphrase_required_(false), 71 passphrase_required_reason_(sync_api::REASON_PASSPHRASE_NOT_REQUIRED),
72 passphrase_required_for_decryption_(false),
73 passphrase_migration_in_progress_(false), 72 passphrase_migration_in_progress_(false),
74 factory_(factory), 73 factory_(factory),
75 profile_(profile), 74 profile_(profile),
76 cros_user_(cros_user), 75 cros_user_(cros_user),
77 sync_service_url_(kDevServerUrl), 76 sync_service_url_(kDevServerUrl),
78 backend_initialized_(false), 77 backend_initialized_(false),
79 is_auth_in_progress_(false), 78 is_auth_in_progress_(false),
80 wizard_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 79 wizard_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
81 unrecoverable_error_detected_(false), 80 unrecoverable_error_detected_(false),
82 scoped_runnable_method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 81 scoped_runnable_method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 scoped_ptr<SyncBackendHost> doomed_backend(backend_.release()); 371 scoped_ptr<SyncBackendHost> doomed_backend(backend_.release());
373 if (doomed_backend.get()) { 372 if (doomed_backend.get()) {
374 doomed_backend->Shutdown(sync_disabled); 373 doomed_backend->Shutdown(sync_disabled);
375 374
376 doomed_backend.reset(); 375 doomed_backend.reset();
377 } 376 }
378 377
379 // Clear various flags. 378 // Clear various flags.
380 is_auth_in_progress_ = false; 379 is_auth_in_progress_ = false;
381 backend_initialized_ = false; 380 backend_initialized_ = false;
382 observed_passphrase_required_ = false; 381 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED;
383 last_attempted_user_email_.clear(); 382 last_attempted_user_email_.clear();
384 last_auth_error_ = GoogleServiceAuthError::None(); 383 last_auth_error_ = GoogleServiceAuthError::None();
385 } 384 }
386 385
387 void ProfileSyncService::ClearServerData() { 386 void ProfileSyncService::ClearServerData() {
388 clear_server_data_state_ = CLEAR_CLEARING; 387 clear_server_data_state_ = CLEAR_CLEARING;
389 clear_server_data_timer_.Start( 388 clear_server_data_timer_.Start(
390 base::TimeDelta::FromSeconds(kSyncClearDataTimeoutInSeconds), this, 389 base::TimeDelta::FromSeconds(kSyncClearDataTimeoutInSeconds), this,
391 &ProfileSyncService::OnClearServerDataTimeout); 390 &ProfileSyncService::OnClearServerDataTimeout);
392 backend_->RequestClearServerData(); 391 backend_->RequestClearServerData();
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 clear_server_data_timer_.Stop(); 584 clear_server_data_timer_.Stop();
586 585
587 // Even if the timout fired, we still transition to the succeeded state as 586 // Even if the timout fired, we still transition to the succeeded state as
588 // we want UI to update itself and no longer allow the user to press "clear" 587 // we want UI to update itself and no longer allow the user to press "clear"
589 if (clear_server_data_state_ != CLEAR_SUCCEEDED) { 588 if (clear_server_data_state_ != CLEAR_SUCCEEDED) {
590 clear_server_data_state_ = CLEAR_SUCCEEDED; 589 clear_server_data_state_ = CLEAR_SUCCEEDED;
591 NotifyObservers(); 590 NotifyObservers();
592 } 591 }
593 } 592 }
594 593
595 void ProfileSyncService::OnPassphraseRequired(bool for_decryption) { 594 void ProfileSyncService::OnPassphraseRequired(
595 sync_api::PassphraseRequiredReason reason) {
596 DCHECK(backend_.get()); 596 DCHECK(backend_.get());
597 DCHECK(backend_->IsNigoriEnabled()); 597 DCHECK(backend_->IsNigoriEnabled());
598 598
599 // TODO(lipalani) : add this check to other locations as well. 599 // TODO(lipalani) : add this check to other locations as well.
600 if (unrecoverable_error_detected_) { 600 if (unrecoverable_error_detected_) {
601 // When unrecoverable error is detected we post a task to shutdown the 601 // When unrecoverable error is detected we post a task to shutdown the
602 // backend. The task might not have executed yet. 602 // backend. The task might not have executed yet.
603 return; 603 return;
604 } 604 }
605 observed_passphrase_required_ = true; 605
606 passphrase_required_for_decryption_ = for_decryption; 606 passphrase_required_reason_ = reason;
607 607
608 if (!cached_passphrase_.value.empty()) { 608 if (!cached_passphrase_.value.empty()) {
609 SetPassphrase(cached_passphrase_.value, 609 SetPassphrase(cached_passphrase_.value,
610 cached_passphrase_.is_explicit, 610 cached_passphrase_.is_explicit,
611 cached_passphrase_.is_creation); 611 cached_passphrase_.is_creation);
612 cached_passphrase_ = CachedPassphrase(); 612 cached_passphrase_ = CachedPassphrase();
613 return; 613 return;
614 } 614 }
615 615
616 // We will skip the passphrase prompt and suppress the warning 616 // We will skip the passphrase prompt and suppress the warning if the
617 // if the passphrase is needed for decryption but the user is 617 // passphrase is needed for decryption but the user is not syncing an
618 // not syncing an encrypted data type on this machine. 618 // encrypted data type on this machine. Otherwise we prompt.
619 // Otherwise we prompt. 619 if (!IsEncryptedDatatypeEnabled() &&
620 if (!IsEncryptedDatatypeEnabled() && for_decryption) { 620 (reason == sync_api::REASON_DECRYPTION ||
621 reason == sync_api::REASON_SET_PASSPHRASE_FAILED)) {
621 OnPassphraseAccepted(); 622 OnPassphraseAccepted();
622 return; 623 return;
623 } 624 }
624 625
625 if (WizardIsVisible() && for_decryption) { 626 if (WizardIsVisible() &&
627 (reason == sync_api::REASON_DECRYPTION ||
628 reason == sync_api::REASON_SET_PASSPHRASE_FAILED)) {
626 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); 629 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE);
627 } 630 }
628 631
629 NotifyObservers(); 632 NotifyObservers();
630 } 633 }
631 634
632 void ProfileSyncService::OnPassphraseAccepted() { 635 void ProfileSyncService::OnPassphraseAccepted() {
633 // Make sure the data types that depend on the passphrase are started at 636 // Make sure the data types that depend on the passphrase are started at
634 // this time. 637 // this time.
635 syncable::ModelTypeSet types; 638 syncable::ModelTypeSet types;
636 GetPreferredDataTypes(&types); 639 GetPreferredDataTypes(&types);
637 // Reset "passphrase_required" flag before configuring the DataTypeManager 640
641 // Reset passphrase_required_reason_ before configuring the DataTypeManager
638 // since we know we no longer require the passphrase. 642 // since we know we no longer require the passphrase.
639 observed_passphrase_required_ = false; 643 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED;
644
640 if (data_type_manager_.get()) 645 if (data_type_manager_.get())
641 data_type_manager_->Configure(types); 646 data_type_manager_->Configure(types);
642 647
643 NotifyObservers(); 648 NotifyObservers();
644 649
645 wizard_.Step(SyncSetupWizard::DONE); 650 wizard_.Step(SyncSetupWizard::DONE);
646 } 651 }
647 652
648 void ProfileSyncService::OnEncryptionComplete( 653 void ProfileSyncService::OnEncryptionComplete(
649 const syncable::ModelTypeSet& encrypted_types) { 654 const syncable::ModelTypeSet& encrypted_types) {
(...skipping 27 matching lines...) Expand all
677 base::TimeTicks::Now() - auth_error_time_); 682 base::TimeTicks::Now() - auth_error_time_);
678 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null. 683 auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null.
679 } 684 }
680 685
681 wizard_.Step(SyncSetupWizard::GAIA_LOGIN); 686 wizard_.Step(SyncSetupWizard::GAIA_LOGIN);
682 687
683 NotifyObservers(); 688 NotifyObservers();
684 } 689 }
685 690
686 void ProfileSyncService::ShowErrorUI(gfx::NativeWindow parent_window) { 691 void ProfileSyncService::ShowErrorUI(gfx::NativeWindow parent_window) {
687 if (observed_passphrase_required()) { 692 if (ObservedPassphraseRequired()) {
688 if (IsUsingSecondaryPassphrase()) 693 if (IsUsingSecondaryPassphrase())
689 PromptForExistingPassphrase(parent_window); 694 PromptForExistingPassphrase(parent_window);
690 else 695 else
691 SigninForPassphraseMigration(parent_window); 696 SigninForPassphraseMigration(parent_window);
692 return; 697 return;
693 } 698 }
694 const GoogleServiceAuthError& error = GetAuthError(); 699 const GoogleServiceAuthError& error = GetAuthError();
695 if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS || 700 if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
696 error.state() == GoogleServiceAuthError::CAPTCHA_REQUIRED || 701 error.state() == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
697 error.state() == GoogleServiceAuthError::ACCOUNT_DELETED || 702 error.state() == GoogleServiceAuthError::ACCOUNT_DELETED ||
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 for (DataTypeController::TypeMap::const_iterator it = 938 for (DataTypeController::TypeMap::const_iterator it =
934 data_type_controllers_.begin(); 939 data_type_controllers_.begin();
935 it != data_type_controllers_.end(); ++it) { 940 it != data_type_controllers_.end(); ++it) {
936 registered_types->insert((*it).first); 941 registered_types->insert((*it).first);
937 } 942 }
938 } 943 }
939 944
940 bool ProfileSyncService::IsUsingSecondaryPassphrase() const { 945 bool ProfileSyncService::IsUsingSecondaryPassphrase() const {
941 return backend_.get() && (backend_->IsUsingExplicitPassphrase() || 946 return backend_.get() && (backend_->IsUsingExplicitPassphrase() ||
942 (tried_implicit_gaia_remove_when_bug_62103_fixed_ && 947 (tried_implicit_gaia_remove_when_bug_62103_fixed_ &&
943 observed_passphrase_required_)); 948 ObservedPassphraseRequired()));
944 } 949 }
945 950
946 bool ProfileSyncService::IsCryptographerReady( 951 bool ProfileSyncService::IsCryptographerReady(
947 const sync_api::BaseTransaction* trans) const { 952 const sync_api::BaseTransaction* trans) const {
948 return backend_.get() && backend_->IsCryptographerReady(trans); 953 return backend_.get() && backend_->IsCryptographerReady(trans);
949 } 954 }
950 955
951 SyncBackendHost* ProfileSyncService::GetBackendForTest() { 956 SyncBackendHost* ProfileSyncService::GetBackendForTest() {
952 // We don't check |backend_initialized_|; we assume the test class 957 // We don't check |backend_initialized_|; we assume the test class
953 // knows what it's doing. 958 // knows what it's doing.
(...skipping 20 matching lines...) Expand all
974 syncable::ModelTypeSet types; 979 syncable::ModelTypeSet types;
975 GetPreferredDataTypes(&types); 980 GetPreferredDataTypes(&types);
976 // We set this special case here since it's the only datatype whose encryption 981 // We set this special case here since it's the only datatype whose encryption
977 // status we already know. All others are set after the initial sync 982 // status we already know. All others are set after the initial sync
978 // completes (for now). 983 // completes (for now).
979 // TODO(zea): Implement a better way that uses preferences for which types 984 // TODO(zea): Implement a better way that uses preferences for which types
980 // need encryption. 985 // need encryption.
981 encrypted_types_.clear(); 986 encrypted_types_.clear();
982 if (types.count(syncable::PASSWORDS) > 0) 987 if (types.count(syncable::PASSWORDS) > 0)
983 encrypted_types_.insert(syncable::PASSWORDS); 988 encrypted_types_.insert(syncable::PASSWORDS);
984 if (observed_passphrase_required_ && passphrase_required_for_decryption_) { 989 if (passphrase_required_reason_ == sync_api::REASON_DECRYPTION ||
990 passphrase_required_reason_ == sync_api::REASON_SET_PASSPHRASE_FAILED) {
985 if (IsEncryptedDatatypeEnabled()) { 991 if (IsEncryptedDatatypeEnabled()) {
986 // We need a passphrase still. Prompt the user for a passphrase, and 992 // We need a passphrase still. Prompt the user for a passphrase, and
987 // DataTypeManager::Configure() will get called once the passphrase is 993 // DataTypeManager::Configure() will get called once the passphrase is
988 // accepted. 994 // accepted.
989 OnPassphraseRequired(true); 995 OnPassphraseRequired(passphrase_required_reason_);
990 return; 996 return;
991 } else { 997 } else {
992 // We've been informed that a passphrase is required for decryption, but 998 // We've been informed that a passphrase is required for decryption, but
993 // now there are no encrypted data types enabled, so clear the flag 999 // now there are no encrypted data types enabled, so change the value of
994 // (NotifyObservers() will be called when configuration completes). 1000 // passphrase_required_reason_ to its default value. (NotifyObservers()
995 observed_passphrase_required_ = false; 1001 // will be called when configuration completes).
1002 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED;
996 } 1003 }
997 } 1004 }
998 data_type_manager_->Configure(types); 1005 data_type_manager_->Configure(types);
999 } 1006 }
1000 1007
1001 sync_api::UserShare* ProfileSyncService::GetUserShare() const { 1008 sync_api::UserShare* ProfileSyncService::GetUserShare() const {
1002 if (backend_.get() && backend_initialized_) { 1009 if (backend_.get() && backend_initialized_) {
1003 return backend_->GetUserShare(); 1010 return backend_->GetUserShare();
1004 } 1011 }
1005 NOTREACHED(); 1012 NOTREACHED();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 DataTypeController* data_type_controller, 1098 DataTypeController* data_type_controller,
1092 ChangeProcessor* change_processor) { 1099 ChangeProcessor* change_processor) {
1093 change_processor->Stop(); 1100 change_processor->Stop();
1094 if (backend_.get()) 1101 if (backend_.get())
1095 backend_->DeactivateDataType(data_type_controller, change_processor); 1102 backend_->DeactivateDataType(data_type_controller, change_processor);
1096 } 1103 }
1097 1104
1098 void ProfileSyncService::SetPassphrase(const std::string& passphrase, 1105 void ProfileSyncService::SetPassphrase(const std::string& passphrase,
1099 bool is_explicit, 1106 bool is_explicit,
1100 bool is_creation) { 1107 bool is_creation) {
1101 if (ShouldPushChanges() || observed_passphrase_required_) { 1108 if (ShouldPushChanges() || ObservedPassphraseRequired()) {
1102 backend_->SetPassphrase(passphrase, is_explicit); 1109 backend_->SetPassphrase(passphrase, is_explicit);
1103 } else { 1110 } else {
1104 cached_passphrase_.value = passphrase; 1111 cached_passphrase_.value = passphrase;
1105 cached_passphrase_.is_explicit = is_explicit; 1112 cached_passphrase_.is_explicit = is_explicit;
1106 cached_passphrase_.is_creation = is_creation; 1113 cached_passphrase_.is_creation = is_creation;
1107 } 1114 }
1108 } 1115 }
1109 1116
1110 void ProfileSyncService::EncryptDataTypes( 1117 void ProfileSyncService::EncryptDataTypes(
1111 const syncable::ModelTypeSet& encrypted_types) { 1118 const syncable::ModelTypeSet& encrypted_types) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 if (!cached_passphrase_.value.empty()) { 1154 if (!cached_passphrase_.value.empty()) {
1148 // Don't hold on to the passphrase in raw form longer than needed. 1155 // Don't hold on to the passphrase in raw form longer than needed.
1149 SetPassphrase(cached_passphrase_.value, 1156 SetPassphrase(cached_passphrase_.value,
1150 cached_passphrase_.is_explicit, 1157 cached_passphrase_.is_explicit,
1151 cached_passphrase_.is_creation); 1158 cached_passphrase_.is_creation);
1152 cached_passphrase_ = CachedPassphrase(); 1159 cached_passphrase_ = CachedPassphrase();
1153 } 1160 }
1154 1161
1155 // We should never get in a state where we have no encrypted datatypes 1162 // We should never get in a state where we have no encrypted datatypes
1156 // enabled, and yet we still think we require a passphrase. 1163 // enabled, and yet we still think we require a passphrase.
1157 DCHECK(!(observed_passphrase_required_ && 1164 DCHECK(passphrase_required_reason_ ==
1158 passphrase_required_for_decryption_ && 1165 sync_api::REASON_PASSPHRASE_NOT_REQUIRED ||
1159 !IsEncryptedDatatypeEnabled())); 1166 passphrase_required_reason_ == sync_api::REASON_ENCRYPTION ||
1167 IsEncryptedDatatypeEnabled());
1160 1168
1161 // TODO(sync): Less wizard, more toast. 1169 // TODO(sync): Less wizard, more toast.
1162 wizard_.Step(SyncSetupWizard::DONE); 1170 wizard_.Step(SyncSetupWizard::DONE);
1163 NotifyObservers(); 1171 NotifyObservers();
1164 1172
1165 // In the old world, this would be a no-op. With new syncer thread, 1173 // In the old world, this would be a no-op. With new syncer thread,
1166 // this is the point where it is safe to switch from config-mode to 1174 // this is the point where it is safe to switch from config-mode to
1167 // normal operation. 1175 // normal operation.
1168 backend_->StartSyncingWithServer(); 1176 backend_->StartSyncingWithServer();
1169 break; 1177 break;
(...skipping 25 matching lines...) Expand all
1195 // request and shouldn't override an explicit one. Thus, we either 1203 // request and shouldn't override an explicit one. Thus, we either
1196 // update the implicit passphrase (idempotent if the passphrase didn't 1204 // update the implicit passphrase (idempotent if the passphrase didn't
1197 // actually change), or the user has an explicit passphrase set so this 1205 // actually change), or the user has an explicit passphrase set so this
1198 // becomes a no-op. 1206 // becomes a no-op.
1199 tried_implicit_gaia_remove_when_bug_62103_fixed_ = true; 1207 tried_implicit_gaia_remove_when_bug_62103_fixed_ = true;
1200 SetPassphrase(successful->password, false, true); 1208 SetPassphrase(successful->password, false, true);
1201 1209
1202 // If this signin was to initiate a passphrase migration (on the 1210 // If this signin was to initiate a passphrase migration (on the
1203 // first computer, thus not for decryption), continue the migration. 1211 // first computer, thus not for decryption), continue the migration.
1204 if (passphrase_migration_in_progress_ && 1212 if (passphrase_migration_in_progress_ &&
1205 !passphrase_required_for_decryption_) { 1213 passphrase_required_reason_ != sync_api::REASON_DECRYPTION &&
1214 passphrase_required_reason_ !=
1215 sync_api::REASON_SET_PASSPHRASE_FAILED) {
1206 wizard_.Step(SyncSetupWizard::PASSPHRASE_MIGRATION); 1216 wizard_.Step(SyncSetupWizard::PASSPHRASE_MIGRATION);
1207 passphrase_migration_in_progress_ = false; 1217 passphrase_migration_in_progress_ = false;
1208 } 1218 }
1209 1219
1210 break; 1220 break;
1211 } 1221 }
1212 case NotificationType::GOOGLE_SIGNIN_FAILED: { 1222 case NotificationType::GOOGLE_SIGNIN_FAILED: {
1213 GoogleServiceAuthError error = 1223 GoogleServiceAuthError error =
1214 *(Details<const GoogleServiceAuthError>(details).ptr()); 1224 *(Details<const GoogleServiceAuthError>(details).ptr());
1215 UpdateAuthErrorState(error); 1225 UpdateAuthErrorState(error);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 // is initialized, all enabled data types are consistent with one 1289 // is initialized, all enabled data types are consistent with one
1280 // another, and no unrecoverable error has transpired. 1290 // another, and no unrecoverable error has transpired.
1281 if (unrecoverable_error_detected_) 1291 if (unrecoverable_error_detected_)
1282 return false; 1292 return false;
1283 1293
1284 if (!data_type_manager_.get()) 1294 if (!data_type_manager_.get())
1285 return false; 1295 return false;
1286 1296
1287 return data_type_manager_->state() == DataTypeManager::CONFIGURED; 1297 return data_type_manager_->state() == DataTypeManager::CONFIGURED;
1288 } 1298 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698