Home | History | Annotate | Download | only in host
      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