1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/testing_pref_service.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/run_loop.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/threading/sequenced_worker_pool.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/policy/device_policy_builder.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/chromeos/settings/token_encryptor.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/pref_names.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/scoped_testing_local_state.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_browser_process.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/cryptohome/system_salt_getter.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/dbus/dbus_thread_manager.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chromeos/dbus/fake_cryptohome_client.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/ownership/mock_owner_key_util.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_browser_thread.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_oauth_client.h"
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service_test_util.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/http/http_status_code.h"
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/url_request/test_url_fetcher_factory.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/url_request/url_fetcher_delegate.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_test_util.h"
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kOAuthTokenServiceUrlFetcherId = 0;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kValidatorUrlFetcherId = gaia::GaiaOAuthClient::kUrlFetcherId;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DeviceOAuth2TokenServiceTest : public testing::Test {
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeviceOAuth2TokenServiceTest()
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        request_context_getter_(new net::TestURLRequestContextGetter(
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            message_loop_.message_loop_proxy())) {}
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~DeviceOAuth2TokenServiceTest() {}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Most tests just want a noop crypto impl with a dummy refresh token value in
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Local State (if the value is an empty string, it will be ignored).
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void SetUpDefaultValues() {
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SetDeviceRefreshTokenInLocalState("device_refresh_token_4_test");
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetRobotAccountId("service_acct@g.com");
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CreateService();
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AssertConsumerTokensAndErrors(0, 0);
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void SetUpWithPendingSalt() {
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_cryptohome_client_->set_system_salt(std::vector<uint8>());
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_cryptohome_client_->SetServiceIsAvailable(false);
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetUpDefaultValues();
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void SetRobotAccountId(const std::string& account_id) {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    device_policy_.policy_data().set_service_account_identity(account_id);
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    device_policy_.Build();
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DeviceSettingsService::Get()->Load();
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    device_settings_test_helper_.Flush();
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> StartTokenRequest() {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return oauth2_service_->StartRequest(oauth2_service_->GetRobotAccountId(),
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         std::set<std::string>(),
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         &consumer_);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_cryptohome_client_ = new FakeCryptohomeClient;
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_cryptohome_client_->SetServiceIsAvailable(true);
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_cryptohome_client_->set_system_salt(
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        FakeCryptohomeClient::GetStubSystemSalt());
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        scoped_ptr<CryptohomeClient>(fake_cryptohome_client_));
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    SystemSaltGetter::Initialize();
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DeviceSettingsService::Initialize();
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_(
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new ownership::MockOwnerKeyUtil());
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    owner_key_util_->SetPublicKeyFromPrivateKey(
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        *device_policy_.GetSigningKey());
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DeviceSettingsService::Get()->SetSessionManager(
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        &device_settings_test_helper_, owner_key_util_);
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CrosSettings::Initialize();
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CrosSettings::Shutdown();
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    TestingBrowserProcess::GetGlobal()->SetBrowserPolicyConnector(NULL);
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::BrowserThread::GetBlockingPool()->FlushForTesting();
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DeviceSettingsService::Get()->UnsetSessionManager();
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DeviceSettingsService::Shutdown();
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    SystemSaltGetter::Shutdown();
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DBusThreadManager::Shutdown();
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop().RunUntilIdle();
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void CreateService() {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    oauth2_service_.reset(new DeviceOAuth2TokenService(
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        request_context_getter_.get(), scoped_testing_local_state_.Get()));
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    oauth2_service_->max_refresh_token_validation_retries_ = 0;
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    oauth2_service_->set_max_authorization_token_fetch_retries_for_testing(0);
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Utility method to set a value in Local State for the device refresh token
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // (it must have a non-empty value or it won't be used).
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void SetDeviceRefreshTokenInLocalState(const std::string& refresh_token) {
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_testing_local_state_.Get()->SetUserPref(
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        prefs::kDeviceRobotAnyApiRefreshToken,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new base::StringValue(refresh_token));
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetValidTokenInfoResponse(const std::string email) {
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return "{ \"email\": \"" + email + "\","
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           "  \"user_id\": \"1234567890\" }";
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool RefreshTokenIsAvailable() {
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return oauth2_service_->RefreshTokenIsAvailable(
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        oauth2_service_->GetRobotAccountId());
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string GetRefreshToken() {
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!RefreshTokenIsAvailable())
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return std::string();
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return oauth2_service_->GetRefreshToken(
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        oauth2_service_->GetRobotAccountId());
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // A utility method to return fake URL results, for testing the refresh token
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // validation logic.  For a successful validation attempt, this method will be
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // called three times for the steps listed below (steps 1 and 2 happen in
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // parallel).
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Step 1a: fetch the access token for the tokeninfo API.
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Step 1b: call the tokeninfo API.
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Step 2:  Fetch the access token for the requested scope
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //          (in this case, cloudprint).
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void ReturnOAuthUrlFetchResults(int fetcher_id,
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  net::HttpStatusCode response_code,
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                  const std::string&  response_string);
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Generates URL fetch replies with the specified results for requests
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // generated by the token service.
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void PerformURLFetchesWithResults(
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HttpStatusCode tokeninfo_access_token_status,
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& tokeninfo_access_token_response,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HttpStatusCode tokeninfo_fetch_status,
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& tokeninfo_fetch_response,
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HttpStatusCode service_access_token_status,
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& service_access_token_response);
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Generates URL fetch replies for the success path.
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void PerformURLFetches();
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void AssertConsumerTokensAndErrors(int num_tokens, int num_errors);
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This is here because DeviceOAuth2TokenService's destructor is private;
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // base::DefaultDeleter therefore doesn't work. However, the test class is
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // declared friend in DeviceOAuth2TokenService, so this deleter works.
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  struct TokenServiceDeleter {
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    inline void operator()(DeviceOAuth2TokenService* ptr) const {
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      delete ptr;
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop message_loop_;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScopedTestingLocalState scoped_testing_local_state_;
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  net::TestURLFetcherFactory factory_;
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeCryptohomeClient* fake_cryptohome_client_;
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DeviceSettingsTestHelper device_settings_test_helper_;
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  policy::DevicePolicyBuilder device_policy_;
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<DeviceOAuth2TokenService, TokenServiceDeleter> oauth2_service_;
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestingOAuth2TokenServiceConsumer consumer_;
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DeviceOAuth2TokenServiceTest::ReturnOAuthUrlFetchResults(
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int fetcher_id,
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    net::HttpStatusCode response_code,
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& response_string) {
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  net::TestURLFetcher* fetcher = factory_.GetFetcherByID(fetcher_id);
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (fetcher) {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    factory_.RemoveFetcherFromMap(fetcher_id);
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fetcher->set_response_code(response_code);
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fetcher->SetResponseString(response_string);
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DeviceOAuth2TokenServiceTest::PerformURLFetchesWithResults(
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::HttpStatusCode tokeninfo_access_token_status,
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& tokeninfo_access_token_response,
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::HttpStatusCode tokeninfo_fetch_status,
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& tokeninfo_fetch_response,
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::HttpStatusCode service_access_token_status,
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& service_access_token_response) {
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ReturnOAuthUrlFetchResults(
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kValidatorUrlFetcherId,
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tokeninfo_access_token_status,
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tokeninfo_access_token_response);
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ReturnOAuthUrlFetchResults(
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kValidatorUrlFetcherId,
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tokeninfo_fetch_status,
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tokeninfo_fetch_response);
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ReturnOAuthUrlFetchResults(
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kOAuthTokenServiceUrlFetcherId,
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      service_access_token_status,
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      service_access_token_response);
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DeviceOAuth2TokenServiceTest::PerformURLFetches() {
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("scoped_access_token", 3600));
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DeviceOAuth2TokenServiceTest::AssertConsumerTokensAndErrors(
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int num_tokens,
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int num_errors) {
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(num_tokens, consumer_.number_of_successful_tokens_);
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(num_errors, consumer_.number_of_errors_);
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, SaveEncryptedToken) {
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CreateService();
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  oauth2_service_->SetAndSaveRefreshToken(
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "test-token", DeviceOAuth2TokenService::StatusCallback());
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("test-token", GetRefreshToken());
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, SaveEncryptedTokenEarly) {
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set a new refresh token without the system salt available.
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpWithPendingSalt();
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  oauth2_service_->SetAndSaveRefreshToken(
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "test-token", DeviceOAuth2TokenService::StatusCallback());
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("test-token", GetRefreshToken());
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make the system salt available.
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->set_system_salt(
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeCryptohomeClient::GetStubSystemSalt());
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->SetServiceIsAvailable(true);
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The original token should still be present.
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("test-token", GetRefreshToken());
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reloading shouldn't change the token either.
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CreateService();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("test-token", GetRefreshToken());
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_Success) {
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetches();
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AssertConsumerTokensAndErrors(1, 0);
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("scoped_access_token", consumer_.last_token_);
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_SuccessAsyncLoad) {
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpWithPendingSalt();
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetches();
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AssertConsumerTokensAndErrors(0, 0);
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->set_system_salt(
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeCryptohomeClient::GetStubSystemSalt());
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->SetServiceIsAvailable(true);
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetches();
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(1, 0);
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("scoped_access_token", consumer_.last_token_);
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_Cancel) {
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request.reset();
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetches();
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Test succeeds if this line is reached without a crash.
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_NoSalt) {
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->set_system_salt(std::vector<uint8>());
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_cryptohome_client_->SetServiceIsAvailable(true);
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpDefaultValues();
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(RefreshTokenIsAvailable());
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest,
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       RefreshTokenValidation_Failure_TokenInfoAccessTokenHttpError) {
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_UNAUTHORIZED, "",
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AssertConsumerTokensAndErrors(0, 1);
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest,
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       RefreshTokenValidation_Failure_TokenInfoAccessTokenInvalidResponse) {
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpDefaultValues();
340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, "invalid response",
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest,
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       RefreshTokenValidation_Failure_TokenInfoApiCallHttpError) {
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_INTERNAL_SERVER_ERROR, "",
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest,
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       RefreshTokenValidation_Failure_TokenInfoApiCallInvalidResponse) {
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, "invalid response",
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest,
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       RefreshTokenValidation_Failure_CloudPrintAccessTokenHttpError) {
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_BAD_REQUEST, "");
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest,
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       RefreshTokenValidation_Failure_CloudPrintAccessTokenInvalidResponse) {
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, "invalid request");
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_Failure_BadOwner) {
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SetUpDefaultValues();
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetRobotAccountId("WRONG_service_acct@g.com");
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("tokeninfo_access_token", 3600),
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AssertConsumerTokensAndErrors(0, 1);
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(DeviceOAuth2TokenServiceTest, RefreshTokenValidation_Retry) {
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUpDefaultValues();
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<OAuth2TokenService::Request> request = StartTokenRequest();
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetchesWithResults(
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_INTERNAL_SERVER_ERROR, "",
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenInfoResponse("service_acct@g.com"),
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::HTTP_OK, GetValidTokenResponse("ignored", 3600));
424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AssertConsumerTokensAndErrors(0, 1);
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Retry should succeed.
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request = StartTokenRequest();
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PerformURLFetches();
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AssertConsumerTokensAndErrors(1, 1);
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
434