Index: remoting/protocol/third_party_authenticator_unittest.cc |
diff --git a/remoting/protocol/third_party_authenticator_unittest.cc b/remoting/protocol/third_party_authenticator_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..38204fd36c081b6c95a76f0117665b199f3d5556 |
--- /dev/null |
+++ b/remoting/protocol/third_party_authenticator_unittest.cc |
@@ -0,0 +1,215 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/protocol/third_party_authenticator.h" |
+ |
+#include "base/bind.h" |
+#include "net/base/net_errors.h" |
+#include "remoting/base/rsa_key_pair.h" |
+#include "remoting/protocol/authenticator_test_base.h" |
+#include "remoting/protocol/channel_authenticator.h" |
+#include "remoting/protocol/connection_tester.h" |
+#include "remoting/protocol/fake_authenticator.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
+ |
+using testing::_; |
+using testing::DeleteArg; |
+using testing::SaveArg; |
+ |
+namespace { |
+ |
+const int kMessageSize = 100; |
+const int kMessages = 1; |
+ |
+const char kTokenIssueUrl[] = "https://example.com/Issue"; |
+const char kTokenVerificationUrl[] = "https://example.com/Verify"; |
+const char kTokenScope[] = "host:a@b.com/1 client:a@b.com/2"; |
+const char kToken[] = "abc123456xyz789"; |
+const char kSharedSecret[] = "1234-1234-5678"; |
+const char kSharedSecretBad[] = "0000-0000-0001"; |
+ |
+} // namespace |
+ |
+namespace remoting { |
+namespace protocol { |
+ |
+class ThirdPartyAuthenticatorTest : public AuthenticatorTestBase { |
+ class FakeTokenFetcher |
Wez
2013/03/05 22:55:53
nit: Specify visibility explicitly.
|
+ : public protocol::ThirdPartyAuthenticator::TokenFetcher { |
+ public: |
+ virtual void FetchThirdPartyToken( |
+ const std::string& token_url, |
+ const std::string& host_public_key, |
+ const std::string& scope, |
+ const TokenFetchedCallback& token_fetched_callback) { |
+ on_token_fetched_ = token_fetched_callback; |
+ } |
+ |
+ void OnTokenFetched(const std::string& token, |
+ const std::string& shared_secret) { |
+ on_token_fetched_.Run(token, shared_secret); |
+ on_token_fetched_.Reset(); |
+ } |
+ |
+ private: |
+ TokenFetchedCallback on_token_fetched_; |
+ }; |
+ |
+ class FakeTokenValidator |
+ : public protocol::ThirdPartyAuthenticator::TokenValidator { |
+ public: |
+ FakeTokenValidator() |
+ : token_url_(kTokenIssueUrl), |
+ token_scope_(kTokenScope) {} |
+ |
+ virtual ~FakeTokenValidator() {} |
Wez
2013/03/05 22:55:53
Indentation here & below.
|
+ |
+ virtual void ValidateThirdPartyToken( |
+ const std::string& token, |
+ const TokenValidatedCallback& token_validated_callback) { |
+ on_token_validated_ = token_validated_callback; |
+ } |
+ |
+ void OnTokenValidated(const std::string& shared_secret) { |
+ on_token_validated_.Run(shared_secret); |
+ on_token_validated_.Reset(); |
+ } |
+ |
+ virtual const GURL& token_url() const OVERRIDE { |
+ return token_url_; |
+ } |
+ |
+ virtual const std::string& token_scope() const OVERRIDE { |
+ return token_scope_; |
+ } |
+ |
+ private: |
+ GURL token_url_; |
+ std::string token_scope_; |
+ base::Callback<void(const std::string& shared_secret)> on_token_validated_; |
+ }; |
+ |
+ public: |
+ ThirdPartyAuthenticatorTest() { |
+ } |
+ virtual ~ThirdPartyAuthenticatorTest() { |
+ } |
+ |
+ protected: |
+ void InitAuthenticators() { |
+ scoped_ptr<protocol::ThirdPartyAuthenticator::TokenValidator> |
+ token_validator(new FakeTokenValidator()); |
+ token_validator_ = static_cast<FakeTokenValidator*>(token_validator.get()); |
Wez
2013/03/05 22:55:53
nit: You could new & assign straight to the bare p
|
+ host_ = ThirdPartyAuthenticator::CreateForHost( |
+ host_cert_, key_pair_, |
+ token_validator.Pass(), Authenticator::WAITING_MESSAGE); |
+ scoped_ptr<protocol::ThirdPartyAuthenticator::TokenFetcher> |
Wez
2013/03/05 22:55:53
nit: Blank line here to separate host & client set
|
+ token_fetcher(new FakeTokenFetcher()); |
+ token_fetcher_ = static_cast<FakeTokenFetcher*>(token_fetcher.get()); |
+ client_ = ThirdPartyAuthenticator::CreateForClient( |
+ host_public_key_, token_fetcher.Pass(), Authenticator::MESSAGE_READY); |
+ } |
+ |
+ FakeTokenFetcher* token_fetcher_; |
Wez
2013/03/05 22:55:53
nit: Add a comment to explain that these are owned
|
+ FakeTokenValidator* token_validator_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ThirdPartyAuthenticatorTest); |
+}; |
+ |
+TEST_F(ThirdPartyAuthenticatorTest, SuccessfulAuth) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+// ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
Wez
2013/03/05 22:55:53
Why are these commented out?
|
+ ASSERT_NO_FATAL_FAILURE(token_fetcher_->OnTokenFetched( |
+ kToken, kSharedSecret)); |
+// ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state()); |
+ ASSERT_NO_FATAL_FAILURE( |
+ token_validator_->OnTokenValidated(kSharedSecret)); |
Wez
2013/03/05 22:55:53
nit: Blank line after this
|
+ // Both sides have finished. |
+ ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); |
+ ASSERT_EQ(Authenticator::ACCEPTED, client_->state()); |
+ |
+ // An authenticated channel can be created after the authentication. |
+ client_auth_ = client_->CreateChannelAuthenticator(); |
+ host_auth_ = host_->CreateChannelAuthenticator(); |
+ RunChannelAuth(false); |
+ |
+ StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), |
+ kMessageSize, kMessages); |
+ |
+ tester.Start(); |
+ message_loop_.Run(); |
+ tester.CheckResults(); |
+} |
+ |
+TEST_F(ThirdPartyAuthenticatorTest, ClientNoSecret) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
+ ASSERT_NO_FATAL_FAILURE(token_fetcher_->OnTokenFetched(kToken, "")); |
+ // The end result is that the client rejected the connection, since it |
Wez
2013/03/05 22:55:53
nit: Blank line before this comment.
|
+ // couldn't fetch the secret. |
Wez
2013/03/05 22:55:53
nit: Suggest: "The client must reject the connecti
|
+ ASSERT_EQ(Authenticator::REJECTED, client_->state()); |
+} |
+ |
+TEST_F(ThirdPartyAuthenticatorTest, InvalidToken) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
+ ASSERT_NO_FATAL_FAILURE(token_fetcher_->OnTokenFetched( |
+ kToken, kSharedSecret)); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state()); |
+ ASSERT_NO_FATAL_FAILURE(token_validator_->OnTokenValidated("")); |
+ |
+ // The end result is that the host rejected the token. |
Wez
2013/03/05 22:55:53
nit: Suggest "The host must reject the connection,
|
+ ASSERT_EQ(Authenticator::REJECTED, host_->state()); |
+} |
+ |
+TEST_F(ThirdPartyAuthenticatorTest, CannotFetchToken) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
+ ASSERT_NO_FATAL_FAILURE(token_fetcher_->OnTokenFetched("", "")); |
+ |
+ // The end result is that the client rejected the connection, since it |
+ // couldn't fetch the token. |
Wez
2013/03/05 22:55:53
See suggestions above re wording.
|
+ ASSERT_EQ(Authenticator::REJECTED, client_->state()); |
+} |
+ |
+// Test that negotiation stops when the fake authentication is rejected. |
+TEST_F(ThirdPartyAuthenticatorTest, HostBadSecret) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+ |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
+ ASSERT_NO_FATAL_FAILURE(token_fetcher_->OnTokenFetched( |
+ kToken, kSharedSecret)); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state()); |
+ ASSERT_NO_FATAL_FAILURE( |
+ token_validator_->OnTokenValidated(kSharedSecretBad)); |
+ |
+ // The end result is that the host rejected the fake authentication. |
Wez
2013/03/05 22:55:53
Ditto
|
+ ASSERT_EQ(Authenticator::REJECTED, client_->state()); |
+} |
+ |
+TEST_F(ThirdPartyAuthenticatorTest, ClientBadSecret) { |
+ ASSERT_NO_FATAL_FAILURE(InitAuthenticators()); |
+ ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); |
+ |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, client_->state()); |
+ ASSERT_NO_FATAL_FAILURE( |
+ token_fetcher_->OnTokenFetched(kToken, kSharedSecretBad)); |
+ ASSERT_EQ(Authenticator::PROCESSING_MESSAGE, host_->state()); |
+ ASSERT_NO_FATAL_FAILURE( |
+ token_validator_->OnTokenValidated(kSharedSecret)); |
+ |
+ // The end result is that the host rejected the fake authentication. |
Wez
2013/03/05 22:55:53
Ditto
|
+ ASSERT_EQ(Authenticator::REJECTED, client_->state()); |
+} |
+ |
+} // namespace protocol |
+} // namespace remoting |