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