google_accounts_browsertest.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Copyright 2020 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. #include "base/strings/escape.h"
  5. #include "base/strings/strcat.h"
  6. #include "components/signin/core/browser/signin_header_helper.h"
  7. #include "google_apis/gaia/gaia_switches.h"
  8. #include "google_apis/gaia/gaia_urls.h"
  9. #include "net/base/url_util.h"
  10. #include "net/dns/mock_host_resolver.h"
  11. #include "net/test/embedded_test_server/default_handlers.h"
  12. #include "net/test/embedded_test_server/http_request.h"
  13. #include "net/test/embedded_test_server/http_response.h"
  14. #include "weblayer/browser/browser_impl.h"
  15. #include "weblayer/browser/profile_impl.h"
  16. #include "weblayer/browser/signin_url_loader_throttle.h"
  17. #include "weblayer/browser/tab_impl.h"
  18. #include "weblayer/public/google_accounts_delegate.h"
  19. #include "weblayer/public/navigation_controller.h"
  20. #include "weblayer/shell/browser/shell.h"
  21. #include "weblayer/test/test_navigation_observer.h"
  22. #include "weblayer/test/weblayer_browser_test.h"
  23. #include "weblayer/test/weblayer_browser_test_utils.h"
  24. namespace weblayer {
  25. namespace {
  26. constexpr char kGaiaDomain[] = "fakegaia.com";
  27. constexpr char kGoogleAccountsPath[] = "/manageaccounts";
  28. constexpr char kGoogleAccountsRedirectPath[] = "/manageaccounts-redirect";
  29. } // namespace
  30. class GoogleAccountsBrowserTest : public WebLayerBrowserTest,
  31. public GoogleAccountsDelegate {
  32. public:
  33. // WebLayerBrowserTest:
  34. void SetUpOnMainThread() override {
  35. host_resolver()->AddRule("*", "127.0.0.1");
  36. shell()->tab()->SetGoogleAccountsDelegate(this);
  37. }
  38. void SetUpCommandLine(base::CommandLine* command_line) override {
  39. https_server_.RegisterRequestHandler(base::BindRepeating(
  40. &GoogleAccountsBrowserTest::HandleGoogleAccountsRequest,
  41. base::Unretained(this)));
  42. net::test_server::RegisterDefaultHandlers(&https_server_);
  43. ASSERT_TRUE(https_server_.Start());
  44. command_line->AppendSwitchASCII(switches::kGaiaUrl, GetGaiaURL("/").spec());
  45. command_line->AppendSwitch("ignore-certificate-errors");
  46. }
  47. // GoogleAccountsDelegate:
  48. void OnGoogleAccountsRequest(
  49. const signin::ManageAccountsParams& params) override {
  50. params_ = params;
  51. if (run_loop_)
  52. run_loop_->Quit();
  53. }
  54. std::string GetGaiaId() override { return ""; }
  55. const signin::ManageAccountsParams& WaitForGoogleAccounts() {
  56. if (!params_) {
  57. run_loop_ = std::make_unique<base::RunLoop>();
  58. run_loop_->Run();
  59. }
  60. EXPECT_TRUE(params_.has_value());
  61. return params_.value();
  62. }
  63. GURL GetGaiaURL(const std::string& path) {
  64. return https_server_.GetURL(kGaiaDomain, path);
  65. }
  66. GURL GetNonGaiaURL(const std::string& path) {
  67. return https_server_.GetURL(path);
  68. }
  69. bool HasReceivedGoogleAccountsResponse() { return params_.has_value(); }
  70. std::string GetBody() {
  71. return ExecuteScript(shell(), "document.body.innerText", true).GetString();
  72. }
  73. protected:
  74. std::string response_header_;
  75. private:
  76. std::unique_ptr<net::test_server::HttpResponse> HandleGoogleAccountsRequest(
  77. const net::test_server::HttpRequest& request) {
  78. std::string path = request.GetURL().path();
  79. if (path != kSignOutPath && path != kGoogleAccountsPath &&
  80. path != kGoogleAccountsRedirectPath) {
  81. return nullptr;
  82. }
  83. auto http_response =
  84. std::make_unique<net::test_server::BasicHttpResponse>();
  85. if (path == kGoogleAccountsRedirectPath) {
  86. http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
  87. http_response->AddCustomHeader(
  88. "Location",
  89. base::UnescapeBinaryURLComponent(request.GetURL().query_piece()));
  90. } else {
  91. http_response->set_code(net::HTTP_OK);
  92. }
  93. if (base::Contains(request.headers, signin::kChromeConnectedHeader)) {
  94. http_response->AddCustomHeader(signin::kChromeManageAccountsHeader,
  95. response_header_);
  96. }
  97. http_response->set_content("");
  98. return http_response;
  99. }
  100. net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  101. absl::optional<signin::ManageAccountsParams> params_;
  102. std::unique_ptr<base::RunLoop> run_loop_;
  103. };
  104. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, Basic) {
  105. response_header_ =
  106. "action=ADDSESSION,email=foo@bar.com,"
  107. "continue_url=https://blah.com,is_same_tab=true";
  108. NavigateAndWaitForCompletion(GetGaiaURL(kGoogleAccountsPath), shell());
  109. const signin::ManageAccountsParams& params = WaitForGoogleAccounts();
  110. EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_ADDSESSION);
  111. EXPECT_EQ(params.email, "foo@bar.com");
  112. EXPECT_EQ(params.continue_url, "https://blah.com");
  113. EXPECT_TRUE(params.is_same_tab);
  114. }
  115. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, NonGaiaUrl) {
  116. response_header_ = "action=ADDSESSION";
  117. NavigateAndWaitForCompletion(GetNonGaiaURL(kGoogleAccountsPath), shell());
  118. // Navigate again to make sure the manage accounts response would have been
  119. // received.
  120. NavigateAndWaitForCompletion(GetNonGaiaURL("/echo"), shell());
  121. EXPECT_FALSE(HasReceivedGoogleAccountsResponse());
  122. }
  123. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, RedirectFromGaiaURL) {
  124. response_header_ = "action=SIGNUP";
  125. GURL final_url = GetGaiaURL(kGoogleAccountsPath);
  126. TestNavigationObserver test_observer(
  127. final_url, TestNavigationObserver::NavigationEvent::kCompletion,
  128. shell()->tab());
  129. shell()->tab()->GetNavigationController()->Navigate(GetNonGaiaURL(
  130. base::StrCat({kGoogleAccountsRedirectPath, "?", final_url.spec()})));
  131. test_observer.Wait();
  132. const signin::ManageAccountsParams& params = WaitForGoogleAccounts();
  133. EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_SIGNUP);
  134. }
  135. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, RedirectToGaiaURL) {
  136. response_header_ = "action=SIGNUP";
  137. GURL final_url = GetNonGaiaURL(kGoogleAccountsPath);
  138. TestNavigationObserver test_observer(
  139. final_url, TestNavigationObserver::NavigationEvent::kCompletion,
  140. shell()->tab());
  141. shell()->tab()->GetNavigationController()->Navigate(GetGaiaURL(
  142. base::StrCat({kGoogleAccountsRedirectPath, "?", final_url.spec()})));
  143. test_observer.Wait();
  144. const signin::ManageAccountsParams& params = WaitForGoogleAccounts();
  145. EXPECT_EQ(params.service_type, signin::GAIA_SERVICE_TYPE_SIGNUP);
  146. }
  147. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, AddsQueryParamsToSignoutURL) {
  148. response_header_ = "action=SIGNUP";
  149. // Sign out URL on the GAIA domain will get a query param added to it.
  150. GURL sign_out_url = GetGaiaURL(kSignOutPath);
  151. GURL sign_out_url_with_params =
  152. net::AppendQueryParameter(sign_out_url, "manage", "true");
  153. {
  154. TestNavigationObserver test_observer(
  155. sign_out_url_with_params,
  156. TestNavigationObserver::NavigationEvent::kCompletion, shell()->tab());
  157. shell()->tab()->GetNavigationController()->Navigate(sign_out_url);
  158. test_observer.Wait();
  159. }
  160. // Other URLs will not have query param added.
  161. NavigateAndWaitForCompletion(GetGaiaURL(kGoogleAccountsPath), shell());
  162. NavigateAndWaitForCompletion(GetNonGaiaURL(kSignOutPath), shell());
  163. // Redirecting to sign out URL will also add params.
  164. {
  165. TestNavigationObserver test_observer(
  166. sign_out_url_with_params,
  167. TestNavigationObserver::NavigationEvent::kCompletion, shell()->tab());
  168. shell()->tab()->GetNavigationController()->Navigate(
  169. GetNonGaiaURL("/server-redirect?" + sign_out_url.spec()));
  170. test_observer.Wait();
  171. }
  172. }
  173. IN_PROC_BROWSER_TEST_F(GoogleAccountsBrowserTest, AddsRequestHeaderToGaiaURLs) {
  174. const std::string path =
  175. base::StrCat({"/echoheader?", signin::kChromeConnectedHeader});
  176. NavigateAndWaitForCompletion(GetGaiaURL(path), shell());
  177. EXPECT_EQ(GetBody(),
  178. "source=WebLayer,mode=3,enable_account_consistency=true,"
  179. "consistency_enabled_by_default=false");
  180. // Non GAIA URL should not get the header.
  181. NavigateAndWaitForCompletion(GetNonGaiaURL(path), shell());
  182. EXPECT_EQ(GetBody(), "None");
  183. }
  184. class IncognitoGoogleAccountsBrowserTest : public GoogleAccountsBrowserTest {
  185. public:
  186. IncognitoGoogleAccountsBrowserTest() { SetShellStartsInIncognitoMode(); }
  187. };
  188. IN_PROC_BROWSER_TEST_F(IncognitoGoogleAccountsBrowserTest,
  189. HeaderAddedForIncognitoBrowser) {
  190. const std::string path =
  191. base::StrCat({"/echoheader?", signin::kChromeConnectedHeader});
  192. NavigateAndWaitForCompletion(GetGaiaURL(path), shell());
  193. EXPECT_EQ(GetBody(),
  194. "source=WebLayer,mode=3,enable_account_consistency=true,"
  195. "consistency_enabled_by_default=false");
  196. }
  197. } // namespace weblayer