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 static const char FAKE_ORIGIN[] = "http://fake.com";
     21 static const char FAKE_IDENTITY_NAME[] = "fake identity";
     22 static const char FAKE_COMMON_NAME[] = "fake common name";
     23 static const char FAKE_CERTIFICATE[] = "fake cert";
     24 static const char FAKE_PRIVATE_KEY[] = "fake private key";
     25 static const int FAKE_ERROR = 100;
     26 static const int FAKE_RENDERER_ID = 10;
     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,
     77                                  bool* message_was_ok) OVERRIDE {
     78     return WebRTCIdentityServiceHost::OnMessageReceived(message,
     79                                                         message_was_ok);
     80   }
     81 
     82   IPC::Message GetLastMessage() { return messages_.back(); }
     83 
     84   int GetNumberOfMessages() { return messages_.size(); }
     85 
     86   void ClearMessages() { messages_.clear(); }
     87 
     88  private:
     89   virtual ~WebRTCIdentityServiceHostForTest() {
     90     ChildProcessSecurityPolicyImpl* policy =
     91         ChildProcessSecurityPolicyImpl::GetInstance();
     92     policy->Remove(FAKE_RENDERER_ID);
     93   }
     94 
     95   std::deque<IPC::Message> messages_;
     96 };
     97 
     98 class WebRTCIdentityServiceHostTest : public ::testing::Test {
     99  public:
    100   WebRTCIdentityServiceHostTest()
    101       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
    102         store_(new MockWebRTCIdentityStore()),
    103         host_(new WebRTCIdentityServiceHostForTest(store_.get())) {}
    104 
    105   void SendRequestToHost() {
    106     bool ok;
    107     host_->OnMessageReceived(
    108         WebRTCIdentityMsg_RequestIdentity(
    109             GURL(FAKE_ORIGIN), FAKE_IDENTITY_NAME, FAKE_COMMON_NAME),
    110         &ok);
    111     ASSERT_TRUE(ok);
    112   }
    113 
    114   void SendCancelRequestToHost() {
    115     bool ok;
    116     host_->OnMessageReceived(WebRTCIdentityMsg_CancelRequest(), &ok);
    117     ASSERT_TRUE(ok);
    118   }
    119 
    120   void VerifyRequestFailedMessage(int error) {
    121     EXPECT_EQ(1, host_->GetNumberOfMessages());
    122     IPC::Message ipc = host_->GetLastMessage();
    123     EXPECT_EQ(ipc.type(), WebRTCIdentityHostMsg_RequestFailed::ID);
    124 
    125     Tuple1<int> error_in_message;
    126     WebRTCIdentityHostMsg_RequestFailed::Read(&ipc, &error_in_message);
    127     EXPECT_EQ(error, error_in_message.a);
    128   }
    129 
    130   void VerifyIdentityReadyMessage(const std::string& cert,
    131                                   const std::string& key) {
    132     EXPECT_EQ(1, host_->GetNumberOfMessages());
    133     IPC::Message ipc = host_->GetLastMessage();
    134     EXPECT_EQ(ipc.type(), WebRTCIdentityHostMsg_IdentityReady::ID);
    135 
    136     Tuple2<std::string, std::string> identity_in_message;
    137     WebRTCIdentityHostMsg_IdentityReady::Read(&ipc, &identity_in_message);
    138     EXPECT_EQ(cert, identity_in_message.a);
    139     EXPECT_EQ(key, identity_in_message.b);
    140   }
    141 
    142  protected:
    143   TestBrowserThreadBundle browser_thread_bundle_;
    144   scoped_refptr<MockWebRTCIdentityStore> store_;
    145   scoped_refptr<WebRTCIdentityServiceHostForTest> host_;
    146 };
    147 
    148 }  // namespace
    149 
    150 TEST_F(WebRTCIdentityServiceHostTest, TestSendAndCancelRequest) {
    151   SendRequestToHost();
    152   EXPECT_TRUE(store_->HasPendingRequest());
    153   SendCancelRequestToHost();
    154   EXPECT_FALSE(store_->HasPendingRequest());
    155 }
    156 
    157 TEST_F(WebRTCIdentityServiceHostTest, TestOnlyOneRequestAllowed) {
    158   SendRequestToHost();
    159   EXPECT_TRUE(store_->HasPendingRequest());
    160   EXPECT_EQ(0, host_->GetNumberOfMessages());
    161   SendRequestToHost();
    162 
    163   VerifyRequestFailedMessage(net::ERR_INSUFFICIENT_RESOURCES);
    164 }
    165 
    166 TEST_F(WebRTCIdentityServiceHostTest, TestOnIdentityReady) {
    167   SendRequestToHost();
    168   store_->RunCompletionCallback(net::OK, FAKE_CERTIFICATE, FAKE_PRIVATE_KEY);
    169   VerifyIdentityReadyMessage(FAKE_CERTIFICATE, FAKE_PRIVATE_KEY);
    170 }
    171 
    172 TEST_F(WebRTCIdentityServiceHostTest, TestOnRequestFailed) {
    173   SendRequestToHost();
    174   store_->RunCompletionCallback(net::ERR_KEY_GENERATION_FAILED, "", "");
    175   VerifyRequestFailedMessage(net::ERR_KEY_GENERATION_FAILED);
    176 }
    177 
    178 TEST_F(WebRTCIdentityServiceHostTest, TestOriginAccessDenied) {
    179   ChildProcessSecurityPolicyImpl* policy =
    180       ChildProcessSecurityPolicyImpl::GetInstance();
    181   policy->Remove(FAKE_RENDERER_ID);
    182 
    183   SendRequestToHost();
    184   VerifyRequestFailedMessage(net::ERR_ACCESS_DENIED);
    185 }
    186 
    187 }  // namespace content
    188