Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / sync / test / integration / sync_auth_test.cc
blob5cfcdf808506c2ee65da5dcbd622d6a6aa4ec58c
1 // Copyright 2013 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.
5 #include "base/strings/stringprintf.h"
6 #include "base/threading/platform_thread.h"
7 #include "base/time/time.h"
8 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
9 #include "chrome/browser/sync/profile_sync_service.h"
10 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
11 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
12 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
13 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
14 #include "chrome/browser/sync/test/integration/sync_test.h"
15 #include "components/signin/core/browser/profile_oauth2_token_service.h"
16 #include "google_apis/gaia/google_service_auth_error.h"
17 #include "net/http/http_status_code.h"
18 #include "net/url_request/url_request_status.h"
20 using bookmarks_helper::AddURL;
21 using sync_integration_test_util::AwaitCommitActivityCompletion;
23 const char kShortLivedOAuth2Token[] =
24 "{"
25 " \"refresh_token\": \"short_lived_refresh_token\","
26 " \"access_token\": \"short_lived_access_token\","
27 " \"expires_in\": 5," // 5 seconds.
28 " \"token_type\": \"Bearer\""
29 "}";
31 const char kValidOAuth2Token[] = "{"
32 " \"refresh_token\": \"new_refresh_token\","
33 " \"access_token\": \"new_access_token\","
34 " \"expires_in\": 3600," // 1 hour.
35 " \"token_type\": \"Bearer\""
36 "}";
38 const char kInvalidGrantOAuth2Token[] = "{"
39 " \"error\": \"invalid_grant\""
40 "}";
42 const char kInvalidClientOAuth2Token[] = "{"
43 " \"error\": \"invalid_client\""
44 "}";
46 const char kEmptyOAuth2Token[] = "";
48 const char kMalformedOAuth2Token[] = "{ \"foo\": ";
50 class TestForAuthError : public SingleClientStatusChangeChecker {
51 public:
52 explicit TestForAuthError(ProfileSyncService* service);
53 ~TestForAuthError() override;
54 bool IsExitConditionSatisfied() override;
55 std::string GetDebugMessage() const override;
58 TestForAuthError::TestForAuthError(ProfileSyncService* service)
59 : SingleClientStatusChangeChecker(service) {}
61 TestForAuthError::~TestForAuthError() {}
63 bool TestForAuthError::IsExitConditionSatisfied() {
64 return !service()->HasUnsyncedItems() ||
65 (service()->GetSyncTokenStatus().last_get_token_error.state() !=
66 GoogleServiceAuthError::NONE);
69 std::string TestForAuthError::GetDebugMessage() const {
70 return "Waiting for auth error";
73 class SyncAuthTest : public SyncTest {
74 public:
75 SyncAuthTest() : SyncTest(SINGLE_CLIENT), bookmark_index_(0) {}
76 ~SyncAuthTest() override {}
78 // Helper function that adds a bookmark and waits for either an auth error, or
79 // for the bookmark to be committed. Returns true if it detects an auth
80 // error, false if the bookmark is committed successfully.
81 bool AttemptToTriggerAuthError() {
82 int bookmark_index = GetNextBookmarkIndex();
83 std::string title = base::StringPrintf("Bookmark %d", bookmark_index);
84 GURL url = GURL(base::StringPrintf("http://www.foo%d.com", bookmark_index));
85 EXPECT_TRUE(AddURL(0, title, url) != NULL);
87 // Run until the bookmark is committed or an auth error is encountered.
88 TestForAuthError checker_(GetSyncService((0)));
89 checker_.Wait();
91 GoogleServiceAuthError oauth_error =
92 GetSyncService((0))->GetSyncTokenStatus().last_get_token_error;
94 return oauth_error.state() != GoogleServiceAuthError::NONE;
97 void DisableTokenFetchRetries() {
98 // If ProfileSyncService observes a transient error like SERVICE_UNAVAILABLE
99 // or CONNECTION_FAILED, this means the OAuth2TokenService has given up
100 // trying to reach Gaia. In practice, OA2TS retries a fixed number of times,
101 // but the count is transparent to PSS.
102 // Override the max retry count in TokenService so that we instantly trigger
103 // the case where ProfileSyncService must pick up where OAuth2TokenService
104 // left off (in terms of retries).
105 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile(0))->
106 set_max_authorization_token_fetch_retries_for_testing(0);
110 private:
111 int GetNextBookmarkIndex() {
112 return bookmark_index_++;
115 int bookmark_index_;
117 DISALLOW_COPY_AND_ASSIGN(SyncAuthTest);
120 // Verify that sync works with a valid OAuth2 token.
121 IN_PROC_BROWSER_TEST_F(SyncAuthTest, Sanity) {
122 ASSERT_TRUE(SetupSync());
123 GetFakeServer()->SetAuthenticated();
124 DisableTokenFetchRetries();
125 SetOAuth2TokenResponse(kValidOAuth2Token,
126 net::HTTP_OK,
127 net::URLRequestStatus::SUCCESS);
128 ASSERT_FALSE(AttemptToTriggerAuthError());
131 // Verify that ProfileSyncService continues trying to fetch access tokens
132 // when OAuth2TokenService has encountered more than a fixed number of
133 // HTTP_INTERNAL_SERVER_ERROR (500) errors.
134 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryOnInternalServerError500) {
135 ASSERT_TRUE(SetupSync());
136 ASSERT_FALSE(AttemptToTriggerAuthError());
137 GetFakeServer()->SetUnauthenticated();
138 DisableTokenFetchRetries();
139 SetOAuth2TokenResponse(kValidOAuth2Token,
140 net::HTTP_INTERNAL_SERVER_ERROR,
141 net::URLRequestStatus::SUCCESS);
142 ASSERT_TRUE(AttemptToTriggerAuthError());
143 ASSERT_TRUE(
144 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
147 // Verify that ProfileSyncService continues trying to fetch access tokens
148 // when OAuth2TokenService has encountered more than a fixed number of
149 // HTTP_FORBIDDEN (403) errors.
150 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryOnHttpForbidden403) {
151 ASSERT_TRUE(SetupSync());
152 ASSERT_FALSE(AttemptToTriggerAuthError());
153 GetFakeServer()->SetUnauthenticated();
154 DisableTokenFetchRetries();
155 SetOAuth2TokenResponse(kEmptyOAuth2Token,
156 net::HTTP_FORBIDDEN,
157 net::URLRequestStatus::SUCCESS);
158 ASSERT_TRUE(AttemptToTriggerAuthError());
159 ASSERT_TRUE(
160 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
163 // Verify that ProfileSyncService continues trying to fetch access tokens
164 // when OAuth2TokenService has encountered a URLRequestStatus of FAILED.
165 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryOnRequestFailed) {
166 ASSERT_TRUE(SetupSync());
167 ASSERT_FALSE(AttemptToTriggerAuthError());
168 GetFakeServer()->SetUnauthenticated();
169 DisableTokenFetchRetries();
170 SetOAuth2TokenResponse(kEmptyOAuth2Token,
171 net::HTTP_INTERNAL_SERVER_ERROR,
172 net::URLRequestStatus::FAILED);
173 ASSERT_TRUE(AttemptToTriggerAuthError());
174 ASSERT_TRUE(
175 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
178 // Verify that ProfileSyncService continues trying to fetch access tokens
179 // when OAuth2TokenService receives a malformed token.
180 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryOnMalformedToken) {
181 ASSERT_TRUE(SetupSync());
182 ASSERT_FALSE(AttemptToTriggerAuthError());
183 GetFakeServer()->SetUnauthenticated();
184 DisableTokenFetchRetries();
185 SetOAuth2TokenResponse(kMalformedOAuth2Token,
186 net::HTTP_OK,
187 net::URLRequestStatus::SUCCESS);
188 ASSERT_TRUE(AttemptToTriggerAuthError());
189 ASSERT_TRUE(
190 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
193 // Verify that ProfileSyncService ends up with an INVALID_GAIA_CREDENTIALS auth
194 // error when an invalid_grant error is returned by OAuth2TokenService with an
195 // HTTP_BAD_REQUEST (400) response code.
196 IN_PROC_BROWSER_TEST_F(SyncAuthTest, InvalidGrant) {
197 ASSERT_TRUE(SetupSync());
198 ASSERT_FALSE(AttemptToTriggerAuthError());
199 GetFakeServer()->SetUnauthenticated();
200 DisableTokenFetchRetries();
201 SetOAuth2TokenResponse(kInvalidGrantOAuth2Token,
202 net::HTTP_BAD_REQUEST,
203 net::URLRequestStatus::SUCCESS);
204 ASSERT_TRUE(AttemptToTriggerAuthError());
205 ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
206 GetSyncService((0))->GetAuthError().state());
209 // Verify that ProfileSyncService retries after SERVICE_ERROR auth error when
210 // an invalid_client error is returned by OAuth2TokenService with an
211 // HTTP_BAD_REQUEST (400) response code.
212 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryInvalidClient) {
213 ASSERT_TRUE(SetupSync());
214 ASSERT_FALSE(AttemptToTriggerAuthError());
215 GetFakeServer()->SetUnauthenticated();
216 DisableTokenFetchRetries();
217 SetOAuth2TokenResponse(kInvalidClientOAuth2Token,
218 net::HTTP_BAD_REQUEST,
219 net::URLRequestStatus::SUCCESS);
220 ASSERT_TRUE(AttemptToTriggerAuthError());
221 ASSERT_TRUE(GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
224 // Verify that ProfileSyncService retries after REQUEST_CANCELED auth error
225 // when OAuth2TokenService has encountered a URLRequestStatus of CANCELED.
226 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryRequestCanceled) {
227 ASSERT_TRUE(SetupSync());
228 ASSERT_FALSE(AttemptToTriggerAuthError());
229 GetFakeServer()->SetUnauthenticated();
230 DisableTokenFetchRetries();
231 SetOAuth2TokenResponse(kEmptyOAuth2Token,
232 net::HTTP_INTERNAL_SERVER_ERROR,
233 net::URLRequestStatus::CANCELED);
234 ASSERT_TRUE(AttemptToTriggerAuthError());
235 ASSERT_TRUE(GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
238 // Verify that ProfileSyncService fails initial sync setup during backend
239 // initialization and ends up with an INVALID_GAIA_CREDENTIALS auth error when
240 // an invalid_grant error is returned by OAuth2TokenService with an
241 // HTTP_BAD_REQUEST (400) response code.
242 IN_PROC_BROWSER_TEST_F(SyncAuthTest, FailInitialSetupWithPersistentError) {
243 ASSERT_TRUE(SetupClients());
244 GetFakeServer()->SetUnauthenticated();
245 DisableTokenFetchRetries();
246 SetOAuth2TokenResponse(kInvalidGrantOAuth2Token,
247 net::HTTP_BAD_REQUEST,
248 net::URLRequestStatus::SUCCESS);
249 ASSERT_FALSE(GetClient(0)->SetupSync());
250 ASSERT_FALSE(GetSyncService((0))->IsSyncActive());
251 ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
252 GetSyncService((0))->GetAuthError().state());
255 // Verify that ProfileSyncService fails initial sync setup during backend
256 // initialization, but continues trying to fetch access tokens when
257 // OAuth2TokenService receives an HTTP_INTERNAL_SERVER_ERROR (500) response
258 // code.
259 IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryInitialSetupWithTransientError) {
260 ASSERT_TRUE(SetupClients());
261 GetFakeServer()->SetUnauthenticated();
262 DisableTokenFetchRetries();
263 SetOAuth2TokenResponse(kEmptyOAuth2Token,
264 net::HTTP_INTERNAL_SERVER_ERROR,
265 net::URLRequestStatus::SUCCESS);
266 ASSERT_FALSE(GetClient(0)->SetupSync());
267 ASSERT_FALSE(GetSyncService((0))->IsSyncActive());
268 ASSERT_TRUE(
269 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
272 // Verify that ProfileSyncService fetches a new token when an old token expires.
273 IN_PROC_BROWSER_TEST_F(SyncAuthTest, TokenExpiry) {
274 // Initial sync succeeds with a short lived OAuth2 Token.
275 ASSERT_TRUE(SetupClients());
276 GetFakeServer()->SetAuthenticated();
277 DisableTokenFetchRetries();
278 SetOAuth2TokenResponse(kShortLivedOAuth2Token,
279 net::HTTP_OK,
280 net::URLRequestStatus::SUCCESS);
281 ASSERT_TRUE(GetClient(0)->SetupSync());
282 std::string old_token = GetSyncService((0))->GetAccessTokenForTest();
284 // Wait until the token has expired.
285 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(5));
287 // Trigger an auth error on the server so PSS requests OA2TS for a new token
288 // during the next sync cycle.
289 GetFakeServer()->SetUnauthenticated();
290 SetOAuth2TokenResponse(kEmptyOAuth2Token,
291 net::HTTP_INTERNAL_SERVER_ERROR,
292 net::URLRequestStatus::SUCCESS);
293 ASSERT_TRUE(AttemptToTriggerAuthError());
294 ASSERT_TRUE(
295 GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
297 // Trigger an auth success state and set up a new valid OAuth2 token.
298 GetFakeServer()->SetAuthenticated();
299 SetOAuth2TokenResponse(kValidOAuth2Token,
300 net::HTTP_OK,
301 net::URLRequestStatus::SUCCESS);
303 // Verify that the next sync cycle is successful, and uses the new auth token.
304 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
305 std::string new_token = GetSyncService((0))->GetAccessTokenForTest();
306 ASSERT_NE(old_token, new_token);