| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/login/google_authenticator.h" | 5 #include "chrome/browser/chromeos/login/google_authenticator.h" |
| 6 #include "chrome/browser/chromeos/login/client_login_response_handler.h" | 6 #include "chrome/browser/chromeos/login/client_login_response_handler.h" |
| 7 #include "chrome/browser/chromeos/login/issue_response_handler.h" | 7 #include "chrome/browser/chromeos/login/issue_response_handler.h" |
| 8 | 8 |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
| 15 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" | 15 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" |
| 16 #include "chrome/browser/chromeos/cros/mock_library_loader.h" |
| 16 #include "chrome/browser/chromeos/login/mock_auth_response_handler.h" | 17 #include "chrome/browser/chromeos/login/mock_auth_response_handler.h" |
| 17 #include "chrome/browser/chrome_thread.h" | 18 #include "chrome/browser/chrome_thread.h" |
| 18 #include "chrome/browser/net/url_fetcher.h" | 19 #include "chrome/browser/net/url_fetcher.h" |
| 19 #include "googleurl/src/gurl.h" | 20 #include "googleurl/src/gurl.h" |
| 20 #include "net/url_request/url_request_status.h" | 21 #include "net/url_request/url_request_status.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
| 23 | 24 |
| 24 namespace chromeos { | 25 namespace chromeos { |
| 26 using ::testing::AnyNumber; |
| 25 using ::testing::InvokeWithoutArgs; | 27 using ::testing::InvokeWithoutArgs; |
| 26 using ::testing::Return; | 28 using ::testing::Return; |
| 27 using ::testing::_; | 29 using ::testing::_; |
| 28 | 30 |
| 29 class MockConsumer : public LoginStatusConsumer { | 31 class MockConsumer : public LoginStatusConsumer { |
| 30 public: | 32 public: |
| 31 MockConsumer() {} | 33 MockConsumer() {} |
| 32 ~MockConsumer() {} | 34 ~MockConsumer() {} |
| 33 MOCK_METHOD1(OnLoginFailure, void(const std::string error)); | 35 MOCK_METHOD1(OnLoginFailure, void(const std::string error)); |
| 34 MOCK_METHOD2(OnLoginSuccess, void(const std::string username, | 36 MOCK_METHOD2(OnLoginSuccess, void(const std::string username, |
| 35 const std::vector<std::string> cookies)); | 37 const std::vector<std::string> cookies)); |
| 36 }; | 38 }; |
| 37 | 39 |
| 38 class GoogleAuthenticatorTest : public ::testing::Test { | 40 class GoogleAuthenticatorTest : public ::testing::Test { |
| 39 public: | 41 public: |
| 40 GoogleAuthenticatorTest() : username_("me@nowhere.org") { | 42 GoogleAuthenticatorTest() : username_("me@nowhere.org") { |
| 41 memset(fake_hash_, 0, sizeof(fake_hash_)); | 43 memset(fake_hash_, 0, sizeof(fake_hash_)); |
| 42 fake_hash_[0] = 10; | 44 fake_hash_[0] = 10; |
| 43 fake_hash_[1] = 1; | 45 fake_hash_[1] = 1; |
| 44 fake_hash_[7] = 10 << 4; | 46 fake_hash_[7] = 10 << 4; |
| 45 hash_ascii_.assign("0a010000000000a0"); | 47 hash_ascii_.assign("0a010000000000a0"); |
| 46 hash_ascii_.append(std::string(16,'0')); | 48 hash_ascii_.append(std::string(16,'0')); |
| 47 } | 49 } |
| 48 ~GoogleAuthenticatorTest() {} | 50 ~GoogleAuthenticatorTest() {} |
| 49 | 51 |
| 52 virtual void SetUp() { |
| 53 chromeos::CrosLibrary::TestApi* test_api = |
| 54 chromeos::CrosLibrary::Get()->GetTestApi(); |
| 55 |
| 56 loader_ = new MockLibraryLoader(); |
| 57 ON_CALL(*loader_, Load(_)) |
| 58 .WillByDefault(Return(true)); |
| 59 EXPECT_CALL(*loader_, Load(_)) |
| 60 .Times(AnyNumber()); |
| 61 |
| 62 test_api->SetLibraryLoader(loader_); |
| 63 |
| 64 mock_library_ = new MockCryptohomeLibrary(); |
| 65 test_api->SetCryptohomeLibrary(mock_library_); |
| 66 } |
| 67 |
| 68 // Tears down the test fixture. |
| 69 virtual void TearDown() { |
| 70 } |
| 71 |
| 50 unsigned char fake_hash_[32]; | 72 unsigned char fake_hash_[32]; |
| 51 std::string hash_ascii_; | 73 std::string hash_ascii_; |
| 52 std::string username_; | 74 std::string username_; |
| 53 ResponseCookies cookies_; | 75 ResponseCookies cookies_; |
| 76 // Mocks, destroyed by CrosLibrary class. |
| 77 MockCryptohomeLibrary* mock_library_; |
| 78 MockLibraryLoader* loader_; |
| 54 }; | 79 }; |
| 55 | 80 |
| 56 TEST_F(GoogleAuthenticatorTest, SaltToAsciiTest) { | 81 TEST_F(GoogleAuthenticatorTest, SaltToAsciiTest) { |
| 57 unsigned char fake_salt[8] = { 0 }; | 82 unsigned char fake_salt[8] = { 0 }; |
| 58 fake_salt[0] = 10; | 83 fake_salt[0] = 10; |
| 59 fake_salt[1] = 1; | 84 fake_salt[1] = 1; |
| 60 fake_salt[7] = 10 << 4; | 85 fake_salt[7] = 10 << 4; |
| 61 std::vector<unsigned char> salt_v(fake_salt, fake_salt + sizeof(fake_salt)); | 86 std::vector<unsigned char> salt_v(fake_salt, fake_salt + sizeof(fake_salt)); |
| 62 | 87 |
| 63 MockCryptohomeLibrary library; | 88 GoogleAuthenticator auth(NULL, NULL, NULL); |
| 64 GoogleAuthenticator auth(NULL, &library, NULL, NULL); | |
| 65 auth.set_system_salt(salt_v); | 89 auth.set_system_salt(salt_v); |
| 66 | 90 |
| 67 EXPECT_EQ("0a010000000000a0", auth.SaltAsAscii()); | 91 EXPECT_EQ("0a010000000000a0", auth.SaltAsAscii()); |
| 68 } | 92 } |
| 69 | 93 |
| 70 TEST_F(GoogleAuthenticatorTest, ClientLoginResponseHandlerTest) { | 94 TEST_F(GoogleAuthenticatorTest, ClientLoginResponseHandlerTest) { |
| 71 ClientLoginResponseHandler handler(NULL); | 95 ClientLoginResponseHandler handler(NULL); |
| 72 std::string input("a\nb\n"); | 96 std::string input("a\nb\n"); |
| 73 std::string expected("a&b&"); | 97 std::string expected("a&b&"); |
| 74 expected.append(ClientLoginResponseHandler::kService); | 98 expected.append(ClientLoginResponseHandler::kService); |
| 75 | 99 |
| 76 scoped_ptr<URLFetcher> fetcher(handler.Handle(input, NULL)); | 100 scoped_ptr<URLFetcher> fetcher(handler.Handle(input, NULL)); |
| 77 EXPECT_EQ(expected, handler.payload()); | 101 EXPECT_EQ(expected, handler.payload()); |
| 78 } | 102 } |
| 79 | 103 |
| 80 TEST_F(GoogleAuthenticatorTest, IssueResponseHandlerTest) { | 104 TEST_F(GoogleAuthenticatorTest, IssueResponseHandlerTest) { |
| 81 IssueResponseHandler handler(NULL); | 105 IssueResponseHandler handler(NULL); |
| 82 std::string input("a\n"); | 106 std::string input("a\n"); |
| 83 std::string expected(IssueResponseHandler::kTokenAuthUrl); | 107 std::string expected(IssueResponseHandler::kTokenAuthUrl); |
| 84 expected.append(input); | 108 expected.append(input); |
| 85 | 109 |
| 86 scoped_ptr<URLFetcher> fetcher(handler.Handle(input, NULL)); | 110 scoped_ptr<URLFetcher> fetcher(handler.Handle(input, NULL)); |
| 87 EXPECT_EQ(expected, handler.token_url()); | 111 EXPECT_EQ(expected, handler.token_url()); |
| 88 } | 112 } |
| 89 | 113 |
| 90 TEST_F(GoogleAuthenticatorTest, OnLoginSuccessTest) { | 114 TEST_F(GoogleAuthenticatorTest, OnLoginSuccessTest) { |
| 91 MockConsumer consumer; | 115 MockConsumer consumer; |
| 92 EXPECT_CALL(consumer, OnLoginSuccess(username_, _)); | 116 EXPECT_CALL(consumer, OnLoginSuccess(username_, _)); |
| 93 | 117 |
| 94 MockCryptohomeLibrary library; | 118 EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_)) |
| 95 EXPECT_CALL(library, Mount(username_, hash_ascii_)) | |
| 96 .WillOnce(Return(true)); | 119 .WillOnce(Return(true)); |
| 97 | 120 |
| 98 GoogleAuthenticator auth(&consumer, &library, NULL, NULL); | 121 GoogleAuthenticator auth(&consumer, NULL, NULL); |
| 99 auth.OnLoginSuccess(&consumer, &library, username_, hash_ascii_, cookies_); | 122 auth.OnLoginSuccess(&consumer, username_, hash_ascii_, |
| 123 cookies_); |
| 100 } | 124 } |
| 101 | 125 |
| 102 TEST_F(GoogleAuthenticatorTest, MountFailureTest) { | 126 TEST_F(GoogleAuthenticatorTest, MountFailureTest) { |
| 103 MockConsumer consumer; | 127 MockConsumer consumer; |
| 104 EXPECT_CALL(consumer, OnLoginFailure(_)); | 128 EXPECT_CALL(consumer, OnLoginFailure(_)); |
| 105 | 129 |
| 106 MockCryptohomeLibrary library; | 130 EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_)) |
| 107 EXPECT_CALL(library, Mount(username_, hash_ascii_)) | |
| 108 .WillOnce(Return(false)); | 131 .WillOnce(Return(false)); |
| 109 | 132 |
| 110 GoogleAuthenticator auth(&consumer, &library, NULL, NULL); | 133 GoogleAuthenticator auth(&consumer, NULL, NULL); |
| 111 auth.OnLoginSuccess(&consumer, &library, username_, hash_ascii_, cookies_); | 134 auth.OnLoginSuccess(&consumer, username_, hash_ascii_, |
| 135 cookies_); |
| 112 } | 136 } |
| 113 | 137 |
| 114 static void Quit() { MessageLoop::current()->Quit(); } | 138 static void Quit() { MessageLoop::current()->Quit(); } |
| 115 TEST_F(GoogleAuthenticatorTest, LoginNetFailureTest) { | 139 TEST_F(GoogleAuthenticatorTest, LoginNetFailureTest) { |
| 116 MessageLoopForUI message_loop; | 140 MessageLoopForUI message_loop; |
| 117 ChromeThread ui_thread(ChromeThread::UI, &message_loop); | 141 ChromeThread ui_thread(ChromeThread::UI, &message_loop); |
| 118 | 142 |
| 119 int error_no = ECONNRESET; | 143 int error_no = ECONNRESET; |
| 120 std::string data(strerror(error_no)); | 144 std::string data(strerror(error_no)); |
| 121 GURL source; | 145 GURL source; |
| 122 | 146 |
| 123 URLRequestStatus status(URLRequestStatus::FAILED, error_no); | 147 URLRequestStatus status(URLRequestStatus::FAILED, error_no); |
| 124 | 148 |
| 125 MockConsumer consumer; | 149 MockConsumer consumer; |
| 126 EXPECT_CALL(consumer, OnLoginFailure(data)) | 150 EXPECT_CALL(consumer, OnLoginFailure(data)) |
| 127 .WillOnce(InvokeWithoutArgs(Quit)); | 151 .WillOnce(InvokeWithoutArgs(Quit)); |
| 128 MockCryptohomeLibrary library; | 152 EXPECT_CALL(*mock_library_, CheckKey(username_, hash_ascii_)) |
| 129 EXPECT_CALL(library, CheckKey(username_, hash_ascii_)) | |
| 130 .WillOnce(Return(false)); | 153 .WillOnce(Return(false)); |
| 131 | 154 |
| 132 GoogleAuthenticator auth(&consumer, &library, NULL, NULL); | 155 GoogleAuthenticator auth(&consumer, NULL, NULL); |
| 133 auth.set_password_hash(hash_ascii_); | 156 auth.set_password_hash(hash_ascii_); |
| 134 auth.set_username(username_); | 157 auth.set_username(username_); |
| 135 auth.OnURLFetchComplete(NULL, source, status, 0, cookies_, data); | 158 auth.OnURLFetchComplete(NULL, source, status, 0, cookies_, data); |
| 136 MessageLoop::current()->Run(); // So tasks can be posted. | 159 MessageLoop::current()->Run(); // So tasks can be posted. |
| 137 } | 160 } |
| 138 | 161 |
| 139 TEST_F(GoogleAuthenticatorTest, LoginDeniedTest) { | 162 TEST_F(GoogleAuthenticatorTest, LoginDeniedTest) { |
| 140 MessageLoopForUI message_loop; | 163 MessageLoopForUI message_loop; |
| 141 ChromeThread ui_thread(ChromeThread::UI, &message_loop); | 164 ChromeThread ui_thread(ChromeThread::UI, &message_loop); |
| 142 | 165 |
| 143 std::string data("Error: NO!"); | 166 std::string data("Error: NO!"); |
| 144 GURL source(AuthResponseHandler::kTokenAuthUrl); | 167 GURL source(AuthResponseHandler::kTokenAuthUrl); |
| 145 | 168 |
| 146 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); | 169 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); |
| 147 | 170 |
| 148 MockConsumer consumer; | 171 MockConsumer consumer; |
| 149 EXPECT_CALL(consumer, OnLoginFailure(data)) | 172 EXPECT_CALL(consumer, OnLoginFailure(data)) |
| 150 .WillOnce(InvokeWithoutArgs(Quit)); | 173 .WillOnce(InvokeWithoutArgs(Quit)); |
| 151 MockCryptohomeLibrary library; | |
| 152 | 174 |
| 153 GoogleAuthenticator auth(&consumer, &library, NULL, NULL); | 175 GoogleAuthenticator auth(&consumer, NULL, NULL); |
| 154 auth.OnURLFetchComplete(NULL, source, status, 403, cookies_, data); | 176 auth.OnURLFetchComplete(NULL, source, status, 403, cookies_, data); |
| 155 MessageLoop::current()->Run(); // So tasks can be posted. | 177 MessageLoop::current()->Run(); // So tasks can be posted. |
| 156 } | 178 } |
| 157 | 179 |
| 158 TEST_F(GoogleAuthenticatorTest, OfflineLoginTest) { | 180 TEST_F(GoogleAuthenticatorTest, OfflineLoginTest) { |
| 159 MessageLoopForUI message_loop; | 181 MessageLoopForUI message_loop; |
| 160 ChromeThread ui_thread(ChromeThread::UI, &message_loop); | 182 ChromeThread ui_thread(ChromeThread::UI, &message_loop); |
| 161 | 183 |
| 162 int error_no = ECONNRESET; | 184 int error_no = ECONNRESET; |
| 163 std::string data(strerror(error_no)); | 185 std::string data(strerror(error_no)); |
| 164 GURL source; | 186 GURL source; |
| 165 | 187 |
| 166 URLRequestStatus status(URLRequestStatus::FAILED, error_no); | 188 URLRequestStatus status(URLRequestStatus::FAILED, error_no); |
| 167 | 189 |
| 168 MockConsumer consumer; | 190 MockConsumer consumer; |
| 169 EXPECT_CALL(consumer, OnLoginSuccess(username_, cookies_)) | 191 EXPECT_CALL(consumer, OnLoginSuccess(username_, cookies_)) |
| 170 .WillOnce(InvokeWithoutArgs(Quit)); | 192 .WillOnce(InvokeWithoutArgs(Quit)); |
| 171 MockCryptohomeLibrary library; | 193 EXPECT_CALL(*mock_library_, CheckKey(username_, hash_ascii_)) |
| 172 EXPECT_CALL(library, CheckKey(username_, hash_ascii_)) | |
| 173 .WillOnce(Return(true)); | 194 .WillOnce(Return(true)); |
| 174 EXPECT_CALL(library, Mount(username_, hash_ascii_)) | 195 EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_)) |
| 175 .WillOnce(Return(true)); | 196 .WillOnce(Return(true)); |
| 176 | 197 |
| 177 GoogleAuthenticator auth(&consumer, &library, NULL, NULL); | 198 GoogleAuthenticator auth(&consumer, NULL, NULL); |
| 178 auth.set_password_hash(hash_ascii_); | 199 auth.set_password_hash(hash_ascii_); |
| 179 auth.set_username(username_); | 200 auth.set_username(username_); |
| 180 auth.OnURLFetchComplete(NULL, source, status, 0, cookies_, data); | 201 auth.OnURLFetchComplete(NULL, source, status, 0, cookies_, data); |
| 181 MessageLoop::current()->Run(); // So tasks can be posted. | 202 MessageLoop::current()->Run(); // So tasks can be posted. |
| 182 } | 203 } |
| 183 | 204 |
| 184 TEST_F(GoogleAuthenticatorTest, ClientLoginPassIssueAuthTokenFailTest) { | 205 TEST_F(GoogleAuthenticatorTest, ClientLoginPassIssueAuthTokenFailTest) { |
| 185 MessageLoopForUI message_loop; | 206 MessageLoopForUI message_loop; |
| 186 ChromeThread ui_thread(ChromeThread::UI, &message_loop); | 207 ChromeThread ui_thread(ChromeThread::UI, &message_loop); |
| 187 | 208 |
| 188 std::string data("Error: NO!"); | 209 std::string data("Error: NO!"); |
| 189 GURL cl_source(AuthResponseHandler::kClientLoginUrl); | 210 GURL cl_source(AuthResponseHandler::kClientLoginUrl); |
| 190 GURL iat_source(AuthResponseHandler::kIssueAuthTokenUrl); | 211 GURL iat_source(AuthResponseHandler::kIssueAuthTokenUrl); |
| 191 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); | 212 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); |
| 192 | 213 |
| 193 MockConsumer consumer; | 214 MockConsumer consumer; |
| 194 EXPECT_CALL(consumer, OnLoginFailure(data)) | 215 EXPECT_CALL(consumer, OnLoginFailure(data)) |
| 195 .WillOnce(InvokeWithoutArgs(Quit)); | 216 .WillOnce(InvokeWithoutArgs(Quit)); |
| 196 MockCryptohomeLibrary library; | |
| 197 MockAuthResponseHandler* cl_handler = new MockAuthResponseHandler; | 217 MockAuthResponseHandler* cl_handler = new MockAuthResponseHandler; |
| 198 EXPECT_CALL(*cl_handler, CanHandle(cl_source)) | 218 EXPECT_CALL(*cl_handler, CanHandle(cl_source)) |
| 199 .WillOnce(Return(true)); | 219 .WillOnce(Return(true)); |
| 200 | 220 |
| 201 GoogleAuthenticator auth(&consumer, | 221 GoogleAuthenticator auth(&consumer, |
| 202 &library, | |
| 203 cl_handler, // takes ownership. | 222 cl_handler, // takes ownership. |
| 204 new IssueResponseHandler(NULL)); | 223 new IssueResponseHandler(NULL)); |
| 205 auth.set_password_hash(hash_ascii_); | 224 auth.set_password_hash(hash_ascii_); |
| 206 auth.set_username(username_); | 225 auth.set_username(username_); |
| 207 | 226 |
| 208 EXPECT_CALL(*cl_handler, Handle(_, &auth)) | 227 EXPECT_CALL(*cl_handler, Handle(_, &auth)) |
| 209 .WillOnce(Return(new URLFetcher(GURL(""), | 228 .WillOnce(Return(new URLFetcher(GURL(""), |
| 210 URLFetcher::POST, | 229 URLFetcher::POST, |
| 211 &auth))); | 230 &auth))); |
| 212 | 231 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 223 TEST_F(GoogleAuthenticatorTest, OnlineLoginTest) { | 242 TEST_F(GoogleAuthenticatorTest, OnlineLoginTest) { |
| 224 MessageLoopForUI message_loop; | 243 MessageLoopForUI message_loop; |
| 225 ChromeThread ui_thread(ChromeThread::UI, &message_loop); | 244 ChromeThread ui_thread(ChromeThread::UI, &message_loop); |
| 226 | 245 |
| 227 GURL source(AuthResponseHandler::kTokenAuthUrl); | 246 GURL source(AuthResponseHandler::kTokenAuthUrl); |
| 228 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); | 247 URLRequestStatus status(URLRequestStatus::SUCCESS, 0); |
| 229 | 248 |
| 230 MockConsumer consumer; | 249 MockConsumer consumer; |
| 231 EXPECT_CALL(consumer, OnLoginSuccess(username_, cookies_)) | 250 EXPECT_CALL(consumer, OnLoginSuccess(username_, cookies_)) |
| 232 .WillOnce(InvokeWithoutArgs(Quit)); | 251 .WillOnce(InvokeWithoutArgs(Quit)); |
| 233 MockCryptohomeLibrary library; | 252 EXPECT_CALL(*mock_library_, Mount(username_, hash_ascii_)) |
| 234 EXPECT_CALL(library, Mount(username_, hash_ascii_)) | |
| 235 .WillOnce(Return(true)); | 253 .WillOnce(Return(true)); |
| 236 | 254 |
| 237 GoogleAuthenticator auth(&consumer, | 255 GoogleAuthenticator auth(&consumer, |
| 238 &library, | |
| 239 new ClientLoginResponseHandler(NULL), | 256 new ClientLoginResponseHandler(NULL), |
| 240 new IssueResponseHandler(NULL)); | 257 new IssueResponseHandler(NULL)); |
| 241 auth.set_password_hash(hash_ascii_); | 258 auth.set_password_hash(hash_ascii_); |
| 242 auth.set_username(username_); | 259 auth.set_username(username_); |
| 243 auth.OnURLFetchComplete(NULL, source, status, 200, cookies_, std::string()); | 260 auth.OnURLFetchComplete(NULL, source, status, 200, cookies_, std::string()); |
| 244 MessageLoop::current()->Run(); // So tasks can be posted. | 261 MessageLoop::current()->Run(); // So tasks can be posted. |
| 245 } | 262 } |
| 246 | 263 |
| 247 } // namespace chromeos | 264 } // namespace chromeos |
| OLD | NEW |