// 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.
//
// A set of unit tests for TokenValidatorFactoryImpl

#include "remoting/host/token_validator_factory_impl.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/base/test_rsa_key_pair.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace {

const char kTokenUrl[] = "https://example.com/token";
const char kTokenValidationUrl[] = "https://example.com/validate";
const char kTokenValidationCertIssuer[] = "";
const char kLocalJid[] = "user@example.com/local";
const char kRemoteJid[] = "user@example.com/remote";
const char kToken[] = "xyz123456";
const char kSharedSecret[] = "abcdefgh";

// Bad scope: no nonce element.
const char kBadScope[] =
    "client:user@example.com/local host:user@example.com/remote";

class FakeProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  FakeProtocolHandler(const std::string& headers, const std::string& response)
      : headers_(headers),
        response_(response) {
  }

  ~FakeProtocolHandler() override = default;

  net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    return new net::URLRequestTestJob(
        request, network_delegate, headers_, response_, true);
  }

 private:
  std::string headers_;
  std::string response_;
};

// Creates URLRequestJobs that fail at the specified phase.
class FakeFailingProtocolHandler
    : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  FakeFailingProtocolHandler(
      net::URLRequestFailedJob::FailurePhase failure_phase,
      net::Error net_error)
      : failure_phase_(failure_phase), net_error_(net_error) {}

  ~FakeFailingProtocolHandler() override = default;

  net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    return new net::URLRequestFailedJob(request, network_delegate,
                                        failure_phase_, net_error_);
  }

 private:
  const net::URLRequestFailedJob::FailurePhase failure_phase_;
  const net::Error net_error_;
};

class SetResponseURLRequestContext: public net::TestURLRequestContext {
 public:
  void SetResponse(const std::string& headers, const std::string& response) {
    std::unique_ptr<net::URLRequestJobFactoryImpl> factory =
        std::make_unique<net::URLRequestJobFactoryImpl>();
    factory->SetProtocolHandler(
        "https", std::make_unique<FakeProtocolHandler>(headers, response));
    context_storage_.set_job_factory(std::move(factory));
  }

  void SetErrorResponse(net::URLRequestFailedJob::FailurePhase failure_phase,
                        net::Error net_error) {
    std::unique_ptr<net::URLRequestJobFactoryImpl> factory =
        std::make_unique<net::URLRequestJobFactoryImpl>();
    factory->SetProtocolHandler(
        "https",
        std::make_unique<FakeFailingProtocolHandler>(failure_phase, net_error));
    context_storage_.set_job_factory(std::move(factory));
  }
};

}  // namespace

namespace remoting {

class TokenValidatorFactoryImplTest : public testing::Test {
 public:
  TokenValidatorFactoryImplTest() : message_loop_(base::MessageLoop::TYPE_IO) {}

  void SuccessCallback(const std::string& shared_secret) {
    EXPECT_FALSE(shared_secret.empty());
    run_loop_.QuitWhenIdle();
  }

  void FailureCallback(const std::string& shared_secret) {
    EXPECT_TRUE(shared_secret.empty());
    run_loop_.QuitWhenIdle();
  }

  void DeleteOnFailureCallback(const std::string& shared_secret) {
    EXPECT_TRUE(shared_secret.empty());
    token_validator_.reset();
    run_loop_.QuitWhenIdle();
  }

 protected:
  void SetUp() override {
    key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair);
    request_context_getter_ = new net::TestURLRequestContextGetter(
        message_loop_.task_runner(),
        std::make_unique<SetResponseURLRequestContext>());
    ThirdPartyAuthConfig config;
    config.token_url = GURL(kTokenUrl);
    config.token_validation_url = GURL(kTokenValidationUrl);
    config.token_validation_cert_issuer = kTokenValidationCertIssuer;
    token_validator_factory_ = new TokenValidatorFactoryImpl(
        config, key_pair_, request_context_getter_);
  }

  static std::string CreateResponse(const std::string& scope) {
    base::DictionaryValue response_dict;
    response_dict.SetString("access_token", kSharedSecret);
    response_dict.SetString("token_type", "shared_secret");
    response_dict.SetString("scope", scope);
    std::string response;
    base::JSONWriter::Write(response_dict, &response);
    return response;
  }

  static std::string CreateErrorResponse(const std::string& error) {
    base::DictionaryValue response_dict;
    response_dict.SetString("error", error);
    std::string response;
    base::JSONWriter::Write(response_dict, &response);
    return response;
  }


  void SetResponse(const std::string& headers, const std::string& response) {
    SetResponseURLRequestContext* context =
        static_cast<SetResponseURLRequestContext*>(
            request_context_getter_->GetURLRequestContext());
    context->SetResponse(headers, response);
  }

  void SetErrorResponse(net::URLRequestFailedJob::FailurePhase failure_phase,
                        net::Error net_error) {
    SetResponseURLRequestContext* context =
        static_cast<SetResponseURLRequestContext*>(
            request_context_getter_->GetURLRequestContext());
    context->SetErrorResponse(failure_phase, net_error);
  }

  base::MessageLoop message_loop_;
  base::RunLoop run_loop_;
  scoped_refptr<RsaKeyPair> key_pair_;
  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
  scoped_refptr<TokenValidatorFactoryImpl> token_validator_factory_;
  std::unique_ptr<protocol::TokenValidator> token_validator_;
};

TEST_F(TokenValidatorFactoryImplTest, Success) {
  token_validator_ = token_validator_factory_->CreateTokenValidator(
      kLocalJid, kRemoteJid);

  SetResponse(net::URLRequestTestJob::test_headers(),
              CreateResponse(token_validator_->token_scope()));

  token_validator_->ValidateThirdPartyToken(
      kToken, base::Bind(&TokenValidatorFactoryImplTest::SuccessCallback,
                             base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, BadToken) {
  token_validator_ = token_validator_factory_->CreateTokenValidator(
      kLocalJid, kRemoteJid);

  SetResponse(net::URLRequestTestJob::test_error_headers(), std::string());

  token_validator_->ValidateThirdPartyToken(
      kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback,
                             base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, BadScope) {
  token_validator_ = token_validator_factory_->CreateTokenValidator(
      kLocalJid, kRemoteJid);

  SetResponse(net::URLRequestTestJob::test_headers(),
              CreateResponse(kBadScope));

  token_validator_->ValidateThirdPartyToken(
      kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback,
                         base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, DeleteOnFailure) {
  token_validator_ = token_validator_factory_->CreateTokenValidator(
      kLocalJid, kRemoteJid);

  SetResponse(net::URLRequestTestJob::test_error_headers(), std::string());

  token_validator_->ValidateThirdPartyToken(
      kToken, base::Bind(
          &TokenValidatorFactoryImplTest::DeleteOnFailureCallback,
          base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, DeleteOnStartError) {
  token_validator_ =
      token_validator_factory_->CreateTokenValidator(kLocalJid, kRemoteJid);

  SetErrorResponse(net::URLRequestFailedJob::START, net::ERR_FAILED);

  token_validator_->ValidateThirdPartyToken(
      kToken,
      base::Bind(&TokenValidatorFactoryImplTest::DeleteOnFailureCallback,
                 base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, DeleteOnSyncReadError) {
  token_validator_ =
      token_validator_factory_->CreateTokenValidator(kLocalJid, kRemoteJid);

  SetErrorResponse(net::URLRequestFailedJob::READ_SYNC, net::ERR_FAILED);

  token_validator_->ValidateThirdPartyToken(
      kToken,
      base::Bind(&TokenValidatorFactoryImplTest::DeleteOnFailureCallback,
                 base::Unretained(this)));
  run_loop_.Run();
}

TEST_F(TokenValidatorFactoryImplTest, DeleteOnAsyncReadError) {
  token_validator_ =
      token_validator_factory_->CreateTokenValidator(kLocalJid, kRemoteJid);

  SetErrorResponse(net::URLRequestFailedJob::READ_ASYNC, net::ERR_FAILED);

  token_validator_->ValidateThirdPartyToken(
      kToken,
      base::Bind(&TokenValidatorFactoryImplTest::DeleteOnFailureCallback,
                 base::Unretained(this)));
  run_loop_.Run();
}

}  // namespace remoting
