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"
110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/http/http_status_code.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_job_factory.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_status.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_test_job.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_test_util.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/base/rsa_key_pair.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/base/test_rsa_key_pair.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/token_validator_factory_impl.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTokenUrl[] = "https://example.com/token";
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTokenValidationUrl[] = "https://example.com/validate";
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTokenValidationCertIssuer[] = "";
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kLocalJid[] = "user@example.com/local";
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kRemoteJid[] = "user@example.com/remote";
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kToken[] = "xyz123456";
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kSharedSecret[] = "abcdefgh";
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Bad scope: no nonce element.
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kBadScope[] =
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "client:user@example.com/local host:user@example.com/remote";
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeProtocolHandler(const std::string& headers, const std::string& response)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : headers_(headers),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        response_(response) {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual net::URLRequestJob* MaybeCreateJob(
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::URLRequest* request, net::NetworkDelegate* network_delegate) const
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OVERRIDE {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return new net::URLRequestTestJob(
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        request, network_delegate, headers_, response_, true);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string headers_;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string response_;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SetResponseURLRequestContext: public net::TestURLRequestContext {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetResponse(const std::string& headers, const std::string& response) {
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::URLRequestJobFactoryImpl* factory =
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new net::URLRequestJobFactoryImpl();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    factory->SetProtocolHandler(
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "https", new FakeProtocolHandler(headers, response));
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_storage_.set_job_factory(factory);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace remoting {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TokenValidatorFactoryImplTest : public testing::Test {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TokenValidatorFactoryImplTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SuccessCallback(const std::string& shared_secret) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(shared_secret.empty());
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.Quit();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void FailureCallback(const std::string& shared_secret) {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(shared_secret.empty());
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.Quit();
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DeleteOnFailureCallback(const std::string& shared_secret) {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(shared_secret.empty());
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    token_validator_.reset();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.Quit();
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    key_pair_ = RsaKeyPair::FromString(kTestRsaKeyPair);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<net::TestURLRequestContext> context(
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new SetResponseURLRequestContext());
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    request_context_getter_ = new net::TestURLRequestContextGetter(
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        message_loop_.message_loop_proxy(), context.Pass());
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ThirdPartyAuthConfig config;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    config.token_url = GURL(kTokenUrl);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    config.token_validation_url = GURL(kTokenValidationUrl);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    config.token_validation_cert_issuer = kTokenValidationCertIssuer;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    token_validator_factory_.reset(new TokenValidatorFactoryImpl(
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        config, key_pair_, request_context_getter_));
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static std::string CreateResponse(const std::string& scope) {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue response_dict;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_dict.SetString("access_token", kSharedSecret);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_dict.SetString("token_type", "shared_secret");
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_dict.SetString("scope", scope);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string response;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::JSONWriter::Write(&response_dict, &response);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static std::string CreateErrorResponse(const std::string& error) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue response_dict;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_dict.SetString("error", error);
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string response;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::JSONWriter::Write(&response_dict, &response);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetResponse(const std::string& headers, const std::string& response) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetResponseURLRequestContext* context =
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<SetResponseURLRequestContext*>(
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            request_context_getter_->GetURLRequestContext());
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context->SetResponse(headers, response);
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::MessageLoop message_loop_;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<RsaKeyPair> key_pair_;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<TokenValidatorFactoryImpl> token_validator_factory_;
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<protocol::TokenValidator> token_validator_;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, Success) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_ = token_validator_factory_->CreateTokenValidator(
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kLocalJid, kRemoteJid);
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResponse(net::URLRequestTestJob::test_headers(),
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              CreateResponse(token_validator_->token_scope()));
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_->ValidateThirdPartyToken(
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kToken, base::Bind(&TokenValidatorFactoryImplTest::SuccessCallback,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::Unretained(this)));
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.Run();
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, BadToken) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_ = token_validator_factory_->CreateTokenValidator(
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kLocalJid, kRemoteJid);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResponse(net::URLRequestTestJob::test_error_headers(), std::string());
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_->ValidateThirdPartyToken(
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback,
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::Unretained(this)));
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.Run();
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, BadScope) {
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_ = token_validator_factory_->CreateTokenValidator(
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kLocalJid, kRemoteJid);
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResponse(net::URLRequestTestJob::test_headers(),
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              CreateResponse(kBadScope));
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_->ValidateThirdPartyToken(
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kToken, base::Bind(&TokenValidatorFactoryImplTest::FailureCallback,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         base::Unretained(this)));
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.Run();
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TokenValidatorFactoryImplTest, DeleteOnFailure) {
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_ = token_validator_factory_->CreateTokenValidator(
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kLocalJid, kRemoteJid);
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetResponse(net::URLRequestTestJob::test_error_headers(), std::string());
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  token_validator_->ValidateThirdPartyToken(
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kToken, base::Bind(
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          &TokenValidatorFactoryImplTest::DeleteOnFailureCallback,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::Unretained(this)));
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop_.Run();
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace remoting
190