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

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

Issue 10388169: Merge 137359 - Treat SyncCredentialsLost as an auth error (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1132/src/
Patch Set: Created 8 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) 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 sync_service_url_ = GURL(kSyncServerUrl); 151 sync_service_url_ = GURL(kSyncServerUrl);
152 } 152 }
153 #endif 153 #endif
154 } 154 }
155 155
156 ProfileSyncService::~ProfileSyncService() { 156 ProfileSyncService::~ProfileSyncService() {
157 sync_prefs_.RemoveSyncPrefObserver(this); 157 sync_prefs_.RemoveSyncPrefObserver(this);
158 Shutdown(); 158 Shutdown();
159 } 159 }
160 160
161 bool ProfileSyncService::AreCredentialsAvailable() { 161 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() {
162 if (IsManaged()) { 162 // Exit if sync is disabled.
163 return false; 163 if (IsManaged() || sync_prefs_.IsStartSuppressed())
164 }
165
166 // If we have start suppressed, then basically just act like we have no
167 // credentials (login is required to fix this, since we need the user's
168 // passphrase to encrypt/decrypt anyway).
169 // TODO(sync): Revisit this when we move to a server-based keystore.
170 if (sync_prefs_.IsStartSuppressed())
171 return false; 164 return false;
172 165
173 // CrOS user is always logged in. Chrome uses signin_ to check logged in. 166 // Sync is logged in if there is a non-empty authenticated username.
174 if (signin_->GetAuthenticatedUsername().empty()) 167 return !signin_->GetAuthenticatedUsername().empty();
175 return false; 168 }
176 169
170 bool ProfileSyncService::IsSyncTokenAvailable() {
177 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 171 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
178 if (!token_service) 172 if (!token_service)
179 return false; 173 return false;
180
181 // TODO(chron): Verify CrOS unit test behavior.
182 return token_service->HasTokenForService(GaiaConstants::kSyncService); 174 return token_service->HasTokenForService(GaiaConstants::kSyncService);
183 } 175 }
184 176
185 void ProfileSyncService::Initialize() { 177 void ProfileSyncService::Initialize() {
186 InitSettings(); 178 InitSettings();
187 179
188 // We clear this here (vs Shutdown) because we want to remember that an error 180 // We clear this here (vs Shutdown) because we want to remember that an error
189 // happened on shutdown so we can display details (message, location) about it 181 // happened on shutdown so we can display details (message, location) about it
190 // in about:sync. 182 // in about:sync.
191 ClearStaleErrors(); 183 ClearStaleErrors();
192 184
193 sync_prefs_.AddSyncPrefObserver(this); 185 sync_prefs_.AddSyncPrefObserver(this);
194 186
195 // For now, the only thing we can do through policy is to turn sync off. 187 // For now, the only thing we can do through policy is to turn sync off.
196 if (IsManaged()) { 188 if (IsManaged()) {
197 DisableForUser(); 189 DisableForUser();
198 return; 190 return;
199 } 191 }
200 192
201 RegisterAuthNotifications(); 193 RegisterAuthNotifications();
202 194
203 if (!HasSyncSetupCompleted()) 195 if (!HasSyncSetupCompleted())
204 DisableForUser(); // Clean up in case of previous crash / setup abort. 196 DisableForUser(); // Clean up in case of previous crash / setup abort.
205 197
206 TryStart(); 198 TryStart();
207 } 199 }
208 200
209 void ProfileSyncService::TryStart() { 201 void ProfileSyncService::TryStart() {
210 if (!sync_prefs_.IsStartSuppressed() && AreCredentialsAvailable()) { 202 if (!IsSyncEnabledAndLoggedIn())
203 return;
204 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
205 if (!token_service)
206 return;
207 // Don't start the backend if the token service hasn't finished loading tokens
208 // yet (if the backend is started before the sync token has been loaded,
209 // GetCredentials() will return bogus credentials).
210 if (IsSyncTokenAvailable() || token_service->TokensLoadedFromDB()) {
211 if (HasSyncSetupCompleted() || auto_start_enabled_) { 211 if (HasSyncSetupCompleted() || auto_start_enabled_) {
212 // If sync setup has completed we always start the backend. 212 // If sync setup has completed we always start the backend.
213 // If autostart is enabled, but we haven't completed sync setup, we try to 213 // If autostart is enabled, but we haven't completed sync setup, we try to
214 // start sync anyway, since it's possible we crashed/shutdown after 214 // start sync anyway, since it's possible we crashed/shutdown after
215 // logging in but before the backend finished initializing the last time. 215 // logging in but before the backend finished initializing the last time.
216 // Note that if we haven't finished setting up sync, backend bring up will 216 // Note that if we haven't finished setting up sync, backend bring up will
217 // be done by the wizard. 217 // be done by the wizard.
218 StartUp(); 218 StartUp();
219 } 219 }
220 } else if (HasSyncSetupCompleted()) {
221 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
222 if (token_service && token_service->TokensLoadedFromDB() &&
223 !AreCredentialsAvailable()) {
224 // The token service has lost sync's tokens. We cannot recover from this
225 // without signing back in, which is not yet supported. For now, we
226 // trigger an unrecoverable error.
227 OnUnrecoverableError(FROM_HERE, "Sync credentials lost.");
228 }
229 } 220 }
230 } 221 }
231 222
232 void ProfileSyncService::StartSyncingWithServer() { 223 void ProfileSyncService::StartSyncingWithServer() {
233 if (backend_.get()) 224 if (backend_.get())
234 backend_->StartSyncingWithServer(); 225 backend_->StartSyncingWithServer();
235 } 226 }
236 227
237 void ProfileSyncService::RegisterAuthNotifications() { 228 void ProfileSyncService::RegisterAuthNotifications() {
238 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 229 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 } 296 }
306 } 297 }
307 } 298 }
308 } 299 }
309 300
310 SyncCredentials ProfileSyncService::GetCredentials() { 301 SyncCredentials ProfileSyncService::GetCredentials() {
311 SyncCredentials credentials; 302 SyncCredentials credentials;
312 credentials.email = signin_->GetAuthenticatedUsername(); 303 credentials.email = signin_->GetAuthenticatedUsername();
313 DCHECK(!credentials.email.empty()); 304 DCHECK(!credentials.email.empty());
314 TokenService* service = TokenServiceFactory::GetForProfile(profile_); 305 TokenService* service = TokenServiceFactory::GetForProfile(profile_);
315 credentials.sync_token = service->GetTokenForService( 306 if (service->HasTokenForService(GaiaConstants::kSyncService)) {
316 GaiaConstants::kSyncService); 307 credentials.sync_token = service->GetTokenForService(
308 GaiaConstants::kSyncService);
309 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false);
310 } else {
311 // We've lost our sync credentials (crbug.com/121755), so just make up some
312 // invalid credentials so the backend will generate an auth error.
313 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true);
314 credentials.sync_token = "credentials_lost";
315 }
317 return credentials; 316 return credentials;
318 } 317 }
319 318
320 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { 319 void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
321 if (!backend_.get()) { 320 if (!backend_.get()) {
322 NOTREACHED(); 321 NOTREACHED();
323 return; 322 return;
324 } 323 }
325 324
326 syncable::ModelTypeSet initial_types; 325 syncable::ModelTypeSet initial_types;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 396 }
398 397
399 398
400 void ProfileSyncService::StartUp() { 399 void ProfileSyncService::StartUp() {
401 // Don't start up multiple times. 400 // Don't start up multiple times.
402 if (backend_.get()) { 401 if (backend_.get()) {
403 DVLOG(1) << "Skipping bringing up backend host."; 402 DVLOG(1) << "Skipping bringing up backend host.";
404 return; 403 return;
405 } 404 }
406 405
407 DCHECK(AreCredentialsAvailable()); 406 DCHECK(IsSyncEnabledAndLoggedIn());
408 407
409 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); 408 last_synced_time_ = sync_prefs_.GetLastSyncedTime();
410 409
411 #if defined(OS_CHROMEOS) 410 #if defined(OS_CHROMEOS)
412 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); 411 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken();
413 if (bootstrap_token.empty()) { 412 if (bootstrap_token.empty()) {
414 sync_prefs_.SetEncryptionBootstrapToken( 413 sync_prefs_.SetEncryptionBootstrapToken(
415 sync_prefs_.GetSpareBootstrapToken()); 414 sync_prefs_.GetSpareBootstrapToken());
416 } 415 }
417 #endif 416 #endif
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 DCHECK(encrypted_types_.Has(syncable::PASSWORDS)); 1382 DCHECK(encrypted_types_.Has(syncable::PASSWORDS));
1384 // We may be called during the setup process before we're 1383 // We may be called during the setup process before we're
1385 // initialized. In this case, we default to the sensitive types. 1384 // initialized. In this case, we default to the sensitive types.
1386 return encrypted_types_; 1385 return encrypted_types_;
1387 } 1386 }
1388 1387
1389 void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { 1388 void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) {
1390 NotifyObservers(); 1389 NotifyObservers();
1391 if (is_sync_managed) { 1390 if (is_sync_managed) {
1392 DisableForUser(); 1391 DisableForUser();
1393 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { 1392 } else if (HasSyncSetupCompleted() &&
1393 IsSyncEnabledAndLoggedIn() &&
1394 IsSyncTokenAvailable()) {
1395 // Previously-configured sync has been re-enabled, so start sync now.
1394 StartUp(); 1396 StartUp();
1395 } 1397 }
1396 } 1398 }
1397 1399
1398 void ProfileSyncService::Observe(int type, 1400 void ProfileSyncService::Observe(int type,
1399 const content::NotificationSource& source, 1401 const content::NotificationSource& source,
1400 const content::NotificationDetails& details) { 1402 const content::NotificationDetails& details) {
1401 switch (type) { 1403 switch (type) {
1402 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: 1404 case chrome::NOTIFICATION_SYNC_CONFIGURE_START:
1403 case chrome::NOTIFICATION_SYNC_CONFIGURE_BLOCKED: 1405 case chrome::NOTIFICATION_SYNC_CONFIGURE_BLOCKED:
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 // Track the fact that we're still waiting for auth to complete. 1507 // Track the fact that we're still waiting for auth to complete.
1506 is_auth_in_progress_ = true; 1508 is_auth_in_progress_ = true;
1507 } 1509 }
1508 break; 1510 break;
1509 } 1511 }
1510 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { 1512 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
1511 const TokenService::TokenRequestFailedDetails& token_details = 1513 const TokenService::TokenRequestFailedDetails& token_details =
1512 *(content::Details<const TokenService::TokenRequestFailedDetails>( 1514 *(content::Details<const TokenService::TokenRequestFailedDetails>(
1513 details).ptr()); 1515 details).ptr());
1514 if (IsTokenServiceRelevant(token_details.service()) && 1516 if (IsTokenServiceRelevant(token_details.service()) &&
1515 !AreCredentialsAvailable()) { 1517 !IsSyncTokenAvailable()) {
1516 // The additional check around AreCredentialsAvailable above prevents us 1518 // The additional check around IsSyncTokenAvailable() above prevents us
1517 // sounding the alarm if we actually have a valid token but a refresh 1519 // sounding the alarm if we actually have a valid token but a refresh
1518 // attempt by TokenService failed for any variety of reasons (e.g. flaky 1520 // attempt by TokenService failed for any variety of reasons (e.g. flaky
1519 // network). It's possible the token we do have is also invalid, but in 1521 // network). It's possible the token we do have is also invalid, but in
1520 // that case we should already have (or can expect) an auth error sent 1522 // that case we should already have (or can expect) an auth error sent
1521 // from the sync backend. 1523 // from the sync backend.
1522 GoogleServiceAuthError error( 1524 GoogleServiceAuthError error(
1523 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 1525 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
1524 UpdateAuthErrorState(error); 1526 UpdateAuthErrorState(error);
1525 } 1527 }
1526 break; 1528 break;
1527 } 1529 }
1528 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 1530 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
1529 const TokenService::TokenAvailableDetails& token_details = 1531 const TokenService::TokenAvailableDetails& token_details =
1530 *(content::Details<const TokenService::TokenAvailableDetails>( 1532 *(content::Details<const TokenService::TokenAvailableDetails>(
1531 details).ptr()); 1533 details).ptr());
1532 if (IsTokenServiceRelevant(token_details.service()) && 1534 if (IsTokenServiceRelevant(token_details.service()) &&
1533 AreCredentialsAvailable()) { 1535 IsSyncEnabledAndLoggedIn() &&
1536 IsSyncTokenAvailable()) {
1534 if (backend_initialized_) 1537 if (backend_initialized_)
1535 backend_->UpdateCredentials(GetCredentials()); 1538 backend_->UpdateCredentials(GetCredentials());
1536 else if (!sync_prefs_.IsStartSuppressed()) 1539 else
1537 StartUp(); 1540 StartUp();
1538 } 1541 }
1539 break; 1542 break;
1540 } 1543 }
1541 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { 1544 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
1542 // This notification gets fired when TokenService loads the tokens 1545 // This notification gets fired when TokenService loads the tokens
1543 // from storage. 1546 // from storage.
1544 if (AreCredentialsAvailable()) { 1547 if (IsSyncEnabledAndLoggedIn()) {
1545 // Initialize the backend if sync token was loaded. 1548 // Initialize the backend if sync is enabled. If the sync token was
1546 if (backend_initialized_) { 1549 // not loaded, GetCredentials() will generate invalid credentials to
1550 // cause the backend to generate an auth error (crbug.com/121755).
1551 if (backend_initialized_)
1547 backend_->UpdateCredentials(GetCredentials()); 1552 backend_->UpdateCredentials(GetCredentials());
1548 } 1553 else
1549 if (!sync_prefs_.IsStartSuppressed())
1550 StartUp(); 1554 StartUp();
1551 } else if (!auto_start_enabled_ &&
1552 !signin_->GetAuthenticatedUsername().empty() &&
1553 HasSyncSetupCompleted()) {
1554 // If not in auto-start / Chrome OS mode, and we have a username
1555 // without tokens, the user will need to signin again. At the moment
1556 // this is not supported, so we trigger an unrecoverable error.
1557 OnUnrecoverableError(FROM_HERE, "Sync credentials lost.");
1558 } 1555 }
1559 break; 1556 break;
1560 } 1557 }
1561 default: { 1558 default: {
1562 NOTREACHED(); 1559 NOTREACHED();
1563 } 1560 }
1564 } 1561 }
1565 } 1562 }
1566 1563
1567 void ProfileSyncService::AddObserver(Observer* observer) { 1564 void ProfileSyncService::AddObserver(Observer* observer) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 // See http://stackoverflow.com/questions/6224121/is-new-this-myclass-undefine d-behaviour-after-directly-calling-the-destru. 1661 // See http://stackoverflow.com/questions/6224121/is-new-this-myclass-undefine d-behaviour-after-directly-calling-the-destru.
1665 ProfileSyncService* old_this = this; 1662 ProfileSyncService* old_this = this;
1666 this->~ProfileSyncService(); 1663 this->~ProfileSyncService();
1667 new(old_this) ProfileSyncService( 1664 new(old_this) ProfileSyncService(
1668 new ProfileSyncComponentsFactoryImpl(profile, 1665 new ProfileSyncComponentsFactoryImpl(profile,
1669 CommandLine::ForCurrentProcess()), 1666 CommandLine::ForCurrentProcess()),
1670 profile, 1667 profile,
1671 signin, 1668 signin,
1672 behavior); 1669 behavior);
1673 } 1670 }
OLDNEW
« no previous file with comments | « chrome/browser/sync/profile_sync_service.h ('k') | chrome/browser/sync/profile_sync_service_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698