1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A set of unit tests for TokenValidatorFactoryImpl 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/json/json_writer.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_test_util.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/base/rsa_key_pair.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/base/test_rsa_key_pair.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/token_validator_factory_impl.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTokenUrl[] = "https://example.com/token"; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTokenValidationUrl[] = "https://example.com/validate"; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kLocalJid[] = "user@example.com/local"; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kRemoteJid[] = "user@example.com/remote"; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kToken[] = "xyz123456"; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kSharedSecret[] = "abcdefgh"; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Bad scope: no nonce element. 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kBadScope[] = 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "client:user@example.com/local host:user@example.com/remote"; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace remoting { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TokenValidatorFactoryImplTest : public testing::Test { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TokenValidatorFactoryImplTest() : message_loop_(base::MessageLoop::TYPE_IO) {} 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SuccessCallback(const std::string& shared_secret) { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(shared_secret.empty()); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Quit(); 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void FailureCallback(const std::string& shared_secret) { 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(shared_secret.empty()); 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Quit(); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void DeleteOnFailureCallback(const std::string& shared_secret) { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(shared_secret.empty()); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_.reset(); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Quit(); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_context_getter_ = new net::TestURLRequestContextGetter( 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.message_loop_proxy()); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_factory_.reset(new TokenValidatorFactoryImpl( 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL(kTokenUrl), GURL(kTokenValidationUrl), key_pair_, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_context_getter_)); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static std::string CreateResponse(const std::string& scope) { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DictionaryValue response_dict; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_dict.SetString("access_token", kSharedSecret); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_dict.SetString("token_type", "shared_secret"); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_dict.SetString("scope", scope); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string response; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::JSONWriter::Write(&response_dict, &response); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return response; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static std::string CreateErrorResponse(const std::string& error) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DictionaryValue response_dict; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_dict.SetString("error", error); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string response; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::JSONWriter::Write(&response_dict, &response); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return response; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoop message_loop_; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<RsaKeyPair> key_pair_; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TokenValidatorFactoryImpl> token_validator_factory_; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<protocol::ThirdPartyHostAuthenticator::TokenValidator> 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, Success) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::FakeURLFetcherFactory factory(NULL); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_ = token_validator_factory_->CreateTokenValidator( 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kLocalJid, kRemoteJid); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) factory.SetFakeResponse(kTokenValidationUrl, CreateResponse( 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_->token_scope()), true); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_->ValidateThirdPartyToken( 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kToken, base::Bind(&TokenValidatorFactoryImplTest::SuccessCallback, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Run(); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, BadToken) { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::FakeURLFetcherFactory factory(NULL); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_ = token_validator_factory_->CreateTokenValidator( 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kLocalJid, kRemoteJid); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) factory.SetFakeResponse(kTokenValidationUrl, std::string(), false); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_->ValidateThirdPartyToken( 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback, 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Run(); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, BadScope) { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::FakeURLFetcherFactory factory(NULL); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_ = token_validator_factory_->CreateTokenValidator( 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kLocalJid, kRemoteJid); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) factory.SetFakeResponse(kTokenValidationUrl, CreateResponse(kBadScope), true); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_->ValidateThirdPartyToken( 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback, 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Run(); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, DeleteOnFailure) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::FakeURLFetcherFactory factory(NULL); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_ = token_validator_factory_->CreateTokenValidator( 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kLocalJid, kRemoteJid); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) factory.SetFakeResponse(kTokenValidationUrl, std::string(), false); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_validator_->ValidateThirdPartyToken( 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kToken, base::Bind( 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &TokenValidatorFactoryImplTest::DeleteOnFailureCallback, 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.Run(); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace remoting 139