Home | History | Annotate | Download | only in media
      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 #include <deque>
      6 
      7 #include "content/browser/child_process_security_policy_impl.h"
      8 #include "content/browser/media/webrtc_identity_store.h"
      9 #include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
     10 #include "content/common/media/webrtc_identity_messages.h"
     11 #include "content/public/test/test_browser_thread_bundle.h"
     12 #include "ipc/ipc_message.h"
     13 #include "net/base/net_errors.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace content {
     17 
     18 namespace {
     19 
     20 const char FAKE_ORIGIN[] = "http://fake.com";
     21 const char FAKE_IDENTITY_NAME[] = "fake identity";
     22 const char FAKE_COMMON_NAME[] = "fake common name";
     23 const char FAKE_CERTIFICATE[] = "fake cert";
     24 const char FAKE_PRIVATE_KEY[] = "fake private key";
     25 const int FAKE_RENDERER_ID = 10;
     26 const int FAKE_SEQUENCE_NUMBER = 1;
     27 
     28 class MockWebRTCIdentityStore : public WebRTCIdentityStore {
     29  public:
     30   MockWebRTCIdentityStore() : WebRTCIdentityStore(base::FilePath(), NULL) {}
     31 
     32   virtual base::Closure RequestIdentity(
     33       const GURL& origin,
     34       const std::string& identity_name,
     35       const std::string& common_name,
     36       const CompletionCallback& callback) OVERRIDE {
     37     EXPECT_TRUE(callback_.is_null());
     38 
     39     callback_ = callback;
     40     return base::Bind(&MockWebRTCIdentityStore::OnCancel,
     41                       base::Unretained(this));
     42   }
     43 
     44   bool HasPendingRequest() const { return !callback_.is_null(); }
     45 
     46   void RunCompletionCallback(int error,
     47                              const std::string& cert,
     48                              const std::string& key) {
     49     callback_.Run(error, cert, key);
     50     callback_.Reset();
     51   }
     52 
     53  private:
     54   virtual ~MockWebRTCIdentityStore() {}
     55 
     56   void OnCancel() { callback_.Reset(); }
     57 
     58   CompletionCallback callback_;
     59 };
     60 
     61 class WebRTCIdentityServiceHostForTest : public WebRTCIdentityServiceHost {
     62  public:
     63   explicit WebRTCIdentityServiceHostForTest(WebRTCIdentityStore* identity_store)
     64       : WebRTCIdentityServiceHost(FAKE_RENDERER_ID, identity_store) {
     65     ChildProcessSecurityPolicyImpl* policy =
     66         ChildProcessSecurityPolicyImpl::GetInstance();
     67     policy->Add(FAKE_RENDERER_ID);
     68   }
     69 
     70   virtual bool Send(IPC::Message* message) OVERRIDE {
     71     messages_.push_back(*message);
     72     delete message;
     73     return true;
     74   }
     75 
     76   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
     77     return WebRTCIdentityServiceHost::OnMessageReceived(message);
     78   }
     79 
     80   IPC::Message GetLastMessage() { return messages_.back(); }
     81 
     82   int GetNumberOfMessages() { return messages_.size(); }
     83 
     84   void ClearMessages() { messages_.clear(); }
     85 
     86  private:
     87   virtual ~WebRTCIdentityServiceHostForTest() {
     88     ChildProcessSecurityPolicyImpl* policy =
     89         ChildProcessSecurityPolicyImpl::GetInstance();
     90     policy->Remove(FAKE_RENDERER_ID);
     91   }
     92 
     93   std::deque<IPC::Message> messages_;
     94 };
     95 
     96 class WebRTCIdentityServiceHostTest : public ::testing::Test {
     97  public:
     98   WebRTCIdentityServiceHostTest()
     99       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
    100         store_(new MockWebRTCIdentityStore()),
    101         host_(new WebRTCIdentityServiceHostForTest(store_.get())) {}
    102 
    103   void SendRequestToHost() {
    104     host_->OnMessageReceived(
    105         WebRTCIdentityMsg_RequestIdentity(FAKE_SEQUENCE_NUMBER,
    106                                           GURL(FAKE_ORIGIN),
    107                                           FAKE_IDENTITY_NAME,
    108                                           FAKE_COMMON_NAME));
    109   }
    110 
    111   void SendCancelRequestToHost() {
    112     host_->OnMessageReceived(WebRTCIdentityMsg_CancelRequest());
    113   }
    114 
    115   void VerifyRequestFailedMessage(int error) {
    116     EXPECT_EQ(1, host_->GetNumberOfMessages());
    117     IPC::Message ipc = host_->GetLastMessage();
    118     EXPECT_EQ(ipc.type(), WebRTCIdentityHostMsg_RequestFailed::ID);
    119 
    120     Tuple2<int, int> error_in_message;
    121     WebRTCIdentityHostMsg_RequestFailed::Read(&ipc, &error_in_message);
    122     EXPECT_EQ(FAKE_SEQUENCE_NUMBER, error_in_message.a);
    123     EXPECT_EQ(error, error_in_message.b);
    124   }
    125 
    126   void VerifyIdentityReadyMessage(const std::string& cert,
    127                                   const std::string& key) {
    128     EXPECT_EQ(1, host_->GetNumberOfMessages());
    129     IPC::Message ipc = host_->GetLastMessage();
    130     EXPECT_EQ(ipc.type(), WebRTCIdentityHostMsg_IdentityReady::ID);
    131 
    132     Tuple3<int, std::string, std::string> identity_in_message;
    133     WebRTCIdentityHostMsg_IdentityReady::Read(&ipc, &identity_in_message);
    134     EXPECT_EQ(FAKE_SEQUENCE_NUMBER, identity_in_message.a);
    135     EXPECT_EQ(cert, identity_in_message.b);
    136     EXPECT_EQ(key, identity_in_message.c);
    137   }
    138 
    139  protected:
    140   TestBrowserThreadBundle browser_thread_bundle_;
    141   scoped_refptr<MockWebRTCIdentityStore> store_;
    142   scoped_refptr<WebRTCIdentityServiceHostForTest> host_;
    143 };
    144 
    145 }  // namespace
    146 
    147 TEST_F(WebRTCIdentityServiceHostTest, TestSendAndCancelRequest) {
    148   SendRequestToHost();
    149   EXPECT_TRUE(store_->HasPendingRequest());
    150   SendCancelRequestToHost();
    151   EXPECT_FALSE(store_->HasPendingRequest());
    152 }
    153 
    154 TEST_F(WebRTCIdentityServiceHostTest, TestOnlyOneRequestAllowed) {
    155   SendRequestToHost();
    156   EXPECT_TRUE(store_->HasPendingRequest());
    157   EXPECT_EQ(0, host_->GetNumberOfMessages());
    158   SendRequestToHost();
    159 
    160   VerifyRequestFailedMessage(net::ERR_INSUFFICIENT_RESOURCES);
    161 }
    162 
    163 TEST_F(WebRTCIdentityServiceHostTest, TestOnIdentityReady) {
    164   SendRequestToHost();
    165   store_->RunCompletionCallback(net::OK, FAKE_CERTIFICATE, FAKE_PRIVATE_KEY);
    166   VerifyIdentityReadyMessage(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY);
    167 }
    168 
    169 TEST_F(WebRTCIdentityServiceHostTest, TestOnRequestFailed) {
    170   SendRequestToHost();
    171   store_->RunCompletionCallback(net::ERR_KEY_GENERATION_FAILED, "", "");
    172   VerifyRequestFailedMessage(net::ERR_KEY_GENERATION_FAILED);
    173 }
    174 
    175 TEST_F(WebRTCIdentityServiceHostTest, TestOriginAccessDenied) {
    176   ChildProcessSecurityPolicyImpl* policy =
    177       ChildProcessSecurityPolicyImpl::GetInstance();
    178   policy->Remove(FAKE_RENDERER_ID);
    179 
    180   SendRequestToHost();
    181   VerifyRequestFailedMessage(net::ERR_ACCESS_DENIED);
    182 }
    183 
    184 // Verifies that we do not crash if we try to cancel a completed request.
    185 TEST_F(WebRTCIdentityServiceHostTest, TestCancelAfterRequestCompleted) {
    186   SendRequestToHost();
    187   store_->RunCompletionCallback(net::OK, FAKE_CERTIFICATE, FAKE_PRIVATE_KEY);
    188   SendCancelRequestToHost();
    189 }
    190 
    191 }  // namespace content
    192