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