| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 <string> | 5 #include <string> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/memory/ptr_util.h" |
| 9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 11 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
| 12 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
| 14 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" | 15 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" |
| 15 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" | 16 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" |
| 16 #include "chrome/browser/chromeos/login/signin_specifics.h" | 17 #include "chrome/browser/chromeos/login/signin_specifics.h" |
| 17 #include "chrome/browser/chromeos/login/startup_utils.h" | 18 #include "chrome/browser/chromeos/login/startup_utils.h" |
| 18 #include "chrome/browser/chromeos/login/test/oobe_base_test.h" | 19 #include "chrome/browser/chromeos/login/test/oobe_base_test.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 31 #include "chromeos/login/auth/user_context.h" | 32 #include "chromeos/login/auth/user_context.h" |
| 32 #include "components/app_modal/javascript_app_modal_dialog.h" | 33 #include "components/app_modal/javascript_app_modal_dialog.h" |
| 33 #include "components/app_modal/native_app_modal_dialog.h" | 34 #include "components/app_modal/native_app_modal_dialog.h" |
| 34 #include "components/browser_sync/browser_sync_switches.h" | 35 #include "components/browser_sync/browser_sync_switches.h" |
| 35 #include "components/prefs/pref_service.h" | 36 #include "components/prefs/pref_service.h" |
| 36 #include "components/signin/core/account_id/account_id.h" | 37 #include "components/signin/core/account_id/account_id.h" |
| 37 #include "components/signin/core/browser/account_tracker_service.h" | 38 #include "components/signin/core/browser/account_tracker_service.h" |
| 38 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 39 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 39 #include "components/user_manager/user.h" | 40 #include "components/user_manager/user.h" |
| 40 #include "components/user_manager/user_manager.h" | 41 #include "components/user_manager/user_manager.h" |
| 42 #include "content/public/browser/browser_thread.h" |
| 41 #include "content/public/browser/notification_service.h" | 43 #include "content/public/browser/notification_service.h" |
| 42 #include "content/public/test/browser_test_utils.h" | 44 #include "content/public/test/browser_test_utils.h" |
| 43 #include "extensions/browser/process_manager.h" | 45 #include "extensions/browser/process_manager.h" |
| 44 #include "extensions/test/extension_test_message_listener.h" | 46 #include "extensions/test/extension_test_message_listener.h" |
| 45 #include "extensions/test/result_catcher.h" | 47 #include "extensions/test/result_catcher.h" |
| 46 #include "google_apis/gaia/gaia_constants.h" | 48 #include "google_apis/gaia/gaia_constants.h" |
| 47 #include "google_apis/gaia/gaia_urls.h" | 49 #include "google_apis/gaia/gaia_urls.h" |
| 48 #include "net/cookies/canonical_cookie.h" | 50 #include "net/cookies/canonical_cookie.h" |
| 49 #include "net/cookies/cookie_store.h" | 51 #include "net/cookies/cookie_store.h" |
| 50 #include "net/test/embedded_test_server/http_request.h" | 52 #include "net/test/embedded_test_server/http_request.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 | 137 |
| 136 Profile* profile_; | 138 Profile* profile_; |
| 137 std::set<OAuth2LoginManager::SessionRestoreState> states_; | 139 std::set<OAuth2LoginManager::SessionRestoreState> states_; |
| 138 bool waiting_for_state_; | 140 bool waiting_for_state_; |
| 139 OAuth2LoginManager::SessionRestoreState final_state_; | 141 OAuth2LoginManager::SessionRestoreState final_state_; |
| 140 scoped_refptr<content::MessageLoopRunner> runner_; | 142 scoped_refptr<content::MessageLoopRunner> runner_; |
| 141 | 143 |
| 142 DISALLOW_COPY_AND_ASSIGN(OAuth2LoginManagerStateWaiter); | 144 DISALLOW_COPY_AND_ASSIGN(OAuth2LoginManagerStateWaiter); |
| 143 }; | 145 }; |
| 144 | 146 |
| 147 // Blocks a BrowserThread on construction and unblocks it on destruction. |
| 148 class BrowserThreadBlocker { |
| 149 public: |
| 150 explicit BrowserThreadBlocker(content::BrowserThread::ID identifier) |
| 151 : unblock_event_(new base::WaitableEvent( |
| 152 base::WaitableEvent::ResetPolicy::MANUAL, |
| 153 base::WaitableEvent::InitialState::NOT_SIGNALED)) { |
| 154 content::BrowserThread::PostTask( |
| 155 identifier, FROM_HERE, |
| 156 base::Bind(&BlockThreadOnThread, base::Owned(unblock_event_))); |
| 157 } |
| 158 ~BrowserThreadBlocker() { unblock_event_->Signal(); } |
| 159 |
| 160 private: |
| 161 // Blocks the target thread until |event| is signaled. |
| 162 static void BlockThreadOnThread(base::WaitableEvent* event) { event->Wait(); } |
| 163 |
| 164 // |unblock_event_| is deleted after BlockThreadOnThread returns. |
| 165 base::WaitableEvent* const unblock_event_; |
| 166 |
| 167 DISALLOW_COPY_AND_ASSIGN(BrowserThreadBlocker); |
| 168 }; |
| 169 |
| 145 } // namespace | 170 } // namespace |
| 146 | 171 |
| 147 class OAuth2Test : public OobeBaseTest { | 172 class OAuth2Test : public OobeBaseTest { |
| 148 protected: | 173 protected: |
| 149 OAuth2Test() {} | 174 OAuth2Test() {} |
| 150 | 175 |
| 151 void SetUpCommandLine(base::CommandLine* command_line) override { | 176 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 152 OobeBaseTest::SetUpCommandLine(command_line); | 177 OobeBaseTest::SetUpCommandLine(command_line); |
| 153 | 178 |
| 154 // Disable sync sinc we don't really need this for these tests and it also | 179 // Disable sync sinc we don't really need this for these tests and it also |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 // Use capitalized and dotted user name on purpose to make sure | 382 // Use capitalized and dotted user name on purpose to make sure |
| 358 // our email normalization kicks in. | 383 // our email normalization kicks in. |
| 359 GetLoginDisplay()->ShowSigninScreenForCreds(kTestRawEmail, | 384 GetLoginDisplay()->ShowSigninScreenForCreds(kTestRawEmail, |
| 360 kTestAccountPassword); | 385 kTestAccountPassword); |
| 361 session_start_waiter.Wait(); | 386 session_start_waiter.Wait(); |
| 362 | 387 |
| 363 if (wait_for_merge) { | 388 if (wait_for_merge) { |
| 364 // Wait for the session merge to finish. | 389 // Wait for the session merge to finish. |
| 365 WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE); | 390 WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE); |
| 366 } | 391 } |
| 367 } | 392 } |
| 368 | 393 |
| 394 OAuth2LoginManager::SessionRestoreStrategy GetSessionRestoreStrategy() { |
| 395 OAuth2LoginManager* login_manager = |
| 396 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile()); |
| 397 return login_manager->restore_strategy_; |
| 398 } |
| 399 |
| 400 private: |
| 369 DISALLOW_COPY_AND_ASSIGN(OAuth2Test); | 401 DISALLOW_COPY_AND_ASSIGN(OAuth2Test); |
| 370 }; | 402 }; |
| 371 | 403 |
| 372 class CookieReader : public base::RefCountedThreadSafe<CookieReader> { | 404 class CookieReader : public base::RefCountedThreadSafe<CookieReader> { |
| 373 public: | 405 public: |
| 374 CookieReader() { | 406 CookieReader() { |
| 375 } | 407 } |
| 376 | 408 |
| 377 void ReadCookies(Profile* profile) { | 409 void ReadCookies(Profile* profile) { |
| 378 context_ = profile->GetRequestContext(); | 410 context_ = profile->GetRequestContext(); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId), | 530 TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId), |
| 499 kTestAccountPassword)); | 531 kTestAccountPassword)); |
| 500 | 532 |
| 501 // Wait for the session merge to finish. | 533 // Wait for the session merge to finish. |
| 502 WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED); | 534 WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED); |
| 503 | 535 |
| 504 EXPECT_EQ(GetOAuthStatusFromLocalState(account_id), | 536 EXPECT_EQ(GetOAuthStatusFromLocalState(account_id), |
| 505 user_manager::User::OAUTH2_TOKEN_STATUS_INVALID); | 537 user_manager::User::OAUTH2_TOKEN_STATUS_INVALID); |
| 506 } | 538 } |
| 507 | 539 |
| 540 // Sets up a new user with stored refresh token. |
| 541 IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_OverlappingContinueSessionRestore) { |
| 542 StartNewUserSession(true); |
| 543 } |
| 544 |
| 545 // Tests that ContinueSessionRestore could be called multiple times. |
| 546 IN_PROC_BROWSER_TEST_F(OAuth2Test, OverlappingContinueSessionRestore) { |
| 547 SetupGaiaServerForUnexpiredAccount(); |
| 548 SimulateNetworkOnline(); |
| 549 |
| 550 // Waits for login screen to be ready. |
| 551 content::WindowedNotificationObserver( |
| 552 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
| 553 content::NotificationService::AllSources()) |
| 554 .Wait(); |
| 555 |
| 556 // Blocks DB thread to control TokenService::LoadCredentials timing. |
| 557 std::unique_ptr<BrowserThreadBlocker> db_blocker = |
| 558 base::MakeUnique<BrowserThreadBlocker>(content::BrowserThread::DB); |
| 559 |
| 560 // Signs in as the existing user created in pre test. |
| 561 EXPECT_TRUE( |
| 562 TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId), |
| 563 kTestAccountPassword)); |
| 564 |
| 565 // Session restore should be using the saved tokens. |
| 566 EXPECT_EQ(OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN, |
| 567 GetSessionRestoreStrategy()); |
| 568 |
| 569 // Checks that refresh token is not yet loaded. |
| 570 ProfileOAuth2TokenService* token_service = |
| 571 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()); |
| 572 const std::string account_id = |
| 573 PickAccountId(profile(), kTestGaiaId, kTestEmail); |
| 574 EXPECT_FALSE(token_service->RefreshTokenIsAvailable(account_id)); |
| 575 |
| 576 // Invokes ContinueSessionRestore multiple times and there should be |
| 577 // no DCHECK failures. |
| 578 OAuth2LoginManager* login_manager = |
| 579 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile()); |
| 580 login_manager->ContinueSessionRestore(); |
| 581 login_manager->ContinueSessionRestore(); |
| 582 |
| 583 // Let go DB thread to finish TokenService::LoadCredentials. |
| 584 db_blocker.reset(); |
| 585 |
| 586 // Session restore can finish normally and token is loaded. |
| 587 WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE); |
| 588 EXPECT_TRUE(token_service->RefreshTokenIsAvailable(account_id)); |
| 589 } |
| 508 | 590 |
| 509 const char kGooglePageContent[] = | 591 const char kGooglePageContent[] = |
| 510 "<html><title>Hello!</title><script>alert('hello');</script>" | 592 "<html><title>Hello!</title><script>alert('hello');</script>" |
| 511 "<body>Hello Google!</body></html>"; | 593 "<body>Hello Google!</body></html>"; |
| 512 const char kRandomPageContent[] = | 594 const char kRandomPageContent[] = |
| 513 "<html><title>SomthingElse</title><body>I am SomethingElse</body></html>"; | 595 "<html><title>SomthingElse</title><body>I am SomethingElse</body></html>"; |
| 514 const char kHelloPagePath[] = "/hello_google"; | 596 const char kHelloPagePath[] = "/hello_google"; |
| 515 const char kRandomPagePath[] = "/non_google_page"; | 597 const char kRandomPagePath[] = "/non_google_page"; |
| 516 | 598 |
| 517 | 599 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 const GURL& server_url = embedded_test_server()->base_url(); | 723 const GURL& server_url = embedded_test_server()->base_url(); |
| 642 GURL::Replacements replace_google_host; | 724 GURL::Replacements replace_google_host; |
| 643 replace_google_host.SetHostStr("www.google.com"); | 725 replace_google_host.SetHostStr("www.google.com"); |
| 644 GURL google_url = server_url.ReplaceComponents(replace_google_host); | 726 GURL google_url = server_url.ReplaceComponents(replace_google_host); |
| 645 fake_google_page_url_ = google_url.Resolve(kHelloPagePath); | 727 fake_google_page_url_ = google_url.Resolve(kHelloPagePath); |
| 646 | 728 |
| 647 GURL::Replacements replace_non_google_host; | 729 GURL::Replacements replace_non_google_host; |
| 648 replace_non_google_host.SetHostStr("www.somethingelse.org"); | 730 replace_non_google_host.SetHostStr("www.somethingelse.org"); |
| 649 GURL non_google_url = server_url.ReplaceComponents(replace_non_google_host); | 731 GURL non_google_url = server_url.ReplaceComponents(replace_non_google_host); |
| 650 non_google_page_url_ = non_google_url.Resolve(kRandomPagePath); | 732 non_google_page_url_ = non_google_url.Resolve(kRandomPagePath); |
| 651 } | 733 } |
| 652 | 734 |
| 653 void SetUp() override { | 735 void SetUp() override { |
| 654 embedded_test_server()->RegisterRequestHandler( | 736 embedded_test_server()->RegisterRequestHandler(base::Bind( |
| 655 base::Bind(&FakeGoogle::HandleRequest, | 737 &FakeGoogle::HandleRequest, base::Unretained(&fake_google_))); |
| 656 base::Unretained(&fake_google_))); | |
| 657 OAuth2Test::SetUp(); | 738 OAuth2Test::SetUp(); |
| 658 } | 739 } |
| 659 | 740 |
| 660 protected: | 741 protected: |
| 661 void UnblockMergeSession() { | 742 void UnblockMergeSession() { |
| 662 delayed_fake_gaia_->UnblockMergeSession(); | 743 delayed_fake_gaia_->UnblockMergeSession(); |
| 663 } | 744 } |
| 664 | 745 |
| 665 void WaitForMergeSessionToStart() { | 746 void WaitForMergeSessionToStart() { |
| 666 delayed_fake_gaia_->WaitForMergeSessionToStart(); | 747 delayed_fake_gaia_->WaitForMergeSessionToStart(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 | 888 |
| 808 if (!catcher.GetNextResult()) { | 889 if (!catcher.GetNextResult()) { |
| 809 std::string message = catcher.message(); | 890 std::string message = catcher.message(); |
| 810 ADD_FAILURE() << "Tests failed: " << message; | 891 ADD_FAILURE() << "Tests failed: " << message; |
| 811 } | 892 } |
| 812 | 893 |
| 813 EXPECT_TRUE(fake_google_.IsPageRequested()); | 894 EXPECT_TRUE(fake_google_.IsPageRequested()); |
| 814 } | 895 } |
| 815 | 896 |
| 816 } // namespace chromeos | 897 } // namespace chromeos |
| OLD | NEW |