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 3 // found in the LICENSE file. 4 // 5 // A set of unit tests for TokenValidatorFactoryImpl 6 7 #include <string> 8 9 #include "base/json/json_writer.h" 10 #include "base/values.h" 11 #include "net/http/http_status_code.h" 12 #include "net/url_request/url_request_job_factory.h" 13 #include "net/url_request/url_request_job_factory_impl.h" 14 #include "net/url_request/url_request_status.h" 15 #include "net/url_request/url_request_test_job.h" 16 #include "net/url_request/url_request_test_util.h" 17 #include "remoting/base/rsa_key_pair.h" 18 #include "remoting/base/test_rsa_key_pair.h" 19 #include "remoting/host/token_validator_factory_impl.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "url/gurl.h" 22 23 namespace { 24 25 const char kTokenUrl[] = "https://example.com/token"; 26 const char kTokenValidationUrl[] = "https://example.com/validate"; 27 const char kTokenValidationCertIssuer[] = ""; 28 const char kLocalJid[] = "user (at) example.com/local"; 29 const char kRemoteJid[] = "user (at) example.com/remote"; 30 const char kToken[] = "xyz123456"; 31 const char kSharedSecret[] = "abcdefgh"; 32 33 // Bad scope: no nonce element. 34 const char kBadScope[] = 35 "client:user (at) example.com/local host:user (at) example.com/remote"; 36 37 class FakeProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { 38 public: 39 FakeProtocolHandler(const std::string& headers, const std::string& response) 40 : headers_(headers), 41 response_(response) { 42 } 43 virtual net::URLRequestJob* MaybeCreateJob( 44 net::URLRequest* request, net::NetworkDelegate* network_delegate) const 45 OVERRIDE { 46 return new net::URLRequestTestJob( 47 request, network_delegate, headers_, response_, true); 48 } 49 50 private: 51 std::string headers_; 52 std::string response_; 53 }; 54 55 class SetResponseURLRequestContext: public net::TestURLRequestContext { 56 public: 57 void SetResponse(const std::string& headers, const std::string& response) { 58 net::URLRequestJobFactoryImpl* factory = 59 new net::URLRequestJobFactoryImpl(); 60 factory->SetProtocolHandler( 61 "https", new FakeProtocolHandler(headers, response)); 62 context_storage_.set_job_factory(factory); 63 } 64 }; 65 66 } // namespace 67 68 namespace remoting { 69 70 class TokenValidatorFactoryImplTest : public testing::Test { 71 public: 72 TokenValidatorFactoryImplTest() : message_loop_(base::MessageLoop::TYPE_IO) {} 73 74 void SuccessCallback(const std::string& shared_secret) { 75 EXPECT_FALSE(shared_secret.empty()); 76 message_loop_.Quit(); 77 } 78 79 void FailureCallback(const std::string& shared_secret) { 80 EXPECT_TRUE(shared_secret.empty()); 81 message_loop_.Quit(); 82 } 83 84 void DeleteOnFailureCallback(const std::string& shared_secret) { 85 EXPECT_TRUE(shared_secret.empty()); 86 token_validator_.reset(); 87 message_loop_.Quit(); 88 } 89 90 protected: 91 virtual void SetUp() OVERRIDE { 92 key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); 93 scoped_ptr<net::TestURLRequestContext> context( 94 new SetResponseURLRequestContext()); 95 request_context_getter_ = new net::TestURLRequestContextGetter( 96 message_loop_.message_loop_proxy(), context.Pass()); 97 ThirdPartyAuthConfig config; 98 config.token_url = GURL(kTokenUrl); 99 config.token_validation_url = GURL(kTokenValidationUrl); 100 config.token_validation_cert_issuer = kTokenValidationCertIssuer; 101 token_validator_factory_.reset(new TokenValidatorFactoryImpl( 102 config, key_pair_, request_context_getter_)); 103 } 104 105 static std::string CreateResponse(const std::string& scope) { 106 base::DictionaryValue response_dict; 107 response_dict.SetString("access_token", kSharedSecret); 108 response_dict.SetString("token_type", "shared_secret"); 109 response_dict.SetString("scope", scope); 110 std::string response; 111 base::JSONWriter::Write(&response_dict, &response); 112 return response; 113 } 114 115 static std::string CreateErrorResponse(const std::string& error) { 116 base::DictionaryValue response_dict; 117 response_dict.SetString("error", error); 118 std::string response; 119 base::JSONWriter::Write(&response_dict, &response); 120 return response; 121 } 122 123 124 void SetResponse(const std::string& headers, const std::string& response) { 125 SetResponseURLRequestContext* context = 126 static_cast<SetResponseURLRequestContext*>( 127 request_context_getter_->GetURLRequestContext()); 128 context->SetResponse(headers, response); 129 } 130 131 base::MessageLoop message_loop_; 132 scoped_refptr<RsaKeyPair> key_pair_; 133 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 134 scoped_ptr<TokenValidatorFactoryImpl> token_validator_factory_; 135 scoped_ptr<protocol::TokenValidator> token_validator_; 136 }; 137 138 TEST_F(TokenValidatorFactoryImplTest, Success) { 139 token_validator_ = token_validator_factory_->CreateTokenValidator( 140 kLocalJid, kRemoteJid); 141 142 SetResponse(net::URLRequestTestJob::test_headers(), 143 CreateResponse(token_validator_->token_scope())); 144 145 token_validator_->ValidateThirdPartyToken( 146 kToken, base::Bind(&TokenValidatorFactoryImplTest::SuccessCallback, 147 base::Unretained(this))); 148 message_loop_.Run(); 149 } 150 151 TEST_F(TokenValidatorFactoryImplTest, BadToken) { 152 token_validator_ = token_validator_factory_->CreateTokenValidator( 153 kLocalJid, kRemoteJid); 154 155 SetResponse(net::URLRequestTestJob::test_error_headers(), std::string()); 156 157 token_validator_->ValidateThirdPartyToken( 158 kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback, 159 base::Unretained(this))); 160 message_loop_.Run(); 161 } 162 163 TEST_F(TokenValidatorFactoryImplTest, BadScope) { 164 token_validator_ = token_validator_factory_->CreateTokenValidator( 165 kLocalJid, kRemoteJid); 166 167 SetResponse(net::URLRequestTestJob::test_headers(), 168 CreateResponse(kBadScope)); 169 170 token_validator_->ValidateThirdPartyToken( 171 kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback, 172 base::Unretained(this))); 173 message_loop_.Run(); 174 } 175 176 TEST_F(TokenValidatorFactoryImplTest, DeleteOnFailure) { 177 token_validator_ = token_validator_factory_->CreateTokenValidator( 178 kLocalJid, kRemoteJid); 179 180 SetResponse(net::URLRequestTestJob::test_error_headers(), std::string()); 181 182 token_validator_->ValidateThirdPartyToken( 183 kToken, base::Bind( 184 &TokenValidatorFactoryImplTest::DeleteOnFailureCallback, 185 base::Unretained(this))); 186 message_loop_.Run(); 187 } 188 189 } // namespace remoting 190