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

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

Issue 15421011: Use OAuth2 token for sync (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 7 years, 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <cstddef> 7 #include <cstddef>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 13 matching lines...) Expand all
24 #include "build/build_config.h" 24 #include "build/build_config.h"
25 #include "chrome/browser/about_flags.h" 25 #include "chrome/browser/about_flags.h"
26 #include "chrome/browser/browser_process.h" 26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/defaults.h" 27 #include "chrome/browser/defaults.h"
28 #include "chrome/browser/net/chrome_cookie_notification_details.h" 28 #include "chrome/browser/net/chrome_cookie_notification_details.h"
29 #include "chrome/browser/pref_service_flags_storage.h" 29 #include "chrome/browser/pref_service_flags_storage.h"
30 #include "chrome/browser/prefs/pref_service_syncable.h" 30 #include "chrome/browser/prefs/pref_service_syncable.h"
31 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/signin/about_signin_internals.h" 32 #include "chrome/browser/signin/about_signin_internals.h"
33 #include "chrome/browser/signin/about_signin_internals_factory.h" 33 #include "chrome/browser/signin/about_signin_internals_factory.h"
34 #include "chrome/browser/signin/profile_oauth2_token_service.h"
35 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
34 #include "chrome/browser/signin/signin_manager.h" 36 #include "chrome/browser/signin/signin_manager.h"
35 #include "chrome/browser/signin/signin_manager_factory.h" 37 #include "chrome/browser/signin/signin_manager_factory.h"
36 #include "chrome/browser/signin/token_service.h" 38 #include "chrome/browser/signin/token_service.h"
37 #include "chrome/browser/signin/token_service_factory.h" 39 #include "chrome/browser/signin/token_service_factory.h"
38 #include "chrome/browser/sync/backend_migrator.h" 40 #include "chrome/browser/sync/backend_migrator.h"
39 #include "chrome/browser/sync/glue/change_processor.h" 41 #include "chrome/browser/sync/glue/change_processor.h"
40 #include "chrome/browser/sync/glue/chrome_encryptor.h" 42 #include "chrome/browser/sync/glue/chrome_encryptor.h"
41 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" 43 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
42 #include "chrome/browser/sync/glue/data_type_controller.h" 44 #include "chrome/browser/sync/glue/data_type_controller.h"
43 #include "chrome/browser/sync/glue/device_info.h" 45 #include "chrome/browser/sync/glue/device_info.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 typedef GoogleServiceAuthError AuthError; 107 typedef GoogleServiceAuthError AuthError;
106 108
107 const char* ProfileSyncService::kSyncServerUrl = 109 const char* ProfileSyncService::kSyncServerUrl =
108 "https://clients4.google.com/chrome-sync"; 110 "https://clients4.google.com/chrome-sync";
109 111
110 const char* ProfileSyncService::kDevServerUrl = 112 const char* ProfileSyncService::kDevServerUrl =
111 "https://clients4.google.com/chrome-sync/dev"; 113 "https://clients4.google.com/chrome-sync/dev";
112 114
113 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. 115 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute.
114 116
115 static const char* kRelevantTokenServices[] = { 117 static const char* kOAuth2Scopes[] = {
116 GaiaConstants::kSyncService 118 GaiaConstants::kChromeSyncOAuth2Scope,
119 // GoogleTalk scope is needed for notifications.
120 GaiaConstants::kGoogleTalkOAuth2Scope
117 }; 121 };
118 static const int kRelevantTokenServicesCount = 122
119 arraysize(kRelevantTokenServices);
120 123
121 static const char* kSyncUnrecoverableErrorHistogram = 124 static const char* kSyncUnrecoverableErrorHistogram =
122 "Sync.UnrecoverableErrors"; 125 "Sync.UnrecoverableErrors";
123 126
124 // Helper to check if the given token service is relevant for sync. 127 const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = {
125 static bool IsTokenServiceRelevant(const std::string& service) { 128 // Number of initial errors (in sequence) to ignore before applying
126 for (int i = 0; i < kRelevantTokenServicesCount; ++i) { 129 // exponential back-off rules.
127 if (service == kRelevantTokenServices[i]) 130 0,
128 return true; 131
129 } 132 // Initial delay for exponential back-off in ms.
130 return false; 133 2000,
131 } 134
135 // Factor by which the waiting time will be multiplied.
136 2,
137
138 // Fuzzing percentage. ex: 10% will spread requests randomly
139 // between 90%-100% of the calculated time.
140 0.2, // 20%
141
142 // Maximum amount of time we are willing to delay our request in ms.
143 // TODO(pavely): crbug.com/246686 ProfileSyncService should retry
144 // RequestAccessToken on connection state change after backoff
145 1000 * 3600 * 4, // 4 hours.
146
147 // Time to keep an entry from being discarded even when it
148 // has no significant state, -1 to never discard.
149 -1,
150
151 // Don't use initial delay unless the last request was an error.
152 false,
153 };
132 154
133 bool ShouldShowActionOnUI( 155 bool ShouldShowActionOnUI(
134 const syncer::SyncProtocolError& error) { 156 const syncer::SyncProtocolError& error) {
135 return (error.action != syncer::UNKNOWN_ACTION && 157 return (error.action != syncer::UNKNOWN_ACTION &&
136 error.action != syncer::DISABLE_SYNC_ON_CLIENT && 158 error.action != syncer::DISABLE_SYNC_ON_CLIENT &&
137 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT); 159 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT);
138 } 160 }
139 161
140 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, 162 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory,
141 Profile* profile, 163 Profile* profile,
(...skipping 15 matching lines...) Expand all
157 signin_(signin_manager), 179 signin_(signin_manager),
158 unrecoverable_error_reason_(ERROR_REASON_UNSET), 180 unrecoverable_error_reason_(ERROR_REASON_UNSET),
159 weak_factory_(this), 181 weak_factory_(this),
160 expect_sync_configuration_aborted_(false), 182 expect_sync_configuration_aborted_(false),
161 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), 183 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()),
162 encrypt_everything_(false), 184 encrypt_everything_(false),
163 encryption_pending_(false), 185 encryption_pending_(false),
164 auto_start_enabled_(start_behavior == AUTO_START), 186 auto_start_enabled_(start_behavior == AUTO_START),
165 configure_status_(DataTypeManager::UNKNOWN), 187 configure_status_(DataTypeManager::UNKNOWN),
166 setup_in_progress_(false), 188 setup_in_progress_(false),
167 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR) { 189 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR),
190 request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy) {
168 // By default, dev, canary, and unbranded Chromium users will go to the 191 // By default, dev, canary, and unbranded Chromium users will go to the
169 // development servers. Development servers have more features than standard 192 // development servers. Development servers have more features than standard
170 // sync servers. Users with officially-branded Chrome stable and beta builds 193 // sync servers. Users with officially-branded Chrome stable and beta builds
171 // will go to the standard sync servers. 194 // will go to the standard sync servers.
172 // 195 //
173 // GetChannel hits the registry on Windows. See http://crbug.com/70380. 196 // GetChannel hits the registry on Windows. See http://crbug.com/70380.
174 base::ThreadRestrictions::ScopedAllowIO allow_io; 197 base::ThreadRestrictions::ScopedAllowIO allow_io;
175 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 198 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
176 if (channel == chrome::VersionInfo::CHANNEL_STABLE || 199 if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
177 channel == chrome::VersionInfo::CHANNEL_BETA) { 200 channel == chrome::VersionInfo::CHANNEL_BETA) {
(...skipping 11 matching lines...) Expand all
189 212
190 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { 213 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() {
191 // Exit if sync is disabled. 214 // Exit if sync is disabled.
192 if (IsManaged() || sync_prefs_.IsStartSuppressed()) 215 if (IsManaged() || sync_prefs_.IsStartSuppressed())
193 return false; 216 return false;
194 217
195 // Sync is logged in if there is a non-empty effective username. 218 // Sync is logged in if there is a non-empty effective username.
196 return !GetEffectiveUsername().empty(); 219 return !GetEffectiveUsername().empty();
197 } 220 }
198 221
199 bool ProfileSyncService::IsSyncTokenAvailable() { 222 bool ProfileSyncService::IsOAuthRefreshTokenAvailable() {
200 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 223 // Function name doesn't reflect which token is checked. Function checks
201 if (!token_service) 224 // refresh token when use_oauth2_token_ is true (all platforms except android)
202 return false; 225 // and sync token otherwise (for android).
203 return token_service->HasTokenForService(GaiaConstants::kSyncService); 226 // TODO(pavely): Remove "else" part once use_oauth2_token_ is gone.
227 if (use_oauth2_token_) {
228 ProfileOAuth2TokenService* token_service =
229 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
230 if (!token_service)
231 return false;
232 return token_service->RefreshTokenIsAvailable();
233 } else {
234 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
235 if (!token_service)
236 return false;
237 return token_service->HasTokenForService(GaiaConstants::kSyncService);
238 }
204 } 239 }
205 240
206 void ProfileSyncService::Initialize() { 241 void ProfileSyncService::Initialize() {
207 DCHECK(!invalidator_registrar_.get()); 242 DCHECK(!invalidator_registrar_.get());
208 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar()); 243 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar());
209 244
210 InitSettings(); 245 InitSettings();
211 246
212 // We clear this here (vs Shutdown) because we want to remember that an error 247 // We clear this here (vs Shutdown) because we want to remember that an error
213 // happened on shutdown so we can display details (message, location) about it 248 // happened on shutdown so we can display details (message, location) about it
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 return; 306 return;
272 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 307 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
273 if (!token_service) 308 if (!token_service)
274 return; 309 return;
275 // Don't start the backend if the token service hasn't finished loading tokens 310 // Don't start the backend if the token service hasn't finished loading tokens
276 // yet. Note if the backend is started before the sync token has been loaded, 311 // yet. Note if the backend is started before the sync token has been loaded,
277 // GetCredentials() will return bogus credentials. On auto_start platforms 312 // GetCredentials() will return bogus credentials. On auto_start platforms
278 // (like ChromeOS) we don't start sync until tokens are loaded, because the 313 // (like ChromeOS) we don't start sync until tokens are loaded, because the
279 // user can be "signed in" on those platforms long before the tokens get 314 // user can be "signed in" on those platforms long before the tokens get
280 // loaded, and we don't want to generate spurious auth errors. 315 // loaded, and we don't want to generate spurious auth errors.
281 if (!IsSyncTokenAvailable() && 316 if (!IsOAuthRefreshTokenAvailable() &&
282 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { 317 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) {
283 return; 318 return;
284 } 319 }
285 320
321 if (use_oauth2_token_) {
322 // If we got here then tokens are loaded and user logged in and sync is
323 // enabled. If OAuth refresh token is not available then something is wrong.
324 // When PSS requests access token, OAuth2TokenService will return error and
325 // PSS will show error to user asking to reauthenticate.
326 UMA_HISTOGRAM_BOOLEAN("Sync.RefreshTokenAvailable",
327 IsOAuthRefreshTokenAvailable());
328 }
329
286 // If sync setup has completed we always start the backend. If the user is in 330 // If sync setup has completed we always start the backend. If the user is in
287 // the process of setting up now, we should start the backend to download 331 // the process of setting up now, we should start the backend to download
288 // account control state / encryption information). If autostart is enabled, 332 // account control state / encryption information). If autostart is enabled,
289 // but we haven't completed sync setup, we try to start sync anyway, since 333 // but we haven't completed sync setup, we try to start sync anyway, since
290 // it's possible we crashed/shutdown after logging in but before the backend 334 // it's possible we crashed/shutdown after logging in but before the backend
291 // finished initializing the last time. 335 // finished initializing the last time.
292 // 336 //
293 // However, the only time we actually need to start sync _immediately_ is if 337 // However, the only time we actually need to start sync _immediately_ is if
294 // we haven't completed sync setup and the user is in the process of setting 338 // we haven't completed sync setup and the user is in the process of setting
295 // up - either they just signed in (for the first time) on an auto-start 339 // up - either they just signed in (for the first time) on an auto-start
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 if (!value.empty()) { 443 if (!value.empty()) {
400 GURL custom_sync_url(value); 444 GURL custom_sync_url(value);
401 if (custom_sync_url.is_valid()) { 445 if (custom_sync_url.is_valid()) {
402 sync_service_url_ = custom_sync_url; 446 sync_service_url_ = custom_sync_url;
403 } else { 447 } else {
404 LOG(WARNING) << "The following sync URL specified at the command-line " 448 LOG(WARNING) << "The following sync URL specified at the command-line "
405 << "is invalid: " << value; 449 << "is invalid: " << value;
406 } 450 }
407 } 451 }
408 } 452 }
453
454 use_oauth2_token_ = !command_line.HasSwitch(
455 switches::kSyncDisableOAuth2Token);
409 } 456 }
410 457
411 SyncCredentials ProfileSyncService::GetCredentials() { 458 SyncCredentials ProfileSyncService::GetCredentials() {
412 SyncCredentials credentials; 459 SyncCredentials credentials;
413 credentials.email = GetEffectiveUsername(); 460 credentials.email = GetEffectiveUsername();
414 DCHECK(!credentials.email.empty()); 461 DCHECK(!credentials.email.empty());
415 TokenService* service = TokenServiceFactory::GetForProfile(profile_); 462 if (use_oauth2_token_) {
416 if (service->HasTokenForService(GaiaConstants::kSyncService)) { 463 credentials.sync_token = access_token_;
417 credentials.sync_token = service->GetTokenForService(
418 GaiaConstants::kSyncService);
419 credentials.sync_token_time =
420 AboutSigninInternalsFactory::GetForProfile(profile_)->
421 GetTokenTime(GaiaConstants::kSyncService);
422 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false);
423 } else { 464 } else {
424 // We've lost our sync credentials (crbug.com/121755), so just make up some 465 TokenService* service = TokenServiceFactory::GetForProfile(profile_);
425 // invalid credentials so the backend will generate an auth error. 466 if (service->HasTokenForService(GaiaConstants::kSyncService)) {
426 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true); 467 credentials.sync_token = service->GetTokenForService(
468 GaiaConstants::kSyncService);
469 }
470 }
471
472 if (credentials.sync_token.empty())
427 credentials.sync_token = "credentials_lost"; 473 credentials.sync_token = "credentials_lost";
428 }
429 return credentials; 474 return credentials;
430 } 475 }
431 476
432 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { 477 void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
433 if (!backend_) { 478 if (!backend_) {
434 NOTREACHED(); 479 NOTREACHED();
435 return; 480 return;
436 } 481 }
437 482
438 SyncCredentials credentials = GetCredentials(); 483 SyncCredentials credentials = GetCredentials();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 530
486 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { 531 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) {
487 // Don't start up multiple times. 532 // Don't start up multiple times.
488 if (backend_) { 533 if (backend_) {
489 DVLOG(1) << "Skipping bringing up backend host."; 534 DVLOG(1) << "Skipping bringing up backend host.";
490 return; 535 return;
491 } 536 }
492 537
493 DCHECK(IsSyncEnabledAndLoggedIn()); 538 DCHECK(IsSyncEnabledAndLoggedIn());
494 539
540 if (use_oauth2_token_ && access_token_.empty()) {
541 RequestAccessToken();
542 return;
543 }
544
495 if (start_up_time_.is_null()) { 545 if (start_up_time_.is_null()) {
496 start_up_time_ = base::Time::Now(); 546 start_up_time_ = base::Time::Now();
497 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); 547 last_synced_time_ = sync_prefs_.GetLastSyncedTime();
498 548
499 #if defined(OS_CHROMEOS) 549 #if defined(OS_CHROMEOS)
500 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); 550 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken();
501 if (bootstrap_token.empty()) { 551 if (bootstrap_token.empty()) {
502 sync_prefs_.SetEncryptionBootstrapToken( 552 sync_prefs_.SetEncryptionBootstrapToken(
503 sync_prefs_.GetSpareBootstrapToken()); 553 sync_prefs_.GetSpareBootstrapToken());
504 } 554 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 // If |backend_| is NULL, save the acknowledgements to replay when 682 // If |backend_| is NULL, save the acknowledgements to replay when
633 // it's created and initialized. 683 // it's created and initialized.
634 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); 684 ack_replay_queue_.push_back(std::make_pair(id, ack_handle));
635 } 685 }
636 } 686 }
637 687
638 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { 688 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const {
639 return invalidator_registrar_->GetInvalidatorState(); 689 return invalidator_registrar_->GetInvalidatorState();
640 } 690 }
641 691
692 void ProfileSyncService::OnGetTokenSuccess(
693 const OAuth2TokenService::Request* request,
694 const std::string& access_token,
695 const base::Time& expiration_time) {
696 DCHECK_EQ(access_token_request_, request);
697 access_token_request_.reset();
698 // Reset backoff time after successful response.
699 request_access_token_backoff_.Reset();
700 access_token_ = access_token;
701 if (backend_)
702 backend_->UpdateCredentials(GetCredentials());
703 else
704 TryStart();
705 }
706
707 void ProfileSyncService::OnGetTokenFailure(
708 const OAuth2TokenService::Request* request,
709 const GoogleServiceAuthError& error) {
710 DCHECK_EQ(access_token_request_, request);
711 DCHECK_NE(error.state(), GoogleServiceAuthError::NONE);
712 access_token_request_.reset();
713 switch (error.state()) {
714 case GoogleServiceAuthError::CONNECTION_FAILED:
715 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: {
716 // Transient error. Retry after some time.
717 request_access_token_backoff_.InformOfRequest(false);
718 request_access_token_retry_timer_.Start(
719 FROM_HERE,
720 request_access_token_backoff_.GetTimeUntilRelease(),
721 base::Bind(&ProfileSyncService::RequestAccessToken,
722 weak_factory_.GetWeakPtr()));
723 break;
724 }
725 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: {
726 // Report time since token was issued for invalid credentials error.
727 // TODO(pavely): crbug.com/246817 Collect UMA histogram for auth token
728 // rejections from invalidation service.
729 base::Time auth_token_time =
730 AboutSigninInternalsFactory::GetForProfile(profile_)->
731 GetTokenTime(GaiaConstants::kGaiaOAuth2LoginRefreshToken);
732 if (!auth_token_time.is_null()) {
733 base::TimeDelta age = base::Time::Now() - auth_token_time;
734 if (age < base::TimeDelta::FromHours(1)) {
735 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.AuthServerRejectedTokenAgeShort",
736 age,
737 base::TimeDelta::FromSeconds(1),
738 base::TimeDelta::FromHours(1),
739 50);
740 }
741 UMA_HISTOGRAM_COUNTS("Sync.AuthServerRejectedTokenAgeLong",
742 age.InDays());
743 }
744 // Fallthrough.
745 }
746 default: {
747 // Show error to user.
748 UpdateAuthErrorState(error);
749 }
750 }
751 }
752
642 void ProfileSyncService::EmitInvalidationForTest( 753 void ProfileSyncService::EmitInvalidationForTest(
643 const invalidation::ObjectId& id, 754 const invalidation::ObjectId& id,
644 const std::string& payload) { 755 const std::string& payload) {
645 syncer::ObjectIdSet notify_ids; 756 syncer::ObjectIdSet notify_ids;
646 notify_ids.insert(id); 757 notify_ids.insert(id);
647 758
648 const syncer::ObjectIdInvalidationMap& invalidation_map = 759 const syncer::ObjectIdInvalidationMap& invalidation_map =
649 ObjectIdSetToInvalidationMap(notify_ids, payload); 760 ObjectIdSetToInvalidationMap(notify_ids, payload);
650 OnIncomingInvalidation(invalidation_map); 761 OnIncomingInvalidation(invalidation_map);
651 } 762 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 is_auth_in_progress_ = false; 822 is_auth_in_progress_ = false;
712 backend_initialized_ = false; 823 backend_initialized_ = false;
713 // NULL if we're called from Shutdown(). 824 // NULL if we're called from Shutdown().
714 if (invalidator_registrar_) 825 if (invalidator_registrar_)
715 UpdateInvalidatorRegistrarState(); 826 UpdateInvalidatorRegistrarState();
716 cached_passphrase_.clear(); 827 cached_passphrase_.clear();
717 encryption_pending_ = false; 828 encryption_pending_ = false;
718 encrypt_everything_ = false; 829 encrypt_everything_ = false;
719 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); 830 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes();
720 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; 831 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED;
721 start_up_time_ = base::Time(); 832 request_access_token_retry_timer_.Stop();
722 // Revert to "no auth error". 833 // Revert to "no auth error".
723 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) 834 if (last_auth_error_.state() != GoogleServiceAuthError::NONE)
724 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); 835 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone());
725 836
726 if (sync_global_error_) { 837 if (sync_global_error_) {
727 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( 838 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
728 sync_global_error_.get()); 839 sync_global_error_.get());
729 RemoveObserver(sync_global_error_.get()); 840 RemoveObserver(sync_global_error_.get());
730 sync_global_error_.reset(NULL); 841 sync_global_error_.reset(NULL);
731 } 842 }
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 default: 1175 default:
1065 NOTREACHED(); 1176 NOTREACHED();
1066 return AuthError(AuthError::CONNECTION_FAILED); 1177 return AuthError(AuthError::CONNECTION_FAILED);
1067 } 1178 }
1068 } 1179 }
1069 1180
1070 } // namespace 1181 } // namespace
1071 1182
1072 void ProfileSyncService::OnConnectionStatusChange( 1183 void ProfileSyncService::OnConnectionStatusChange(
1073 syncer::ConnectionStatus status) { 1184 syncer::ConnectionStatus status) {
1074 const GoogleServiceAuthError auth_error = 1185 if (use_oauth2_token_ && status == syncer::CONNECTION_AUTH_ERROR) {
1075 ConnectionStatusToAuthError(status); 1186 // Sync or Tango server returned error indicating that access token is
1076 DVLOG(1) << "Connection status change: " << auth_error.ToString(); 1187 // invalid. It could be either expired or access is revoked. Let's request
1077 UpdateAuthErrorState(auth_error); 1188 // another access token and if access is revoked then request for token will
1189 // fail with corresponding error.
1190 RequestAccessToken();
1191 } else {
1192 const GoogleServiceAuthError auth_error =
1193 ConnectionStatusToAuthError(status);
1194 DVLOG(1) << "Connection status change: " << auth_error.ToString();
1195 UpdateAuthErrorState(auth_error);
1196 }
1078 } 1197 }
1079 1198
1080 void ProfileSyncService::OnStopSyncingPermanently() { 1199 void ProfileSyncService::OnStopSyncingPermanently() {
1081 sync_prefs_.SetStartSuppressed(true); 1200 sync_prefs_.SetStartSuppressed(true);
1082 DisableForUser(); 1201 DisableForUser();
1083 } 1202 }
1084 1203
1085 void ProfileSyncService::OnPassphraseRequired( 1204 void ProfileSyncService::OnPassphraseRequired(
1086 syncer::PassphraseRequiredReason reason, 1205 syncer::PassphraseRequiredReason reason,
1087 const sync_pb::EncryptedData& pending_keys) { 1206 const sync_pb::EncryptedData& pending_keys) {
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 } 1910 }
1792 } 1911 }
1793 1912
1794 // If we get here, we don't have pending keys (or at least, the passphrase 1913 // If we get here, we don't have pending keys (or at least, the passphrase
1795 // doesn't decrypt them) - just try to re-encrypt using the encryption 1914 // doesn't decrypt them) - just try to re-encrypt using the encryption
1796 // passphrase. 1915 // passphrase.
1797 if (!IsUsingSecondaryPassphrase()) 1916 if (!IsUsingSecondaryPassphrase())
1798 SetEncryptionPassphrase(passphrase, IMPLICIT); 1917 SetEncryptionPassphrase(passphrase, IMPLICIT);
1799 } 1918 }
1800 1919
1920 void ProfileSyncService::RequestAccessToken() {
1921 // Only one active request at a time.
1922 if (access_token_request_ != NULL)
1923 return;
1924 request_access_token_retry_timer_.Stop();
1925 OAuth2TokenService::ScopeSet oauth2_scopes;
1926 for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++)
1927 oauth2_scopes.insert(kOAuth2Scopes[i]);
1928 OAuth2TokenService* token_service =
1929 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
1930 // Invalidate previous token, otherwise token service will return the same
1931 // token again.
1932 token_service->InvalidateToken(oauth2_scopes, access_token_);
1933 access_token_.clear();
1934 access_token_request_ = token_service->StartRequest(oauth2_scopes, this);
1935 }
1936
1801 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, 1937 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase,
1802 PassphraseType type) { 1938 PassphraseType type) {
1803 // This should only be called when the backend has been initialized. 1939 // This should only be called when the backend has been initialized.
1804 DCHECK(sync_initialized()); 1940 DCHECK(sync_initialized());
1805 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << 1941 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) <<
1806 "Data is already encrypted using an explicit passphrase"; 1942 "Data is already encrypted using an explicit passphrase";
1807 DCHECK(!(type == EXPLICIT && 1943 DCHECK(!(type == EXPLICIT &&
1808 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << 1944 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) <<
1809 "Can not set explicit passphrase when decryption is needed."; 1945 "Can not set explicit passphrase when decryption is needed.";
1810 1946
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 DisableForUser(); 2006 DisableForUser();
1871 } else { 2007 } else {
1872 // Sync is no longer disabled by policy. Try starting it up if appropriate. 2008 // Sync is no longer disabled by policy. Try starting it up if appropriate.
1873 TryStart(); 2009 TryStart();
1874 } 2010 }
1875 } 2011 }
1876 2012
1877 void ProfileSyncService::Observe(int type, 2013 void ProfileSyncService::Observe(int type,
1878 const content::NotificationSource& source, 2014 const content::NotificationSource& source,
1879 const content::NotificationDetails& details) { 2015 const content::NotificationDetails& details) {
2016 const char* sync_token_service = use_oauth2_token_ ?
2017 GaiaConstants::kGaiaOAuth2LoginRefreshToken : GaiaConstants::kSyncService;
1880 switch (type) { 2018 switch (type) {
1881 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { 2019 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
1882 const GoogleServiceSigninSuccessDetails* successful = 2020 const GoogleServiceSigninSuccessDetails* successful =
1883 content::Details<const GoogleServiceSigninSuccessDetails>( 2021 content::Details<const GoogleServiceSigninSuccessDetails>(
1884 details).ptr(); 2022 details).ptr();
1885 if (!sync_prefs_.IsStartSuppressed() && 2023 if (!sync_prefs_.IsStartSuppressed() &&
1886 !successful->password.empty()) { 2024 !successful->password.empty()) {
1887 cached_passphrase_ = successful->password; 2025 cached_passphrase_ = successful->password;
1888 // Try to consume the passphrase we just cached. If the sync backend 2026 // Try to consume the passphrase we just cached. If the sync backend
1889 // is not running yet, the passphrase will remain cached until the 2027 // is not running yet, the passphrase will remain cached until the
1890 // backend starts up. 2028 // backend starts up.
1891 ConsumeCachedPassphraseIfPossible(); 2029 ConsumeCachedPassphraseIfPossible();
1892 } 2030 }
1893 #if defined(OS_CHROMEOS) 2031 #if defined(OS_CHROMEOS)
1894 RefreshSpareBootstrapToken(successful->password); 2032 RefreshSpareBootstrapToken(successful->password);
1895 #endif 2033 #endif
1896 if (!sync_initialized() || 2034 if (!sync_initialized() ||
1897 GetAuthError().state() != AuthError::NONE) { 2035 GetAuthError().state() != AuthError::NONE) {
1898 // Track the fact that we're still waiting for auth to complete. 2036 // Track the fact that we're still waiting for auth to complete.
1899 is_auth_in_progress_ = true; 2037 is_auth_in_progress_ = true;
1900 } 2038 }
1901 break; 2039 break;
1902 } 2040 }
1903 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { 2041 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
2042 // TODO(atwilson): sync shouldn't report refresh token request failures.
2043 // TokenService should do that instead.
1904 const TokenService::TokenRequestFailedDetails& token_details = 2044 const TokenService::TokenRequestFailedDetails& token_details =
1905 *(content::Details<const TokenService::TokenRequestFailedDetails>( 2045 *(content::Details<const TokenService::TokenRequestFailedDetails>(
1906 details).ptr()); 2046 details).ptr());
1907 if (IsTokenServiceRelevant(token_details.service()) && 2047 if (token_details.service() == sync_token_service &&
1908 !IsSyncTokenAvailable()) { 2048 !IsOAuthRefreshTokenAvailable()) {
1909 // The additional check around IsSyncTokenAvailable() above prevents us 2049 // The additional check around IsOAuthRefreshTokenAvailable() above
1910 // sounding the alarm if we actually have a valid token but a refresh 2050 // prevents us sounding the alarm if we actually have a valid token but
1911 // attempt by TokenService failed for any variety of reasons (e.g. flaky 2051 // a refresh attempt by TokenService failed for any variety of reasons
1912 // network). It's possible the token we do have is also invalid, but in 2052 // (e.g. flaky network). It's possible the token we do have is also
1913 // that case we should already have (or can expect) an auth error sent 2053 // invalid, but in that case we should already have (or can expect) an
1914 // from the sync backend. 2054 // auth error sent from the sync backend.
1915 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); 2055 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS);
1916 UpdateAuthErrorState(error); 2056 UpdateAuthErrorState(error);
1917 } 2057 }
1918 break; 2058 break;
1919 } 2059 }
1920 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 2060 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
2061 // TODO(atwilson): Listen for notifications on OAuth2TokenService
2062 // (crbug.com/243737)
1921 const TokenService::TokenAvailableDetails& token_details = 2063 const TokenService::TokenAvailableDetails& token_details =
1922 *(content::Details<const TokenService::TokenAvailableDetails>( 2064 *(content::Details<const TokenService::TokenAvailableDetails>(
1923 details).ptr()); 2065 details).ptr());
1924 if (!IsTokenServiceRelevant(token_details.service())) 2066 if (token_details.service() != sync_token_service)
1925 break; 2067 break;
1926 } // Fall through. 2068 } // Fall through.
1927 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { 2069 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
1928 // This notification gets fired when TokenService loads the tokens 2070 // This notification gets fired when TokenService loads the tokens
1929 // from storage. 2071 // from storage.
1930 // Initialize the backend if sync is enabled. If the sync token was 2072 // Initialize the backend if sync is enabled. If the sync token was
1931 // not loaded, GetCredentials() will generate invalid credentials to 2073 // not loaded, GetCredentials() will generate invalid credentials to
1932 // cause the backend to generate an auth error (crbug.com/121755). 2074 // cause the backend to generate an auth error (crbug.com/121755).
1933 if (backend_) 2075 if (backend_) {
1934 backend_->UpdateCredentials(GetCredentials()); 2076 if (use_oauth2_token_)
1935 else 2077 RequestAccessToken();
2078 else
2079 backend_->UpdateCredentials(GetCredentials());
2080 } else {
1936 TryStart(); 2081 TryStart();
2082 }
1937 break; 2083 break;
1938 } 2084 }
1939 case chrome::NOTIFICATION_TOKENS_CLEARED: { 2085 case chrome::NOTIFICATION_TOKENS_CLEARED: {
1940 // GetCredentials() will generate invalid credentials to cause the backend 2086 // GetCredentials() will generate invalid credentials to cause the backend
1941 // to generate an auth error. 2087 // to generate an auth error.
2088 access_token_.clear();
1942 if (backend_) 2089 if (backend_)
1943 backend_->UpdateCredentials(GetCredentials()); 2090 backend_->UpdateCredentials(GetCredentials());
1944 break; 2091 break;
1945 } 2092 }
1946 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 2093 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
1947 sync_disabled_by_admin_ = false; 2094 sync_disabled_by_admin_ = false;
1948 DisableForUser(); 2095 DisableForUser();
1949 break; 2096 break;
1950 default: { 2097 default: {
1951 NOTREACHED(); 2098 NOTREACHED();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 std::string ProfileSyncService::GetEffectiveUsername() { 2215 std::string ProfileSyncService::GetEffectiveUsername() {
2069 #if defined(ENABLE_MANAGED_USERS) 2216 #if defined(ENABLE_MANAGED_USERS)
2070 if (ManagedUserService::ProfileIsManaged(profile_)) { 2217 if (ManagedUserService::ProfileIsManaged(profile_)) {
2071 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); 2218 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername());
2072 return ManagedUserService::GetManagedUserPseudoEmail(); 2219 return ManagedUserService::GetManagedUserPseudoEmail();
2073 } 2220 }
2074 #endif 2221 #endif
2075 2222
2076 return signin_->GetAuthenticatedUsername(); 2223 return signin_->GetAuthenticatedUsername();
2077 } 2224 }
2078
OLDNEW
« no previous file with comments | « chrome/browser/sync/profile_sync_service.h ('k') | chrome/browser/sync/profile_sync_service_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698