| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/chromeos/settings/device_oauth2_token_service.h" | 5 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/prefs/testing_pref_service.h" | 8 #include "base/prefs/testing_pref_service.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "chrome/common/pref_names.h" | 10 #include "chrome/common/pref_names.h" |
| 11 #include "chrome/test/base/scoped_testing_local_state.h" | 11 #include "chrome/test/base/scoped_testing_local_state.h" |
| 12 #include "chrome/test/base/testing_browser_process.h" | 12 #include "chrome/test/base/testing_browser_process.h" |
| 13 #include "chromeos/cryptohome/mock_cryptohome_library.h" | |
| 14 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 15 #include "content/public/test/test_browser_thread.h" | 14 #include "content/public/test/test_browser_thread.h" |
| 16 #include "google_apis/gaia/gaia_oauth_client.h" | 15 #include "google_apis/gaia/gaia_oauth_client.h" |
| 17 #include "google_apis/gaia/oauth2_token_service_test_util.h" | 16 #include "google_apis/gaia/oauth2_token_service_test_util.h" |
| 18 #include "net/http/http_status_code.h" | 17 #include "net/http/http_status_code.h" |
| 19 #include "net/url_request/test_url_fetcher_factory.h" | 18 #include "net/url_request/test_url_fetcher_factory.h" |
| 20 #include "net/url_request/url_fetcher_delegate.h" | 19 #include "net/url_request/url_fetcher_delegate.h" |
| 21 #include "net/url_request/url_request_test_util.h" | 20 #include "net/url_request/url_request_test_util.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 24 | 23 |
| 25 using ::testing::_; | 24 using ::testing::_; |
| 26 using ::testing::AnyNumber; | 25 using ::testing::AnyNumber; |
| 27 using ::testing::Return; | 26 using ::testing::Return; |
| 27 using ::testing::ReturnArg; |
| 28 using ::testing::StrEq; | 28 using ::testing::StrEq; |
| 29 using ::testing::StrictMock; | 29 using ::testing::StrictMock; |
| 30 | 30 |
| 31 namespace chromeos { | 31 namespace chromeos { |
| 32 | 32 |
| 33 static const int kOAuthTokenServiceUrlFetcherId = 0; | 33 static const int kOAuthTokenServiceUrlFetcherId = 0; |
| 34 static const int kValidatorUrlFetcherId = gaia::GaiaOAuthClient::kUrlFetcherId; | 34 static const int kValidatorUrlFetcherId = gaia::GaiaOAuthClient::kUrlFetcherId; |
| 35 | 35 |
| 36 class TestDeviceOAuth2TokenService : public DeviceOAuth2TokenService { | 36 class TestDeviceOAuth2TokenService : public DeviceOAuth2TokenService { |
| 37 public: | 37 public: |
| 38 explicit TestDeviceOAuth2TokenService(net::URLRequestContextGetter* getter, | 38 explicit TestDeviceOAuth2TokenService(net::URLRequestContextGetter* getter, |
| 39 PrefService* local_state) | 39 PrefService* local_state, |
| 40 : DeviceOAuth2TokenService(getter, local_state) { | 40 TokenEncryptor* token_encryptor) |
| 41 : DeviceOAuth2TokenService(getter, |
| 42 local_state, |
| 43 token_encryptor) { |
| 41 } | 44 } |
| 42 void SetRobotAccountIdPolicyValue(const std::string& id) { | 45 void SetRobotAccountIdPolicyValue(const std::string& id) { |
| 43 robot_account_id_ = id; | 46 robot_account_id_ = id; |
| 44 } | 47 } |
| 45 | 48 |
| 46 // Skip calling into the policy subsystem and return our test value. | 49 // Skip calling into the policy subsystem and return our test value. |
| 47 virtual std::string GetRobotAccountId() OVERRIDE { | 50 virtual std::string GetRobotAccountId() OVERRIDE { |
| 48 return robot_account_id_; | 51 return robot_account_id_; |
| 49 } | 52 } |
| 50 | 53 |
| 51 private: | 54 private: |
| 52 std::string robot_account_id_; | 55 std::string robot_account_id_; |
| 53 DISALLOW_COPY_AND_ASSIGN(TestDeviceOAuth2TokenService); | 56 DISALLOW_COPY_AND_ASSIGN(TestDeviceOAuth2TokenService); |
| 54 }; | 57 }; |
| 55 | 58 |
| 59 class MockTokenEncryptor : public TokenEncryptor { |
| 60 public: |
| 61 MOCK_METHOD1(EncryptWithSystemSalt, std::string(const std::string&)); |
| 62 MOCK_METHOD1(DecryptWithSystemSalt, std::string(const std::string&)); |
| 63 }; |
| 64 |
| 56 class DeviceOAuth2TokenServiceTest : public testing::Test { | 65 class DeviceOAuth2TokenServiceTest : public testing::Test { |
| 57 public: | 66 public: |
| 58 DeviceOAuth2TokenServiceTest() | 67 DeviceOAuth2TokenServiceTest() |
| 59 : ui_thread_(content::BrowserThread::UI, &message_loop_), | 68 : ui_thread_(content::BrowserThread::UI, &message_loop_), |
| 60 scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()), | 69 scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()), |
| 61 request_context_getter_(new net::TestURLRequestContextGetter( | 70 request_context_getter_(new net::TestURLRequestContextGetter( |
| 62 message_loop_.message_loop_proxy())), | 71 message_loop_.message_loop_proxy())), |
| 72 mock_token_encryptor_(new StrictMock<MockTokenEncryptor>), |
| 63 oauth2_service_(request_context_getter_.get(), | 73 oauth2_service_(request_context_getter_.get(), |
| 64 scoped_testing_local_state_.Get()) { | 74 scoped_testing_local_state_.Get(), |
| 75 mock_token_encryptor_) { |
| 65 oauth2_service_.max_refresh_token_validation_retries_ = 0; | 76 oauth2_service_.max_refresh_token_validation_retries_ = 0; |
| 66 oauth2_service_.set_max_authorization_token_fetch_retries_for_testing(0); | 77 oauth2_service_.set_max_authorization_token_fetch_retries_for_testing(0); |
| 67 } | 78 } |
| 68 virtual ~DeviceOAuth2TokenServiceTest() {} | 79 virtual ~DeviceOAuth2TokenServiceTest() {} |
| 69 | 80 |
| 70 // Most tests just want a noop crypto impl with a dummy refresh token value in | 81 // Most tests just want a noop crypto impl with a dummy refresh token value in |
| 71 // Local State (if the value is an empty string, it will be ignored). | 82 // Local State (if the value is an empty string, it will be ignored). |
| 72 void SetUpDefaultValues() { | 83 void SetUpDefaultValues() { |
| 73 cryptohome_library_.reset(chromeos::CryptohomeLibrary::GetTestImpl()); | |
| 74 chromeos::CryptohomeLibrary::SetForTest(cryptohome_library_.get()); | |
| 75 SetDeviceRefreshTokenInLocalState("device_refresh_token_4_test"); | 84 SetDeviceRefreshTokenInLocalState("device_refresh_token_4_test"); |
| 76 oauth2_service_.SetRobotAccountIdPolicyValue("service_acct@g.com"); | 85 oauth2_service_.SetRobotAccountIdPolicyValue("service_acct@g.com"); |
| 77 AssertConsumerTokensAndErrors(0, 0); | 86 AssertConsumerTokensAndErrors(0, 0); |
| 87 |
| 88 // Returns the input token as-is. |
| 89 EXPECT_CALL(*mock_token_encryptor_, DecryptWithSystemSalt(_)) |
| 90 .WillRepeatedly(ReturnArg<0>()); |
| 78 } | 91 } |
| 79 | 92 |
| 80 scoped_ptr<OAuth2TokenService::Request> StartTokenRequest() { | 93 scoped_ptr<OAuth2TokenService::Request> StartTokenRequest() { |
| 81 return oauth2_service_.StartRequest(oauth2_service_.GetRobotAccountId(), | 94 return oauth2_service_.StartRequest(oauth2_service_.GetRobotAccountId(), |
| 82 std::set<std::string>(), | 95 std::set<std::string>(), |
| 83 &consumer_); | 96 &consumer_); |
| 84 } | 97 } |
| 85 | 98 |
| 86 virtual void TearDown() OVERRIDE { | 99 virtual void TearDown() OVERRIDE { |
| 87 CryptohomeLibrary::SetForTest(NULL); | |
| 88 base::RunLoop().RunUntilIdle(); | 100 base::RunLoop().RunUntilIdle(); |
| 89 } | 101 } |
| 90 | 102 |
| 91 // Utility method to set a value in Local State for the device refresh token | 103 // Utility method to set a value in Local State for the device refresh token |
| 92 // (it must have a non-empty value or it won't be used). | 104 // (it must have a non-empty value or it won't be used). |
| 93 void SetDeviceRefreshTokenInLocalState(const std::string& refresh_token) { | 105 void SetDeviceRefreshTokenInLocalState(const std::string& refresh_token) { |
| 94 scoped_testing_local_state_.Get()->SetManagedPref( | 106 scoped_testing_local_state_.Get()->SetManagedPref( |
| 95 prefs::kDeviceRobotAnyApiRefreshToken, | 107 prefs::kDeviceRobotAnyApiRefreshToken, |
| 96 Value::CreateStringValue(refresh_token)); | 108 Value::CreateStringValue(refresh_token)); |
| 97 } | 109 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 115 const std::string& response_string); | 127 const std::string& response_string); |
| 116 | 128 |
| 117 void AssertConsumerTokensAndErrors(int num_tokens, int num_errors); | 129 void AssertConsumerTokensAndErrors(int num_tokens, int num_errors); |
| 118 | 130 |
| 119 protected: | 131 protected: |
| 120 base::MessageLoop message_loop_; | 132 base::MessageLoop message_loop_; |
| 121 content::TestBrowserThread ui_thread_; | 133 content::TestBrowserThread ui_thread_; |
| 122 ScopedTestingLocalState scoped_testing_local_state_; | 134 ScopedTestingLocalState scoped_testing_local_state_; |
| 123 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; | 135 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; |
| 124 net::TestURLFetcherFactory factory_; | 136 net::TestURLFetcherFactory factory_; |
| 137 // Owned by oauth2_service_. |
| 138 StrictMock<MockTokenEncryptor>* mock_token_encryptor_; |
| 125 TestDeviceOAuth2TokenService oauth2_service_; | 139 TestDeviceOAuth2TokenService oauth2_service_; |
| 126 TestingOAuth2TokenServiceConsumer consumer_; | 140 TestingOAuth2TokenServiceConsumer consumer_; |
| 127 scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_library_; | |
| 128 | |
| 129 }; | 141 }; |
| 130 | 142 |
| 131 void DeviceOAuth2TokenServiceTest::ReturnOAuthUrlFetchResults( | 143 void DeviceOAuth2TokenServiceTest::ReturnOAuthUrlFetchResults( |
| 132 int fetcher_id, | 144 int fetcher_id, |
| 133 net::HttpStatusCode response_code, | 145 net::HttpStatusCode response_code, |
| 134 const std::string& response_string) { | 146 const std::string& response_string) { |
| 135 | 147 |
| 136 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(fetcher_id); | 148 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(fetcher_id); |
| 137 ASSERT_TRUE(fetcher); | 149 ASSERT_TRUE(fetcher); |
| 138 fetcher->set_response_code(response_code); | 150 fetcher->set_response_code(response_code); |
| 139 fetcher->SetResponseString(response_string); | 151 fetcher->SetResponseString(response_string); |
| 140 fetcher->delegate()->OnURLFetchComplete(fetcher); | 152 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 141 } | 153 } |
| 142 | 154 |
| 143 void DeviceOAuth2TokenServiceTest::AssertConsumerTokensAndErrors( | 155 void DeviceOAuth2TokenServiceTest::AssertConsumerTokensAndErrors( |
| 144 int num_tokens, | 156 int num_tokens, |
| 145 int num_errors) { | 157 int num_errors) { |
| 146 ASSERT_EQ(num_tokens, consumer_.number_of_successful_tokens_); | 158 ASSERT_EQ(num_tokens, consumer_.number_of_successful_tokens_); |
| 147 ASSERT_EQ(num_errors, consumer_.number_of_errors_); | 159 ASSERT_EQ(num_errors, consumer_.number_of_errors_); |
| 148 } | 160 } |
| 149 | 161 |
| 150 TEST_F(DeviceOAuth2TokenServiceTest, SaveEncryptedToken) { | 162 TEST_F(DeviceOAuth2TokenServiceTest, SaveEncryptedToken) { |
| 151 StrictMock<MockCryptohomeLibrary> mock_cryptohome_library; | 163 EXPECT_CALL(*mock_token_encryptor_, DecryptWithSystemSalt(StrEq(""))) |
| 152 CryptohomeLibrary::SetForTest(&mock_cryptohome_library); | |
| 153 | |
| 154 EXPECT_CALL(mock_cryptohome_library, DecryptWithSystemSalt(StrEq(""))) | |
| 155 .Times(1) | 164 .Times(1) |
| 156 .WillOnce(Return("")); | 165 .WillOnce(Return("")); |
| 157 EXPECT_CALL(mock_cryptohome_library, | 166 EXPECT_CALL(*mock_token_encryptor_, |
| 158 EncryptWithSystemSalt(StrEq("test-token"))) | 167 EncryptWithSystemSalt(StrEq("test-token"))) |
| 159 .Times(1) | 168 .Times(1) |
| 160 .WillOnce(Return("encrypted")); | 169 .WillOnce(Return("encrypted")); |
| 161 EXPECT_CALL(mock_cryptohome_library, | 170 EXPECT_CALL(*mock_token_encryptor_, |
| 162 DecryptWithSystemSalt(StrEq("encrypted"))) | 171 DecryptWithSystemSalt(StrEq("encrypted"))) |
| 163 .Times(1) | 172 .Times(1) |
| 164 .WillOnce(Return("test-token")); | 173 .WillOnce(Return("test-token")); |
| 165 | 174 |
| 166 ASSERT_EQ("", oauth2_service_.GetRefreshToken( | 175 ASSERT_EQ("", oauth2_service_.GetRefreshToken( |
| 167 oauth2_service_.GetRobotAccountId())); | 176 oauth2_service_.GetRobotAccountId())); |
| 168 oauth2_service_.SetAndSaveRefreshToken("test-token"); | 177 oauth2_service_.SetAndSaveRefreshToken("test-token"); |
| 169 ASSERT_EQ("test-token", oauth2_service_.GetRefreshToken( | 178 ASSERT_EQ("test-token", oauth2_service_.GetRefreshToken( |
| 170 oauth2_service_.GetRobotAccountId())); | 179 oauth2_service_.GetRobotAccountId())); |
| 171 | 180 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 kValidatorUrlFetcherId, | 372 kValidatorUrlFetcherId, |
| 364 net::HTTP_OK, | 373 net::HTTP_OK, |
| 365 GetValidTokenInfoResponse("service_acct@g.com")); | 374 GetValidTokenInfoResponse("service_acct@g.com")); |
| 366 | 375 |
| 367 // All fetches were successful, but consumer still given error since | 376 // All fetches were successful, but consumer still given error since |
| 368 // the token owner doesn't match the policy value. | 377 // the token owner doesn't match the policy value. |
| 369 AssertConsumerTokensAndErrors(0, 1); | 378 AssertConsumerTokensAndErrors(0, 1); |
| 370 } | 379 } |
| 371 | 380 |
| 372 } // namespace chromeos | 381 } // namespace chromeos |
| OLD | NEW |