1 // Copyright 2014 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 "components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h"
6
7 #include <map>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/macros.h"
15 #include "base/run_loop.h"
16 #include "base/test/metrics/histogram_tester.h"
17 #include "base/test/task_environment.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/time/time.h"
20 #include "components/os_crypt/os_crypt_mocker.h"
21 #include "components/prefs/scoped_user_pref_update.h"
22 #include "components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h"
23 #include "components/signin/internal/identity_manager/primary_account_manager.h"
24 #include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
25 #include "components/signin/public/base/account_consistency_method.h"
26 #include "components/signin/public/base/device_id_helper.h"
27 #include "components/signin/public/base/signin_pref_names.h"
28 #include "components/signin/public/base/test_signin_client.h"
29 #include "components/signin/public/identity_manager/account_info.h"
30 #include "components/signin/public/webdata/token_web_data.h"
31 #include "components/sync_preferences/testing_pref_service_syncable.h"
32 #include "components/webdata/common/web_data_service_base.h"
33 #include "components/webdata/common/web_database_service.h"
34 #include "google_apis/gaia/gaia_constants.h"
35 #include "google_apis/gaia/gaia_urls.h"
36 #include "google_apis/gaia/google_service_auth_error.h"
37 #include "google_apis/gaia/oauth2_access_token_consumer.h"
38 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
39 #include "google_apis/gaia/oauth2_access_token_manager_test_util.h"
40 #include "net/http/http_status_code.h"
41 #include "services/network/public/cpp/shared_url_loader_factory.h"
42 #include "services/network/test/test_network_connection_tracker.h"
43 #include "testing/gmock/include/gmock/gmock.h"
44 #include "testing/gtest/include/gtest/gtest.h"
45
46 // Defining constant here to handle backward compatiblity tests, but this
47 // constant is no longer used in current versions of chrome.
48 static const char kLSOService[] = "lso";
49 static const char kEmail[] = "user@gmail.com";
50
51 namespace {
52
53 // Create test account info.
CreateTestAccountInfo(const std::string & name,bool is_hosted_domain,bool is_valid)54 AccountInfo CreateTestAccountInfo(const std::string& name,
55 bool is_hosted_domain,
56 bool is_valid) {
57 AccountInfo account_info;
58 account_info.account_id = CoreAccountId(name);
59 account_info.gaia = name;
60 account_info.email = name + "@email.com";
61 account_info.full_name = "name";
62 account_info.given_name = "name";
63 if (is_valid) {
64 account_info.hosted_domain =
65 is_hosted_domain ? "example.com" : kNoHostedDomainFound;
66 }
67 account_info.locale = "en";
68 account_info.picture_url = "https://example.com";
69 account_info.is_child_account = false;
70 EXPECT_EQ(is_valid, account_info.IsValid());
71 return account_info;
72 }
73
74 } // namespace
75
76 class MutableProfileOAuth2TokenServiceDelegateTest
77 : public testing::Test,
78 public OAuth2AccessTokenConsumer,
79 public ProfileOAuth2TokenServiceObserver,
80 public WebDataServiceConsumer {
81 public:
MutableProfileOAuth2TokenServiceDelegateTest()82 MutableProfileOAuth2TokenServiceDelegateTest()
83 : task_environment_(
84 base::test::TaskEnvironment::MainThreadType::UI,
85 base::test::TaskEnvironment::ThreadPoolExecutionMode::ASYNC),
86 access_token_success_count_(0),
87 access_token_failure_count_(0),
88 access_token_failure_(GoogleServiceAuthError::NONE),
89 token_available_count_(0),
90 token_revoked_count_(0),
91 tokens_loaded_count_(0),
92 end_batch_changes_(0),
93 auth_error_changed_count_(0),
94 revoke_all_tokens_on_load_(false) {}
95
SetUp()96 void SetUp() override {
97 OSCryptMocker::SetUp();
98
99 MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs(
100 pref_service_.registry());
101 AccountTrackerService::RegisterPrefs(pref_service_.registry());
102 PrimaryAccountManager::RegisterProfilePrefs(pref_service_.registry());
103 client_.reset(new TestSigninClient(&pref_service_));
104 client_->GetTestURLLoaderFactory()->AddResponse(
105 GaiaUrls::GetInstance()->oauth2_revoke_url().spec(), "");
106 LoadTokenDatabase();
107 account_tracker_service_.Initialize(&pref_service_, base::FilePath());
108 }
109
TearDown()110 void TearDown() override {
111 base::RunLoop().RunUntilIdle();
112 if (oauth2_service_delegate_) {
113 oauth2_service_delegate_->RemoveObserver(this);
114 oauth2_service_delegate_->Shutdown();
115 }
116 OSCryptMocker::TearDown();
117 }
118
LoadTokenDatabase()119 void LoadTokenDatabase() {
120 base::FilePath path(WebDatabase::kInMemoryPath);
121 scoped_refptr<WebDatabaseService> web_database =
122 new WebDatabaseService(path, base::ThreadTaskRunnerHandle::Get(),
123 base::ThreadTaskRunnerHandle::Get());
124 web_database->AddTable(std::make_unique<TokenServiceTable>());
125 web_database->LoadDatabase();
126 token_web_data_ =
127 new TokenWebData(web_database, base::ThreadTaskRunnerHandle::Get(),
128 base::ThreadTaskRunnerHandle::Get());
129 token_web_data_->Init(base::NullCallback());
130 }
131
AddSuccessfulOAuhTokenResponse()132 void AddSuccessfulOAuhTokenResponse() {
133 client_->GetTestURLLoaderFactory()->AddResponse(
134 GaiaUrls::GetInstance()->oauth2_token_url().spec(),
135 GetValidTokenResponse("token", 3600));
136 }
137
138 std::unique_ptr<MutableProfileOAuth2TokenServiceDelegate>
CreateOAuth2ServiceDelegate(signin::AccountConsistencyMethod account_consistency)139 CreateOAuth2ServiceDelegate(
140 signin::AccountConsistencyMethod account_consistency) {
141 return std::make_unique<MutableProfileOAuth2TokenServiceDelegate>(
142 client_.get(), &account_tracker_service_,
143 network::TestNetworkConnectionTracker::GetInstance(), token_web_data_,
144 account_consistency, revoke_all_tokens_on_load_,
145 MutableProfileOAuth2TokenServiceDelegate::FixRequestErrorCallback());
146 }
147
InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod account_consistency)148 void InitializeOAuth2ServiceDelegate(
149 signin::AccountConsistencyMethod account_consistency) {
150 oauth2_service_delegate_ = CreateOAuth2ServiceDelegate(account_consistency);
151 oauth2_service_delegate_->AddObserver(this);
152 }
153
AddAuthTokenManually(const std::string & service,const std::string & value)154 void AddAuthTokenManually(const std::string& service,
155 const std::string& value) {
156 if (token_web_data_)
157 token_web_data_->SetTokenForService(service, value);
158 }
159
160 // WebDataServiceConsumer implementation
OnWebDataServiceRequestDone(WebDataServiceBase::Handle h,std::unique_ptr<WDTypedResult> result)161 void OnWebDataServiceRequestDone(
162 WebDataServiceBase::Handle h,
163 std::unique_ptr<WDTypedResult> result) override {
164 DCHECK(!token_web_data_result_);
165 DCHECK_EQ(TOKEN_RESULT, result->GetType());
166 token_web_data_result_.reset(
167 static_cast<WDResult<TokenResult>*>(result.release()));
168 }
169
170 // OAuth2AccessTokenConusmer implementation
OnGetTokenSuccess(const OAuth2AccessTokenConsumer::TokenResponse & token_response)171 void OnGetTokenSuccess(
172 const OAuth2AccessTokenConsumer::TokenResponse& token_response) override {
173 ++access_token_success_count_;
174 }
175
OnGetTokenFailure(const GoogleServiceAuthError & error)176 void OnGetTokenFailure(const GoogleServiceAuthError& error) override {
177 ++access_token_failure_count_;
178 access_token_failure_ = error;
179 }
180
181 // ProfileOAuth2TokenServiceObserver implementation.
OnRefreshTokenAvailable(const CoreAccountId & account_id)182 void OnRefreshTokenAvailable(const CoreAccountId& account_id) override {
183 ++token_available_count_;
184 }
OnRefreshTokenRevoked(const CoreAccountId & account_id)185 void OnRefreshTokenRevoked(const CoreAccountId& account_id) override {
186 ++token_revoked_count_;
187 }
OnRefreshTokensLoaded()188 void OnRefreshTokensLoaded() override { ++tokens_loaded_count_; }
189
OnEndBatchChanges()190 void OnEndBatchChanges() override { ++end_batch_changes_; }
191
OnAuthErrorChanged(const CoreAccountId & account_id,const GoogleServiceAuthError & auth_error)192 void OnAuthErrorChanged(const CoreAccountId& account_id,
193 const GoogleServiceAuthError& auth_error) override {
194 ++auth_error_changed_count_;
195 }
196
197 // ProfileOAuth2TokenService callbacks.
OnRefreshTokenAvailableFromSource(const CoreAccountId & account_id,bool is_refresh_token_valid,const std::string & source)198 void OnRefreshTokenAvailableFromSource(const CoreAccountId& account_id,
199 bool is_refresh_token_valid,
200 const std::string& source) {
201 source_for_refresh_token_available_ = source;
202 }
OnRefreshTokenRevokedFromSource(const CoreAccountId & account_id,const std::string & source)203 void OnRefreshTokenRevokedFromSource(const CoreAccountId& account_id,
204 const std::string& source) {
205 source_for_refresh_token_revoked_ = source;
206 }
207
ResetObserverCounts()208 void ResetObserverCounts() {
209 token_available_count_ = 0;
210 token_revoked_count_ = 0;
211 tokens_loaded_count_ = 0;
212 end_batch_changes_ = 0;
213 auth_error_changed_count_ = 0;
214 }
215
ExpectNoNotifications()216 void ExpectNoNotifications() {
217 EXPECT_EQ(0, token_available_count_);
218 EXPECT_EQ(0, token_revoked_count_);
219 EXPECT_EQ(0, tokens_loaded_count_);
220 ResetObserverCounts();
221 }
222
ExpectOneTokenAvailableNotification()223 void ExpectOneTokenAvailableNotification() {
224 EXPECT_EQ(1, token_available_count_);
225 EXPECT_EQ(0, token_revoked_count_);
226 EXPECT_EQ(0, tokens_loaded_count_);
227 ResetObserverCounts();
228 }
229
ExpectOneTokenRevokedNotification()230 void ExpectOneTokenRevokedNotification() {
231 EXPECT_EQ(0, token_available_count_);
232 EXPECT_EQ(1, token_revoked_count_);
233 EXPECT_EQ(0, tokens_loaded_count_);
234 ResetObserverCounts();
235 }
236
ExpectOneTokensLoadedNotification()237 void ExpectOneTokensLoadedNotification() {
238 EXPECT_EQ(0, token_available_count_);
239 EXPECT_EQ(0, token_revoked_count_);
240 EXPECT_EQ(1, tokens_loaded_count_);
241 ResetObserverCounts();
242 }
243
244 protected:
245 base::test::TaskEnvironment task_environment_;
246 std::unique_ptr<TestSigninClient> client_;
247 std::unique_ptr<MutableProfileOAuth2TokenServiceDelegate>
248 oauth2_service_delegate_;
249 TestingOAuth2AccessTokenManagerConsumer consumer_;
250 sync_preferences::TestingPrefServiceSyncable pref_service_;
251 AccountTrackerService account_tracker_service_;
252 scoped_refptr<TokenWebData> token_web_data_;
253 std::unique_ptr<WDResult<TokenResult>> token_web_data_result_;
254 int access_token_success_count_;
255 int access_token_failure_count_;
256 GoogleServiceAuthError access_token_failure_;
257 int token_available_count_;
258 int token_revoked_count_;
259 int tokens_loaded_count_;
260 int end_batch_changes_;
261 int auth_error_changed_count_;
262 bool revoke_all_tokens_on_load_;
263 std::string source_for_refresh_token_available_;
264 std::string source_for_refresh_token_revoked_;
265 };
266
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,PersistenceDBUpgrade)267 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) {
268 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
269 CoreAccountId main_account_id("account_id");
270 std::string main_refresh_token("old_refresh_token");
271
272 // Populate DB with legacy tokens.
273 AddAuthTokenManually(GaiaConstants::kSyncService, "syncServiceToken");
274 AddAuthTokenManually(kLSOService, "lsoToken");
275 AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
276 main_refresh_token);
277
278 // Force LoadCredentials.
279 oauth2_service_delegate_->LoadCredentials(main_account_id);
280 base::RunLoop().RunUntilIdle();
281
282 // Legacy tokens get discarded, but the old refresh token is kept.
283 EXPECT_EQ(1, tokens_loaded_count_);
284 EXPECT_EQ(1, token_available_count_);
285 EXPECT_EQ(1, end_batch_changes_);
286 EXPECT_TRUE(
287 oauth2_service_delegate_->RefreshTokenIsAvailable(main_account_id));
288 EXPECT_EQ(1U, oauth2_service_delegate_->refresh_tokens_.size());
289 EXPECT_EQ(
290 main_refresh_token,
291 oauth2_service_delegate_->refresh_tokens_[main_account_id].refresh_token);
292
293 // Add an old legacy token to the DB, to ensure it will not overwrite existing
294 // credentials for main account.
295 AddAuthTokenManually(GaiaConstants::kGaiaOAuth2LoginRefreshToken,
296 "secondOldRefreshToken");
297 // Add some other legacy token. (Expected to get discarded).
298 AddAuthTokenManually(kLSOService, "lsoToken");
299 // Also add a token using PO2TS.UpdateCredentials and make sure upgrade does
300 // not wipe it.
301 CoreAccountId other_account_id("other_account_id");
302 std::string other_refresh_token("other_refresh_token");
303 oauth2_service_delegate_->UpdateCredentials(other_account_id,
304 other_refresh_token);
305 ResetObserverCounts();
306
307 // Force LoadCredentials.
308 oauth2_service_delegate_->LoadCredentials(main_account_id);
309 base::RunLoop().RunUntilIdle();
310
311 // Again legacy tokens get discarded, but since the main porfile account
312 // token is present it is not overwritten.
313 EXPECT_EQ(2, token_available_count_);
314 EXPECT_EQ(1, tokens_loaded_count_);
315 EXPECT_EQ(1, end_batch_changes_);
316 EXPECT_EQ(main_refresh_token,
317 oauth2_service_delegate_->GetRefreshToken(main_account_id));
318 EXPECT_TRUE(
319 oauth2_service_delegate_->RefreshTokenIsAvailable(main_account_id));
320 // TODO(fgorski): cover both using RefreshTokenIsAvailable() and then get the
321 // tokens using GetRefreshToken()
322 EXPECT_EQ(2U, oauth2_service_delegate_->refresh_tokens_.size());
323 EXPECT_EQ(
324 main_refresh_token,
325 oauth2_service_delegate_->refresh_tokens_[main_account_id].refresh_token);
326 EXPECT_EQ(other_refresh_token,
327 oauth2_service_delegate_->refresh_tokens_[other_account_id]
328 .refresh_token);
329
330 oauth2_service_delegate_->RevokeAllCredentials();
331 EXPECT_EQ(2, end_batch_changes_);
332 }
333
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,PersistenceRevokeCredentials)334 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
335 PersistenceRevokeCredentials) {
336 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
337 CoreAccountId account_id_1("account_id_1");
338 std::string refresh_token_1 = "refresh_token_1";
339 CoreAccountId account_id_2("account_id_2");
340 std::string refresh_token_2 = "refresh_token_2";
341
342 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_1));
343 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_2));
344 oauth2_service_delegate_->UpdateCredentials(account_id_1, refresh_token_1);
345 oauth2_service_delegate_->UpdateCredentials(account_id_2, refresh_token_2);
346 EXPECT_EQ(2, end_batch_changes_);
347
348 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_1));
349 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_2));
350
351 ResetObserverCounts();
352 oauth2_service_delegate_->RevokeCredentials(account_id_1);
353 EXPECT_EQ(1, end_batch_changes_);
354 ExpectOneTokenRevokedNotification();
355
356 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_1));
357 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_2));
358
359 oauth2_service_delegate_->RevokeAllCredentials();
360 EXPECT_EQ(0, token_available_count_);
361 EXPECT_EQ(1, token_revoked_count_);
362 EXPECT_EQ(0, tokens_loaded_count_);
363 EXPECT_EQ(1, end_batch_changes_);
364 ResetObserverCounts();
365 }
366
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadCredentialsStateEmptyPrimaryAccountId)367 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
368 LoadCredentialsStateEmptyPrimaryAccountId) {
369 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
370 // Ensure DB is clean.
371 oauth2_service_delegate_->RevokeAllCredentials();
372
373 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_NOT_STARTED,
374 oauth2_service_delegate_->load_credentials_state());
375 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
376 base::RunLoop().RunUntilIdle();
377 EXPECT_EQ(
378 signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
379 oauth2_service_delegate_->load_credentials_state());
380 }
381
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,PersistenceLoadCredentials)382 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
383 PersistenceLoadCredentials) {
384 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
385 const CoreAccountId account_id("account_id");
386 const CoreAccountId account_id2("account_id_2");
387
388 // Ensure DB is clean.
389 oauth2_service_delegate_->RevokeAllCredentials();
390 ResetObserverCounts();
391
392 // Perform a load from an empty DB.
393 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_NOT_STARTED,
394 oauth2_service_delegate_->load_credentials_state());
395 oauth2_service_delegate_->LoadCredentials(account_id);
396 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS,
397 oauth2_service_delegate_->load_credentials_state());
398 base::RunLoop().RunUntilIdle();
399 EXPECT_EQ(signin::LoadCredentialsState::
400 LOAD_CREDENTIALS_FINISHED_WITH_NO_TOKEN_FOR_PRIMARY_ACCOUNT,
401 oauth2_service_delegate_->load_credentials_state());
402 EXPECT_EQ(GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
403 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
404 CREDENTIALS_MISSING),
405 oauth2_service_delegate_->GetAuthError(account_id));
406 EXPECT_EQ(1, end_batch_changes_);
407 EXPECT_EQ(1, auth_error_changed_count_);
408
409 // A"tokens loaded" notification should have been fired.
410 EXPECT_EQ(1, tokens_loaded_count_);
411
412 // As the delegate puts the primary account into the token map with an invalid
413 // token in the case of loading from an empty TB, a "token available"
414 // notification should have been fired as well.
415 EXPECT_EQ(1, token_available_count_);
416
417 ResetObserverCounts();
418
419 // LoadCredentials() guarantees that the account given to it as argument
420 // is in the refresh_token map.
421 EXPECT_EQ(1U, oauth2_service_delegate_->refresh_tokens_.size());
422 EXPECT_EQ(
423 GaiaConstants::kInvalidRefreshToken,
424 oauth2_service_delegate_->refresh_tokens_[account_id].refresh_token);
425 // Setup a DB with tokens that don't require upgrade and clear memory.
426 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
427 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
428 oauth2_service_delegate_->refresh_tokens_.clear();
429 EXPECT_EQ(2, end_batch_changes_);
430 EXPECT_EQ(2, auth_error_changed_count_);
431 ResetObserverCounts();
432
433 oauth2_service_delegate_->LoadCredentials(account_id);
434 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS,
435 oauth2_service_delegate_->load_credentials_state());
436 base::RunLoop().RunUntilIdle();
437 EXPECT_EQ(
438 signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
439 oauth2_service_delegate_->load_credentials_state());
440 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
441 oauth2_service_delegate_->GetAuthError(account_id));
442 EXPECT_EQ(2, token_available_count_);
443 EXPECT_EQ(0, token_revoked_count_);
444 EXPECT_EQ(1, tokens_loaded_count_);
445 EXPECT_EQ(1, end_batch_changes_);
446 EXPECT_EQ(2, auth_error_changed_count_);
447 ResetObserverCounts();
448
449 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id));
450 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id2));
451
452 oauth2_service_delegate_->RevokeAllCredentials();
453 EXPECT_EQ(0, token_available_count_);
454 EXPECT_EQ(2, token_revoked_count_);
455 EXPECT_EQ(0, tokens_loaded_count_);
456 EXPECT_EQ(1, end_batch_changes_);
457 EXPECT_EQ(0, auth_error_changed_count_);
458 ResetObserverCounts();
459 }
460
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,PersistenceLoadCredentialsEmptyPrimaryAccountId_DiceEnabled)461 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
462 PersistenceLoadCredentialsEmptyPrimaryAccountId_DiceEnabled) {
463 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
464 const CoreAccountId account_id("account_id");
465 const CoreAccountId account_id2("account_id_2");
466
467 // Ensure DB is clean.
468 oauth2_service_delegate_->RevokeAllCredentials();
469 ResetObserverCounts();
470 // Perform a load from an empty DB.
471 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_NOT_STARTED,
472 oauth2_service_delegate_->load_credentials_state());
473 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
474 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS,
475 oauth2_service_delegate_->load_credentials_state());
476 base::RunLoop().RunUntilIdle();
477 EXPECT_EQ(
478 signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
479 oauth2_service_delegate_->load_credentials_state());
480 EXPECT_EQ(1, end_batch_changes_);
481 EXPECT_EQ(0, auth_error_changed_count_);
482 ExpectOneTokensLoadedNotification();
483
484 // No account should be present in the refresh token as no primary account
485 // was passed to the token service.
486 EXPECT_TRUE(oauth2_service_delegate_->refresh_tokens_.empty());
487
488 // Setup a DB with tokens that don't require upgrade and clear memory.
489 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
490 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
491 oauth2_service_delegate_->refresh_tokens_.clear();
492 EXPECT_EQ(2, end_batch_changes_);
493 EXPECT_EQ(2, auth_error_changed_count_);
494 ResetObserverCounts();
495
496 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
497 EXPECT_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS,
498 oauth2_service_delegate_->load_credentials_state());
499 base::RunLoop().RunUntilIdle();
500 EXPECT_EQ(
501 signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
502 oauth2_service_delegate_->load_credentials_state());
503 EXPECT_EQ(2, token_available_count_);
504 EXPECT_EQ(0, token_revoked_count_);
505 EXPECT_EQ(1, tokens_loaded_count_);
506 EXPECT_EQ(1, end_batch_changes_);
507 EXPECT_EQ(2, auth_error_changed_count_);
508 ResetObserverCounts();
509
510 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id));
511 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id2));
512
513 oauth2_service_delegate_->RevokeAllCredentials();
514 EXPECT_EQ(0, token_available_count_);
515 EXPECT_EQ(2, token_revoked_count_);
516 EXPECT_EQ(0, tokens_loaded_count_);
517 EXPECT_EQ(1, end_batch_changes_);
518 EXPECT_EQ(0, auth_error_changed_count_);
519 ResetObserverCounts();
520 }
521
522 // Checks that tokens are loaded and prefs::kTokenServiceDiceCompatible is set
523 // to true if the tokens are loaded after the Dice migration.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadAfterDiceMigration)524 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadAfterDiceMigration) {
525 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
526 ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible));
527
528 // Add account info to the account tracker.
529 AccountInfo primary_account = CreateTestAccountInfo(
530 "primary_account", false /* is_hosted_domain*/, true /* is_valid*/);
531 account_tracker_service_.SeedAccountInfo(primary_account);
532 AddAuthTokenManually("AccountId-" + primary_account.account_id.ToString(),
533 "refresh_token");
534
535 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
536 base::RunLoop().RunUntilIdle();
537
538 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
539 primary_account.account_id));
540 EXPECT_EQ(
541 signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
542 oauth2_service_delegate_->load_credentials_state());
543
544 ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible));
545 }
546
547 // Checks that prefs::kTokenServiceDiceCompatible is set to true if the tokens
548 // are loaded after the Dice migration, even if there was a database read error.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadAfterDiceMigrationWithError)549 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
550 LoadAfterDiceMigrationWithError) {
551 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
552 ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible));
553
554 // Shutdown the database to trigger a database read error.
555 token_web_data_->ShutdownDatabase();
556
557 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
558 base::RunLoop().RunUntilIdle();
559
560 EXPECT_EQ(0u, oauth2_service_delegate_->GetAccounts().size());
561 EXPECT_EQ(signin::LoadCredentialsState::
562 LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED,
563 oauth2_service_delegate_->load_credentials_state());
564
565 ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible));
566 }
567
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadCredentialsClearsTokenDBWhenNoPrimaryAccount_DiceDisabled)568 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
569 LoadCredentialsClearsTokenDBWhenNoPrimaryAccount_DiceDisabled) {
570 // Populate DB with 2 valid tokens.
571 AddAuthTokenManually("AccountId-12345", "refresh_token");
572 AddAuthTokenManually("AccountId-67890", "refresh_token");
573
574 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
575 oauth2_service_delegate_->LoadCredentials(
576 /*primary_account_id=*/CoreAccountId());
577 base::RunLoop().RunUntilIdle();
578
579 // No tokens were loaded.
580 EXPECT_EQ(1, tokens_loaded_count_);
581 EXPECT_EQ(0, token_available_count_);
582 EXPECT_EQ(2, token_revoked_count_);
583 EXPECT_EQ(1, end_batch_changes_);
584 EXPECT_EQ(0U, oauth2_service_delegate_->refresh_tokens_.size());
585
586 // Handle to the request reading tokens from database.
587 token_web_data_->GetAllTokens(this);
588 base::RunLoop().RunUntilIdle();
589 ASSERT_TRUE(token_web_data_result_.get());
590 ASSERT_EQ(0u, token_web_data_result_->GetValue().tokens.size());
591 }
592
593 // Tests that calling UpdateCredentials revokes the old token, without sending
594 // the notification.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,RevokeOnUpdate)595 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, RevokeOnUpdate) {
596 const CoreAccountId account_id("account_id");
597
598 // Add a token.
599 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
600 ASSERT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
601 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
602 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
603 ExpectOneTokenAvailableNotification();
604
605 // Updating the token does not revoke the old one.
606 // Regression test for http://crbug.com/865189
607 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token2");
608 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
609 ExpectOneTokenAvailableNotification();
610
611 // Flush the server revokes.
612 base::RunLoop().RunUntilIdle();
613 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
614
615 // Set the same token again.
616 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token2");
617 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
618 ExpectNoNotifications();
619
620 // Clear the token.
621 oauth2_service_delegate_->RevokeAllCredentials();
622 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
623 ExpectOneTokenRevokedNotification();
624
625 // Flush the server revokes.
626 base::RunLoop().RunUntilIdle();
627 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
628 }
629
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,DelayedRevoke)630 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, DelayedRevoke) {
631 const CoreAccountId account_id("account_id");
632
633 client_->SetNetworkCallsDelayed(true);
634 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
635 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
636 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
637 oauth2_service_delegate_->RevokeCredentials(account_id);
638
639 // The revoke does not start until network calls are unblocked.
640 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
641 base::RunLoop().RunUntilIdle();
642 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
643
644 // Unblock network calls, and check that the revocation goes through.
645 client_->SetNetworkCallsDelayed(false);
646 base::RunLoop().RunUntilIdle();
647 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
648 }
649
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,ShutdownDuringRevoke)650 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ShutdownDuringRevoke) {
651 const CoreAccountId account_id("account_id");
652
653 // Shutdown cancels the revocation.
654 client_->SetNetworkCallsDelayed(true);
655 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
656 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
657 oauth2_service_delegate_->RevokeCredentials(account_id);
658 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
659
660 // Shutdown.
661 oauth2_service_delegate_->Shutdown();
662 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
663
664 // Unblocking network calls after shutdown does not crash.
665 client_->SetNetworkCallsDelayed(false);
666 base::RunLoop().RunUntilIdle();
667 }
668
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,RevokeRetries)669 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, RevokeRetries) {
670 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
671 const std::string url = GaiaUrls::GetInstance()->oauth2_revoke_url().spec();
672 const CoreAccountId account_id("account_id");
673 // Revokes will remain in "pending" state.
674 client_->GetTestURLLoaderFactory()->ClearResponses();
675
676 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
677 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
678 EXPECT_FALSE(client_->GetTestURLLoaderFactory()->IsPending(url));
679
680 oauth2_service_delegate_->RevokeCredentials(account_id);
681 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
682 EXPECT_TRUE(client_->GetTestURLLoaderFactory()->IsPending(url));
683 // Fail and retry.
684 client_->GetTestURLLoaderFactory()->SimulateResponseForPendingRequest(
685 url, std::string(), net::HTTP_INTERNAL_SERVER_ERROR);
686 EXPECT_TRUE(client_->GetTestURLLoaderFactory()->IsPending(url));
687 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
688 // Fail and retry.
689 client_->GetTestURLLoaderFactory()->SimulateResponseForPendingRequest(
690 url, std::string(), net::HTTP_INTERNAL_SERVER_ERROR);
691 EXPECT_TRUE(client_->GetTestURLLoaderFactory()->IsPending(url));
692 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
693 // Do not retry after third attempt.
694 client_->GetTestURLLoaderFactory()->SimulateResponseForPendingRequest(
695 url, std::string(), net::HTTP_INTERNAL_SERVER_ERROR);
696 EXPECT_FALSE(client_->GetTestURLLoaderFactory()->IsPending(url));
697 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
698
699 // No retry after success.
700 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
701 oauth2_service_delegate_->RevokeCredentials(account_id);
702 EXPECT_EQ(1u, oauth2_service_delegate_->server_revokes_.size());
703 EXPECT_TRUE(client_->GetTestURLLoaderFactory()->IsPending(url));
704 client_->GetTestURLLoaderFactory()->SimulateResponseForPendingRequest(
705 url, std::string(), net::HTTP_OK);
706 EXPECT_FALSE(client_->GetTestURLLoaderFactory()->IsPending(url));
707 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
708 }
709
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,UpdateInvalidToken)710 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, UpdateInvalidToken) {
711 const CoreAccountId account_id("account_id");
712 // Add the invalid token.
713 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
714 ASSERT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
715 oauth2_service_delegate_->UpdateCredentials(
716 account_id, GaiaConstants::kInvalidRefreshToken);
717 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
718 EXPECT_EQ(1, auth_error_changed_count_);
719 ExpectOneTokenAvailableNotification();
720
721 // The account is in authentication error.
722 EXPECT_EQ(GoogleServiceAuthError(
723 GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
724 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
725 CREDENTIALS_REJECTED_BY_CLIENT)),
726 oauth2_service_delegate_->GetAuthError(account_id));
727
728 // Update the token: authentication error is fixed, no actual server
729 // revocation.
730 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
731 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
732 EXPECT_EQ(1, auth_error_changed_count_);
733 ExpectOneTokenAvailableNotification();
734 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
735 oauth2_service_delegate_->GetAuthError(account_id));
736 }
737
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,InvalidateTokensForMultilogin)738 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
739 InvalidateTokensForMultilogin) {
740 class TokenServiceErrorObserver : public ProfileOAuth2TokenServiceObserver {
741 public:
742 MOCK_METHOD2(OnAuthErrorChanged,
743 void(const CoreAccountId&, const GoogleServiceAuthError&));
744 };
745
746 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
747 TokenServiceErrorObserver observer;
748 oauth2_service_delegate_->AddObserver(&observer);
749
750 const CoreAccountId account_id1("account_id1");
751 const CoreAccountId account_id2("account_id2");
752
753 // This will be fired from UpdateCredentials.
754 EXPECT_CALL(
755 observer,
756 OnAuthErrorChanged(::testing::_, GoogleServiceAuthError::AuthErrorNone()))
757 .Times(2);
758 oauth2_service_delegate_->UpdateCredentials(account_id1, "refresh_token1");
759 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
760
761 testing::Mock::VerifyAndClearExpectations(&observer);
762
763 // This should be fired after error is set.
764 EXPECT_CALL(
765 observer,
766 OnAuthErrorChanged(account_id1,
767 GoogleServiceAuthError(
768 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)))
769 .Times(1);
770
771 oauth2_service_delegate_->InvalidateTokenForMultilogin(account_id1);
772 EXPECT_EQ(oauth2_service_delegate_->GetAuthError(account_id1).state(),
773 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
774 EXPECT_EQ(oauth2_service_delegate_->GetAuthError(account_id2).state(),
775 GoogleServiceAuthError::NONE);
776
777 oauth2_service_delegate_->RemoveObserver(&observer);
778 }
779
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadInvalidToken)780 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadInvalidToken) {
781 pref_service_.SetBoolean(prefs::kTokenServiceDiceCompatible, true);
782 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
783 std::map<std::string, std::string> tokens;
784 const CoreAccountId account_id("account_id");
785 tokens["AccountId-account_id"] = GaiaConstants::kInvalidRefreshToken;
786
787 oauth2_service_delegate_->LoadAllCredentialsIntoMemory(tokens);
788
789 EXPECT_EQ(1u, oauth2_service_delegate_->GetAccounts().size());
790 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id));
791 EXPECT_STREQ(GaiaConstants::kInvalidRefreshToken,
792 oauth2_service_delegate_->GetRefreshToken(account_id).c_str());
793
794 // The account is in authentication error.
795 EXPECT_EQ(GoogleServiceAuthError(
796 GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
797 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
798 CREDENTIALS_REJECTED_BY_CLIENT)),
799 oauth2_service_delegate_->GetAuthError(account_id));
800 }
801
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,GetTokenForMultilogin)802 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GetTokenForMultilogin) {
803 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
804 const CoreAccountId account_id1("account_id1");
805 const CoreAccountId account_id2("account_id2");
806
807 oauth2_service_delegate_->UpdateCredentials(account_id1, "refresh_token1");
808 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
809 oauth2_service_delegate_->UpdateAuthError(
810 account_id2,
811 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
812
813 EXPECT_EQ(oauth2_service_delegate_->GetTokenForMultilogin(account_id1),
814 "refresh_token1");
815 EXPECT_EQ(oauth2_service_delegate_->GetTokenForMultilogin(account_id2),
816 std::string());
817 EXPECT_EQ(oauth2_service_delegate_->GetTokenForMultilogin(
818 CoreAccountId("unknown account")),
819 std::string());
820 }
821
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,PersistenceNotifications)822 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceNotifications) {
823 const CoreAccountId account_id("account_id");
824
825 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
826 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
827 ExpectOneTokenAvailableNotification();
828
829 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
830 ExpectNoNotifications();
831
832 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token2");
833 ExpectOneTokenAvailableNotification();
834
835 oauth2_service_delegate_->RevokeCredentials(account_id);
836 ExpectOneTokenRevokedNotification();
837
838 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token2");
839 ExpectOneTokenAvailableNotification();
840
841 oauth2_service_delegate_->RevokeAllCredentials();
842 ResetObserverCounts();
843 }
844
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,GetAccounts)845 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GetAccounts) {
846 const CoreAccountId account_id1("account_id1");
847 const CoreAccountId account_id2("account_id2");
848
849 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
850 EXPECT_TRUE(oauth2_service_delegate_->GetAccounts().empty());
851
852 oauth2_service_delegate_->UpdateCredentials(account_id1, "refresh_token1");
853 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
854 std::vector<CoreAccountId> accounts = oauth2_service_delegate_->GetAccounts();
855 EXPECT_EQ(2u, accounts.size());
856 EXPECT_EQ(1, count(accounts.begin(), accounts.end(), account_id1));
857 EXPECT_EQ(1, count(accounts.begin(), accounts.end(), account_id2));
858 oauth2_service_delegate_->RevokeCredentials(account_id2);
859 accounts = oauth2_service_delegate_->GetAccounts();
860 EXPECT_EQ(1u, oauth2_service_delegate_->GetAccounts().size());
861 EXPECT_EQ(1, count(accounts.begin(), accounts.end(), account_id1));
862 }
863
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,FetchPersistentError)864 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, FetchPersistentError) {
865 const CoreAccountId email(kEmail);
866
867 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
868 oauth2_service_delegate_->UpdateCredentials(email, "refreshToken");
869 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
870 oauth2_service_delegate_->GetAuthError(email));
871
872 GoogleServiceAuthError authfail(
873 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
874 oauth2_service_delegate_->UpdateAuthError(email, authfail);
875 EXPECT_NE(GoogleServiceAuthError::AuthErrorNone(),
876 oauth2_service_delegate_->GetAuthError(email));
877
878 // Create a "success" fetch we don't expect to get called.
879 AddSuccessfulOAuhTokenResponse();
880
881 EXPECT_EQ(0, access_token_success_count_);
882 EXPECT_EQ(0, access_token_failure_count_);
883 std::vector<std::string> scope_list;
884 scope_list.push_back("scope");
885 std::unique_ptr<OAuth2AccessTokenFetcher> fetcher =
886 oauth2_service_delegate_->CreateAccessTokenFetcher(
887 email, oauth2_service_delegate_->GetURLLoaderFactory(), this);
888 fetcher->Start("foo", "bar", scope_list);
889 base::RunLoop().RunUntilIdle();
890 EXPECT_EQ(0, access_token_success_count_);
891 EXPECT_EQ(1, access_token_failure_count_);
892 }
893
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,RetryBackoff)894 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, RetryBackoff) {
895 const CoreAccountId email(kEmail);
896
897 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
898 oauth2_service_delegate_->UpdateCredentials(email, "refreshToken");
899 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
900 oauth2_service_delegate_->GetAuthError(email));
901
902 GoogleServiceAuthError authfail(GoogleServiceAuthError::SERVICE_UNAVAILABLE);
903 oauth2_service_delegate_->UpdateAuthError(email, authfail);
904 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
905 oauth2_service_delegate_->GetAuthError(email));
906
907 // Create a "success" fetch we don't expect to get called just yet.
908 AddSuccessfulOAuhTokenResponse();
909
910 // Transient error will repeat until backoff period expires.
911 EXPECT_EQ(0, access_token_success_count_);
912 EXPECT_EQ(0, access_token_failure_count_);
913 std::vector<std::string> scope_list;
914 scope_list.push_back("scope");
915 std::unique_ptr<OAuth2AccessTokenFetcher> fetcher1 =
916 oauth2_service_delegate_->CreateAccessTokenFetcher(
917 email, oauth2_service_delegate_->GetURLLoaderFactory(), this);
918 fetcher1->Start("foo", "bar", scope_list);
919 base::RunLoop().RunUntilIdle();
920 EXPECT_EQ(0, access_token_success_count_);
921 EXPECT_EQ(1, access_token_failure_count_);
922 // Expect a positive backoff time.
923 EXPECT_GT(oauth2_service_delegate_->backoff_entry_.GetTimeUntilRelease(),
924 base::TimeDelta());
925
926 // Pretend that backoff has expired and try again.
927 oauth2_service_delegate_->backoff_entry_.SetCustomReleaseTime(
928 base::TimeTicks());
929 std::unique_ptr<OAuth2AccessTokenFetcher> fetcher2 =
930 oauth2_service_delegate_->CreateAccessTokenFetcher(
931 email, oauth2_service_delegate_->GetURLLoaderFactory(), this);
932 fetcher2->Start("foo", "bar", scope_list);
933 base::RunLoop().RunUntilIdle();
934 EXPECT_EQ(1, access_token_success_count_);
935 EXPECT_EQ(1, access_token_failure_count_);
936 }
937
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,ResetBackoff)938 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ResetBackoff) {
939 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
940 const CoreAccountId account_id("account_id");
941 oauth2_service_delegate_->UpdateCredentials(account_id, "refreshToken");
942 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
943 oauth2_service_delegate_->GetAuthError(account_id));
944
945 GoogleServiceAuthError authfail(GoogleServiceAuthError::SERVICE_UNAVAILABLE);
946 oauth2_service_delegate_->UpdateAuthError(account_id, authfail);
947 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
948 oauth2_service_delegate_->GetAuthError(account_id));
949
950 // Create a "success" fetch we don't expect to get called just yet.
951 AddSuccessfulOAuhTokenResponse();
952
953 // Transient error will repeat until backoff period expires.
954 EXPECT_EQ(0, access_token_success_count_);
955 EXPECT_EQ(0, access_token_failure_count_);
956 std::vector<std::string> scope_list;
957 scope_list.push_back("scope");
958 std::unique_ptr<OAuth2AccessTokenFetcher> fetcher1 =
959 oauth2_service_delegate_->CreateAccessTokenFetcher(
960 account_id, oauth2_service_delegate_->GetURLLoaderFactory(), this);
961 fetcher1->Start("foo", "bar", scope_list);
962 base::RunLoop().RunUntilIdle();
963 EXPECT_EQ(0, access_token_success_count_);
964 EXPECT_EQ(1, access_token_failure_count_);
965
966 // Notify of network change and ensure that request now runs.
967 oauth2_service_delegate_->OnConnectionChanged(
968 network::mojom::ConnectionType::CONNECTION_WIFI);
969 std::unique_ptr<OAuth2AccessTokenFetcher> fetcher2 =
970 oauth2_service_delegate_->CreateAccessTokenFetcher(
971 account_id, oauth2_service_delegate_->GetURLLoaderFactory(), this);
972 fetcher2->Start("foo", "bar", scope_list);
973 base::RunLoop().RunUntilIdle();
974 EXPECT_EQ(1, access_token_success_count_);
975 EXPECT_EQ(1, access_token_failure_count_);
976 }
977
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,CanonicalizeAccountId)978 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, CanonicalizeAccountId) {
979 pref_service_.SetInteger(prefs::kAccountIdMigrationState,
980 AccountTrackerService::MIGRATION_NOT_STARTED);
981 pref_service_.SetBoolean(prefs::kTokenServiceDiceCompatible, true);
982 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
983 std::map<std::string, std::string> tokens;
984 tokens["AccountId-user@gmail.com"] = "refresh_token";
985 tokens["AccountId-Foo.Bar@gmail.com"] = "refresh_token";
986 tokens["AccountId-12345"] = "refresh_token";
987
988 oauth2_service_delegate_->LoadAllCredentialsIntoMemory(tokens);
989
990 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
991 CoreAccountId("user@gmail.com")));
992 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
993 CoreAccountId("foobar@gmail.com")));
994 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
995 CoreAccountId("12345")));
996 }
997
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,CanonAndNonCanonAccountId)998 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
999 CanonAndNonCanonAccountId) {
1000 pref_service_.SetBoolean(prefs::kTokenServiceDiceCompatible, true);
1001 pref_service_.SetInteger(prefs::kAccountIdMigrationState,
1002 AccountTrackerService::MIGRATION_NOT_STARTED);
1003 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
1004 std::map<std::string, std::string> tokens;
1005 tokens["AccountId-Foo.Bar@gmail.com"] = "bad_token";
1006 tokens["AccountId-foobar@gmail.com"] = "good_token";
1007
1008 oauth2_service_delegate_->LoadAllCredentialsIntoMemory(tokens);
1009
1010 EXPECT_EQ(1u, oauth2_service_delegate_->GetAccounts().size());
1011 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
1012 CoreAccountId("foobar@gmail.com")));
1013 EXPECT_STREQ("good_token",
1014 oauth2_service_delegate_
1015 ->GetRefreshToken(CoreAccountId("foobar@gmail.com"))
1016 .c_str());
1017 }
1018
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,ShutdownService)1019 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ShutdownService) {
1020 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
1021 EXPECT_TRUE(oauth2_service_delegate_->GetAccounts().empty());
1022 const CoreAccountId account_id1("account_id1");
1023 const CoreAccountId account_id2("account_id2");
1024
1025 oauth2_service_delegate_->UpdateCredentials(account_id1, "refresh_token1");
1026 oauth2_service_delegate_->UpdateCredentials(account_id2, "refresh_token2");
1027 std::vector<CoreAccountId> accounts = oauth2_service_delegate_->GetAccounts();
1028 EXPECT_EQ(2u, accounts.size());
1029 EXPECT_EQ(1, count(accounts.begin(), accounts.end(), account_id1));
1030 EXPECT_EQ(1, count(accounts.begin(), accounts.end(), account_id2));
1031 oauth2_service_delegate_->LoadCredentials(account_id1);
1032 oauth2_service_delegate_->UpdateCredentials(account_id1, "refresh_token3");
1033 oauth2_service_delegate_->Shutdown();
1034 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
1035 EXPECT_TRUE(oauth2_service_delegate_->refresh_tokens_.empty());
1036 EXPECT_EQ(0, oauth2_service_delegate_->web_data_service_request_);
1037 }
1038
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,GaiaIdMigration)1039 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GaiaIdMigration) {
1040 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
1041 if (account_tracker_service_.GetMigrationState() !=
1042 AccountTrackerService::MIGRATION_NOT_STARTED) {
1043 std::string email = "foo@gmail.com";
1044 std::string gaia_id = "foo's gaia id";
1045 const CoreAccountId acc_id_email(email);
1046 const CoreAccountId acc_id_gaia_id(gaia_id);
1047
1048 pref_service_.SetInteger(prefs::kAccountIdMigrationState,
1049 AccountTrackerService::MIGRATION_NOT_STARTED);
1050
1051 ListPrefUpdate update(&pref_service_, prefs::kAccountInfo);
1052 update->Clear();
1053 auto dict = std::make_unique<base::DictionaryValue>();
1054 dict->SetString("account_id", email);
1055 dict->SetString("email", email);
1056 dict->SetString("gaia", gaia_id);
1057 update->Append(std::move(dict));
1058 account_tracker_service_.Shutdown();
1059 account_tracker_service_.Initialize(&pref_service_, base::FilePath());
1060
1061 AddAuthTokenManually("AccountId-" + email, "refresh_token");
1062 oauth2_service_delegate_->LoadCredentials(acc_id_gaia_id);
1063 base::RunLoop().RunUntilIdle();
1064
1065 EXPECT_EQ(1, tokens_loaded_count_);
1066 EXPECT_EQ(1, token_available_count_);
1067 EXPECT_EQ(1, end_batch_changes_);
1068
1069 std::vector<CoreAccountId> accounts =
1070 oauth2_service_delegate_->GetAccounts();
1071 EXPECT_EQ(1u, accounts.size());
1072
1073 EXPECT_FALSE(
1074 oauth2_service_delegate_->RefreshTokenIsAvailable(acc_id_email));
1075 EXPECT_TRUE(
1076 oauth2_service_delegate_->RefreshTokenIsAvailable(acc_id_gaia_id));
1077
1078 account_tracker_service_.SetMigrationDone();
1079 oauth2_service_delegate_->Shutdown();
1080 ResetObserverCounts();
1081
1082 oauth2_service_delegate_->LoadCredentials(acc_id_gaia_id);
1083 base::RunLoop().RunUntilIdle();
1084
1085 EXPECT_EQ(1, tokens_loaded_count_);
1086 EXPECT_EQ(1, token_available_count_);
1087 EXPECT_EQ(1, end_batch_changes_);
1088
1089 EXPECT_FALSE(
1090 oauth2_service_delegate_->RefreshTokenIsAvailable(acc_id_email));
1091 EXPECT_TRUE(
1092 oauth2_service_delegate_->RefreshTokenIsAvailable(acc_id_gaia_id));
1093 accounts = oauth2_service_delegate_->GetAccounts();
1094 EXPECT_EQ(1u, accounts.size());
1095 }
1096 }
1097
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,GaiaIdMigrationCrashInTheMiddle)1098 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
1099 GaiaIdMigrationCrashInTheMiddle) {
1100 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
1101 if (account_tracker_service_.GetMigrationState() !=
1102 AccountTrackerService::MIGRATION_NOT_STARTED) {
1103 std::string email1 = "foo@gmail.com";
1104 std::string gaia_id1 = "foo's gaia id";
1105 std::string email2 = "bar@gmail.com";
1106 std::string gaia_id2 = "bar's gaia id";
1107 const CoreAccountId acc_email1(email1);
1108 const CoreAccountId acc_email2(email2);
1109 const CoreAccountId acc_gaia1(gaia_id1);
1110 const CoreAccountId acc_gaia2(gaia_id2);
1111
1112 pref_service_.SetInteger(prefs::kAccountIdMigrationState,
1113 AccountTrackerService::MIGRATION_NOT_STARTED);
1114
1115 ListPrefUpdate update(&pref_service_, prefs::kAccountInfo);
1116 update->Clear();
1117 auto dict = std::make_unique<base::DictionaryValue>();
1118 dict->SetString("account_id", email1);
1119 dict->SetString("email", email1);
1120 dict->SetString("gaia", gaia_id1);
1121 update->Append(std::move(dict));
1122 dict = std::make_unique<base::DictionaryValue>();
1123 dict->SetString("account_id", email2);
1124 dict->SetString("email", email2);
1125 dict->SetString("gaia", gaia_id2);
1126 update->Append(std::move(dict));
1127 account_tracker_service_.Shutdown();
1128 account_tracker_service_.Initialize(&pref_service_, base::FilePath());
1129
1130 AddAuthTokenManually("AccountId-" + email1, "refresh_token");
1131 AddAuthTokenManually("AccountId-" + email2, "refresh_token");
1132 AddAuthTokenManually("AccountId-" + gaia_id1, "refresh_token");
1133 oauth2_service_delegate_->LoadCredentials(acc_gaia1);
1134 base::RunLoop().RunUntilIdle();
1135
1136 EXPECT_EQ(1, tokens_loaded_count_);
1137 EXPECT_EQ(2, token_available_count_);
1138 EXPECT_EQ(1, end_batch_changes_);
1139
1140 std::vector<CoreAccountId> accounts =
1141 oauth2_service_delegate_->GetAccounts();
1142 EXPECT_EQ(2u, accounts.size());
1143
1144 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_email1));
1145 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_gaia1));
1146 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_email2));
1147 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_gaia2));
1148
1149 account_tracker_service_.SetMigrationDone();
1150 oauth2_service_delegate_->Shutdown();
1151 ResetObserverCounts();
1152
1153 oauth2_service_delegate_->LoadCredentials(acc_gaia1);
1154 base::RunLoop().RunUntilIdle();
1155
1156 EXPECT_EQ(1, tokens_loaded_count_);
1157 EXPECT_EQ(2, token_available_count_);
1158 EXPECT_EQ(1, end_batch_changes_);
1159
1160 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_email1));
1161 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_gaia1));
1162 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_email2));
1163 EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(acc_gaia2));
1164 accounts = oauth2_service_delegate_->GetAccounts();
1165 EXPECT_EQ(2u, accounts.size());
1166 }
1167 }
1168
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,LoadPrimaryAccountOnlyWhenAccountConsistencyDisabled)1169 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
1170 LoadPrimaryAccountOnlyWhenAccountConsistencyDisabled) {
1171 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
1172 CoreAccountId primary_account("primaryaccount");
1173 CoreAccountId secondary_account("secondaryaccount");
1174
1175 oauth2_service_delegate_->RevokeAllCredentials();
1176 ResetObserverCounts();
1177 AddAuthTokenManually("AccountId-" + primary_account.ToString(),
1178 "refresh_token");
1179 AddAuthTokenManually("AccountId-" + secondary_account.ToString(),
1180 "refresh_token");
1181 oauth2_service_delegate_->LoadCredentials(primary_account);
1182 base::RunLoop().RunUntilIdle();
1183
1184 EXPECT_EQ(1, tokens_loaded_count_);
1185 EXPECT_EQ(1, token_available_count_);
1186 EXPECT_EQ(1, token_revoked_count_);
1187 EXPECT_EQ(1, end_batch_changes_);
1188 EXPECT_TRUE(
1189 oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
1190 EXPECT_FALSE(
1191 oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account));
1192 }
1193
1194 // Regression test for https://crbug.com/823707
1195 // Checks that OnAuthErrorChanged() is called during UpdateCredentials(), and
1196 // that RefreshTokenIsAvailable() can be used at this time.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,OnAuthErrorChanged)1197 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, OnAuthErrorChanged) {
1198 class TokenServiceErrorObserver : public ProfileOAuth2TokenServiceObserver {
1199 public:
1200 explicit TokenServiceErrorObserver(
1201 MutableProfileOAuth2TokenServiceDelegate* delegate)
1202 : delegate_(delegate) {}
1203
1204 void OnAuthErrorChanged(const CoreAccountId& account_id,
1205 const GoogleServiceAuthError& auth_error) override {
1206 error_changed_ = true;
1207 EXPECT_EQ("account_id", account_id.ToString());
1208 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), auth_error);
1209 EXPECT_TRUE(delegate_->RefreshTokenIsAvailable(account_id));
1210 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
1211 delegate_->GetAuthError(account_id));
1212 }
1213
1214 MutableProfileOAuth2TokenServiceDelegate* delegate_;
1215 bool error_changed_ = false;
1216
1217 DISALLOW_COPY_AND_ASSIGN(TokenServiceErrorObserver);
1218 };
1219
1220 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
1221
1222 // Start with the SigninErrorController in error state, so that it calls
1223 // OnErrorChanged() from AddProvider().
1224 oauth2_service_delegate_->UpdateCredentials(
1225 CoreAccountId("error_account_id"), GaiaConstants::kInvalidRefreshToken);
1226
1227 TokenServiceErrorObserver token_service_observer(
1228 oauth2_service_delegate_.get());
1229 oauth2_service_delegate_->AddObserver(&token_service_observer);
1230
1231 ASSERT_FALSE(token_service_observer.error_changed_);
1232 oauth2_service_delegate_->UpdateCredentials(CoreAccountId("account_id"),
1233 "token");
1234 EXPECT_TRUE(token_service_observer.error_changed_);
1235
1236 oauth2_service_delegate_->RemoveObserver(&token_service_observer);
1237 }
1238
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,GetAuthError)1239 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GetAuthError) {
1240 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
1241 // Accounts have no error by default.
1242 const CoreAccountId account_id("account_id");
1243 const CoreAccountId account_id_2("account_id_2");
1244
1245 oauth2_service_delegate_->UpdateCredentials(account_id, "refresh_token");
1246 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
1247 oauth2_service_delegate_->GetAuthError(account_id));
1248 // Update the error.
1249 GoogleServiceAuthError error =
1250 GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
1251 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
1252 CREDENTIALS_REJECTED_BY_SERVER);
1253 oauth2_service_delegate_->UpdateAuthError(account_id, error);
1254 EXPECT_EQ(error, oauth2_service_delegate_->GetAuthError(account_id));
1255 // Unknown account has no error.
1256 EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
1257 oauth2_service_delegate_->GetAuthError(CoreAccountId("foo")));
1258 // Add account with invalid token.
1259 oauth2_service_delegate_->UpdateCredentials(
1260 account_id_2, GaiaConstants::kInvalidRefreshToken);
1261 EXPECT_EQ(GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
1262 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
1263 CREDENTIALS_REJECTED_BY_CLIENT),
1264 oauth2_service_delegate_->GetAuthError(account_id_2));
1265 }
1266
1267 // Checks that OnAuthErrorChanged() is called before OnRefreshTokenAvailable,
1268 // and that the error state is correctly available from within both calls.
1269 // Regression test for https://crbug.com/824791.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,InvalidTokenObserverCallsOrdering)1270 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
1271 InvalidTokenObserverCallsOrdering) {
1272 class TokenServiceErrorObserver : public ProfileOAuth2TokenServiceObserver {
1273 public:
1274 explicit TokenServiceErrorObserver(
1275 MutableProfileOAuth2TokenServiceDelegate* delegate)
1276 : delegate_(delegate) {}
1277
1278 void OnAuthErrorChanged(const CoreAccountId& account_id,
1279 const GoogleServiceAuthError& auth_error) override {
1280 error_changed_ = true;
1281 EXPECT_FALSE(token_available_)
1282 << "OnAuthErrorChanged() should be called first";
1283 EXPECT_EQ(auth_error, delegate_->GetAuthError(account_id));
1284 CheckTokenState(account_id);
1285 }
1286
1287 void OnRefreshTokenAvailable(const CoreAccountId& account_id) override {
1288 token_available_ = true;
1289 EXPECT_TRUE(error_changed_)
1290 << "OnAuthErrorChanged() should be called first";
1291 CheckTokenState(account_id);
1292 }
1293
1294 void CheckTokenState(const CoreAccountId& account_id) {
1295 EXPECT_EQ("account_id", account_id.ToString());
1296 EXPECT_TRUE(delegate_->RefreshTokenIsAvailable(account_id));
1297 EXPECT_EQ(GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
1298 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
1299 CREDENTIALS_REJECTED_BY_CLIENT),
1300 delegate_->GetAuthError(account_id));
1301 }
1302
1303 MutableProfileOAuth2TokenServiceDelegate* delegate_;
1304 bool error_changed_ = false;
1305 bool token_available_ = false;
1306
1307 DISALLOW_COPY_AND_ASSIGN(TokenServiceErrorObserver);
1308 };
1309
1310 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
1311 TokenServiceErrorObserver token_service_observer(
1312 oauth2_service_delegate_.get());
1313 oauth2_service_delegate_->AddObserver(&token_service_observer);
1314 oauth2_service_delegate_->UpdateCredentials(
1315 CoreAccountId("account_id"), GaiaConstants::kInvalidRefreshToken);
1316 EXPECT_TRUE(token_service_observer.token_available_);
1317 EXPECT_TRUE(token_service_observer.error_changed_);
1318 oauth2_service_delegate_->RemoveObserver(&token_service_observer);
1319 }
1320
1321 // Checks that set_revoke_all_tokens_on_first_load() revokes the tokens,
1322 // updates the database, and is applied only once.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,ClearTokensOnStartup)1323 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ClearTokensOnStartup) {
1324 client_->SetNetworkCallsDelayed(true);
1325 revoke_all_tokens_on_load_ = true;
1326 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
1327 CoreAccountId primary_account("primaryaccount");
1328 CoreAccountId secondary_account("secondaryaccount");
1329
1330 oauth2_service_delegate_->RevokeAllCredentials();
1331 ResetObserverCounts();
1332 AddAuthTokenManually("AccountId-" + primary_account.ToString(),
1333 "refresh_token");
1334 AddAuthTokenManually("AccountId-" + secondary_account.ToString(),
1335 "refresh_token");
1336 oauth2_service_delegate_->LoadCredentials(primary_account);
1337 base::RunLoop().RunUntilIdle();
1338
1339 EXPECT_EQ(1, tokens_loaded_count_);
1340 EXPECT_EQ(1, token_available_count_);
1341 EXPECT_EQ(1, token_revoked_count_);
1342 EXPECT_EQ(1, end_batch_changes_);
1343 EXPECT_TRUE(
1344 oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
1345 EXPECT_FALSE(
1346 oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account));
1347 EXPECT_STREQ(
1348 GaiaConstants::kInvalidRefreshToken,
1349 oauth2_service_delegate_->GetRefreshToken(primary_account).c_str());
1350 EXPECT_EQ(GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
1351 GoogleServiceAuthError::InvalidGaiaCredentialsReason::
1352 CREDENTIALS_REJECTED_BY_CLIENT),
1353 oauth2_service_delegate_->GetAuthError(primary_account));
1354
1355 // Tokens are revoked on the server.
1356 EXPECT_EQ(2u, oauth2_service_delegate_->server_revokes_.size());
1357 client_->SetNetworkCallsDelayed(false);
1358 base::RunLoop().RunUntilIdle();
1359 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
1360
1361 // Check that the changes have been persisted in the database: tokens are not
1362 // revoked again on the server.
1363 client_->SetNetworkCallsDelayed(true);
1364 oauth2_service_delegate_->LoadCredentials(primary_account);
1365 base::RunLoop().RunUntilIdle();
1366 EXPECT_TRUE(
1367 oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
1368 EXPECT_FALSE(
1369 oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account));
1370 EXPECT_STREQ(
1371 GaiaConstants::kInvalidRefreshToken,
1372 oauth2_service_delegate_->GetRefreshToken(primary_account).c_str());
1373 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
1374 }
1375
1376 // Tests that ProfileOAuthTokenService refresh token operations correctly pass
1377 // the source when used with a |MutableProfileOAuth2TokenServiceDelegate|
1378 // delegate.
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,SourceForRefreshTokenOperations)1379 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
1380 SourceForRefreshTokenOperations) {
1381 using Source = signin_metrics::SourceForRefreshTokenOperation;
1382 const CoreAccountId account_id("account_id");
1383
1384 ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
1385 ProfileOAuth2TokenService token_service(
1386 &pref_service_,
1387 CreateOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled));
1388 token_service.SetRefreshTokenAvailableFromSourceCallback(
1389 base::BindRepeating(&MutableProfileOAuth2TokenServiceDelegateTest::
1390 OnRefreshTokenAvailableFromSource,
1391 base::Unretained(this)));
1392 token_service.SetRefreshTokenRevokedFromSourceCallback(
1393 base::BindRepeating(&MutableProfileOAuth2TokenServiceDelegateTest::
1394 OnRefreshTokenRevokedFromSource,
1395 base::Unretained(this)));
1396
1397 {
1398 base::HistogramTester h_tester;
1399 AddAuthTokenManually("account_id", "refresh_token");
1400 token_service.LoadCredentials(account_id);
1401 base::RunLoop().RunUntilIdle();
1402
1403 EXPECT_EQ("TokenService::LoadCredentials",
1404 source_for_refresh_token_available_);
1405 h_tester.ExpectUniqueSample(
1406 "Signin.RefreshTokenUpdated.ToValidToken.Source",
1407 Source::kTokenService_LoadCredentials, 1);
1408 }
1409
1410 {
1411 base::HistogramTester h_tester;
1412 token_service.UpdateCredentials(account_id, "refresh_token",
1413 Source::kInlineLoginHandler_Signin);
1414 EXPECT_EQ("InlineLoginHandler::Signin",
1415 source_for_refresh_token_available_);
1416 h_tester.ExpectUniqueSample(
1417 "Signin.RefreshTokenUpdated.ToValidToken.Source",
1418 Source::kInlineLoginHandler_Signin, 1);
1419
1420 token_service.RevokeCredentials(
1421 account_id, Source::kAccountReconcilor_GaiaCookiesUpdated);
1422 EXPECT_EQ("AccountReconcilor::GaiaCookiesUpdated",
1423 source_for_refresh_token_revoked_);
1424 h_tester.ExpectUniqueSample("Signin.RefreshTokenRevoked.Source",
1425 Source::kAccountReconcilor_GaiaCookiesUpdated,
1426 1);
1427 base::RunLoop().RunUntilIdle();
1428 }
1429
1430 {
1431 base::HistogramTester h_tester;
1432 token_service.UpdateCredentials(CoreAccountId("account_id_1"),
1433 "refresh_token",
1434 Source::kDiceResponseHandler_Signin);
1435 EXPECT_EQ("DiceResponseHandler::Signin",
1436 source_for_refresh_token_available_);
1437 h_tester.ExpectUniqueSample(
1438 "Signin.RefreshTokenUpdated.ToValidToken.Source",
1439 Source::kDiceResponseHandler_Signin, 1);
1440
1441 token_service.UpdateCredentials(CoreAccountId("account_id_2"),
1442 GaiaConstants::kInvalidRefreshToken,
1443 Source::kDiceResponseHandler_Signin);
1444 EXPECT_EQ("DiceResponseHandler::Signin",
1445 source_for_refresh_token_available_);
1446 h_tester.ExpectUniqueSample(
1447 "Signin.RefreshTokenUpdated.ToInvalidToken.Source",
1448 Source::kDiceResponseHandler_Signin, 1);
1449
1450 token_service.RevokeAllCredentials(Source::kDiceResponseHandler_Signout);
1451 EXPECT_EQ("DiceResponseHandler::Signout",
1452 source_for_refresh_token_revoked_);
1453 h_tester.ExpectUniqueSample("Signin.RefreshTokenRevoked.Source",
1454 Source::kDiceResponseHandler_Signout, 2);
1455 base::RunLoop().RunUntilIdle();
1456 }
1457
1458 token_service.Shutdown();
1459 }
1460
TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,ExtractCredentials)1461 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ExtractCredentials) {
1462 InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice);
1463 oauth2_service_delegate_->LoadCredentials(CoreAccountId());
1464 const CoreAccountId account_id("account_id");
1465
1466 // Create another token service
1467 sync_preferences::TestingPrefServiceSyncable prefs;
1468 ProfileOAuth2TokenService::RegisterProfilePrefs(prefs.registry());
1469 std::unique_ptr<FakeProfileOAuth2TokenServiceDelegate> delegate =
1470 std::make_unique<FakeProfileOAuth2TokenServiceDelegate>();
1471 FakeProfileOAuth2TokenServiceDelegate* other_delegate = delegate.get();
1472 ProfileOAuth2TokenService other_token_service(&prefs, std::move(delegate));
1473 other_token_service.LoadCredentials(CoreAccountId());
1474
1475 // Add credentials to the first token service delegate.
1476 oauth2_service_delegate_->UpdateCredentials(account_id, "token");
1477
1478 // Extract the credentials.
1479 ResetObserverCounts();
1480 oauth2_service_delegate_->ExtractCredentials(&other_token_service,
1481 account_id);
1482
1483 EXPECT_EQ(1, token_revoked_count_);
1484 EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
1485 EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id));
1486 EXPECT_TRUE(other_delegate->RefreshTokenIsAvailable(account_id));
1487 EXPECT_EQ("token", other_delegate->GetRefreshToken(account_id));
1488 }
1489