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