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.
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/mock_resource_context.h"
12 #include "content/public/test/test_browser_thread_bundle.h"
13 #include "content/test/test_content_browser_client.h"
14 #include "ipc/ipc_message.h"
15 #include "net/base/net_errors.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 const char FAKE_URL
[] = "http://fake.com";
23 const char FAKE_FIRST_PARTY_URL
[] = "http://fake.firstparty.com";
24 const char FAKE_IDENTITY_NAME
[] = "fake identity";
25 const char FAKE_COMMON_NAME
[] = "fake common name";
26 const char FAKE_CERTIFICATE
[] = "fake cert";
27 const char FAKE_PRIVATE_KEY
[] = "fake private key";
28 const int FAKE_RENDERER_ID
= 10;
29 const int FAKE_REQUEST_ID
= 1;
31 class WebRTCIdentityServiceHostTestBrowserClient
32 : public TestContentBrowserClient
{
34 WebRTCIdentityServiceHostTestBrowserClient() : allow_cache_(true) {}
36 void set_allow_cache(bool allow
) { allow_cache_
= allow
; }
38 bool AllowWebRTCIdentityCache(const GURL
& url
,
39 const GURL
& first_party_url
,
40 ResourceContext
* context
) override
{
42 first_party_url_
= first_party_url
;
46 GURL
url() const { return url_
; }
47 GURL
first_party_url() const { return first_party_url_
; }
52 GURL first_party_url_
;
55 class MockWebRTCIdentityStore
: public WebRTCIdentityStore
{
57 MockWebRTCIdentityStore()
58 : WebRTCIdentityStore(base::FilePath(), NULL
), enable_cache_(true) {}
60 base::Closure
RequestIdentity(const GURL
& origin
,
61 const std::string
& identity_name
,
62 const std::string
& common_name
,
63 const CompletionCallback
& callback
,
64 bool enable_cache
) override
{
65 EXPECT_TRUE(callback_
.is_null());
68 enable_cache_
= enable_cache
;
69 return base::Bind(&MockWebRTCIdentityStore::OnCancel
,
70 base::Unretained(this));
73 bool HasPendingRequest() const { return !callback_
.is_null(); }
75 void RunCompletionCallback(int error
,
76 const std::string
& cert
,
77 const std::string
& key
) {
78 callback_
.Run(error
, cert
, key
);
82 bool enable_cache() const { return enable_cache_
; }
85 ~MockWebRTCIdentityStore() override
{}
87 void OnCancel() { callback_
.Reset(); }
89 CompletionCallback callback_
;
93 class WebRTCIdentityServiceHostForTest
: public WebRTCIdentityServiceHost
{
95 WebRTCIdentityServiceHostForTest(WebRTCIdentityStore
* identity_store
,
96 ResourceContext
* resource_context
)
97 : WebRTCIdentityServiceHost(FAKE_RENDERER_ID
,
100 ChildProcessSecurityPolicyImpl
* policy
=
101 ChildProcessSecurityPolicyImpl::GetInstance();
102 policy
->Add(FAKE_RENDERER_ID
);
105 bool Send(IPC::Message
* message
) override
{
106 messages_
.push_back(*message
);
111 bool OnMessageReceived(const IPC::Message
& message
) override
{
112 return WebRTCIdentityServiceHost::OnMessageReceived(message
);
115 IPC::Message
GetLastMessage() { return messages_
.back(); }
117 int GetNumberOfMessages() { return messages_
.size(); }
119 void ClearMessages() { messages_
.clear(); }
122 ~WebRTCIdentityServiceHostForTest() override
{
123 ChildProcessSecurityPolicyImpl
* policy
=
124 ChildProcessSecurityPolicyImpl::GetInstance();
125 policy
->Remove(FAKE_RENDERER_ID
);
128 std::deque
<IPC::Message
> messages_
;
131 class WebRTCIdentityServiceHostTest
: public ::testing::Test
{
133 WebRTCIdentityServiceHostTest()
134 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
),
135 mock_resource_context_(new MockResourceContext()),
136 store_(new MockWebRTCIdentityStore()),
137 host_(new WebRTCIdentityServiceHostForTest(
139 mock_resource_context_
.get())) {}
141 void SendRequestToHost() {
142 WebRTCIdentityMsg_RequestIdentity_Params params
;
143 params
.request_id
= FAKE_REQUEST_ID
;
144 params
.url
= GURL(FAKE_URL
);
145 params
.first_party_for_cookies
= GURL(FAKE_FIRST_PARTY_URL
);
146 params
.identity_name
= FAKE_IDENTITY_NAME
;
147 params
.common_name
= FAKE_COMMON_NAME
;
148 host_
->OnMessageReceived(WebRTCIdentityMsg_RequestIdentity(params
));
151 void SendCancelRequestToHost() {
152 host_
->OnMessageReceived(WebRTCIdentityMsg_CancelRequest());
155 void VerifyRequestFailedMessage(int error
) {
156 EXPECT_EQ(1, host_
->GetNumberOfMessages());
157 IPC::Message ipc
= host_
->GetLastMessage();
158 EXPECT_EQ(ipc
.type(), WebRTCIdentityHostMsg_RequestFailed::ID
);
160 base::Tuple
<int, int> error_in_message
;
161 WebRTCIdentityHostMsg_RequestFailed::Read(&ipc
, &error_in_message
);
162 EXPECT_EQ(FAKE_REQUEST_ID
, base::get
<0>(error_in_message
));
163 EXPECT_EQ(error
, base::get
<1>(error_in_message
));
166 void VerifyIdentityReadyMessage(const std::string
& cert
,
167 const std::string
& key
) {
168 EXPECT_EQ(1, host_
->GetNumberOfMessages());
169 IPC::Message ipc
= host_
->GetLastMessage();
170 EXPECT_EQ(ipc
.type(), WebRTCIdentityHostMsg_IdentityReady::ID
);
172 base::Tuple
<int, std::string
, std::string
> identity_in_message
;
173 WebRTCIdentityHostMsg_IdentityReady::Read(&ipc
, &identity_in_message
);
174 EXPECT_EQ(FAKE_REQUEST_ID
, base::get
<0>(identity_in_message
));
175 EXPECT_EQ(cert
, base::get
<1>(identity_in_message
));
176 EXPECT_EQ(key
, base::get
<2>(identity_in_message
));
180 TestBrowserThreadBundle browser_thread_bundle_
;
181 scoped_ptr
<MockResourceContext
> mock_resource_context_
;
182 scoped_refptr
<MockWebRTCIdentityStore
> store_
;
183 scoped_refptr
<WebRTCIdentityServiceHostForTest
> host_
;
188 TEST_F(WebRTCIdentityServiceHostTest
, TestCacheDisabled
) {
189 WebRTCIdentityServiceHostTestBrowserClient test_client
;
190 test_client
.set_allow_cache(false);
191 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&test_client
);
194 EXPECT_TRUE(store_
->HasPendingRequest());
195 EXPECT_FALSE(store_
->enable_cache());
196 EXPECT_EQ(GURL(FAKE_URL
), test_client
.url());
197 EXPECT_EQ(GURL(FAKE_FIRST_PARTY_URL
), test_client
.first_party_url());
199 // Restore the original content browser client.
200 SetBrowserClientForTesting(old_client
);
203 TEST_F(WebRTCIdentityServiceHostTest
, TestSendAndCancelRequest
) {
205 EXPECT_TRUE(store_
->HasPendingRequest());
206 SendCancelRequestToHost();
207 EXPECT_FALSE(store_
->HasPendingRequest());
210 TEST_F(WebRTCIdentityServiceHostTest
, TestOnlyOneRequestAllowed
) {
212 EXPECT_TRUE(store_
->HasPendingRequest());
213 EXPECT_EQ(0, host_
->GetNumberOfMessages());
216 VerifyRequestFailedMessage(net::ERR_INSUFFICIENT_RESOURCES
);
219 TEST_F(WebRTCIdentityServiceHostTest
, TestOnIdentityReady
) {
221 store_
->RunCompletionCallback(net::OK
, FAKE_CERTIFICATE
, FAKE_PRIVATE_KEY
);
222 VerifyIdentityReadyMessage(FAKE_CERTIFICATE
, FAKE_PRIVATE_KEY
);
225 TEST_F(WebRTCIdentityServiceHostTest
, TestOnRequestFailed
) {
227 store_
->RunCompletionCallback(net::ERR_KEY_GENERATION_FAILED
, "", "");
228 VerifyRequestFailedMessage(net::ERR_KEY_GENERATION_FAILED
);
231 TEST_F(WebRTCIdentityServiceHostTest
, TestOriginAccessDenied
) {
232 ChildProcessSecurityPolicyImpl
* policy
=
233 ChildProcessSecurityPolicyImpl::GetInstance();
234 policy
->Remove(FAKE_RENDERER_ID
);
237 VerifyRequestFailedMessage(net::ERR_ACCESS_DENIED
);
240 // Verifies that we do not crash if we try to cancel a completed request.
241 TEST_F(WebRTCIdentityServiceHostTest
, TestCancelAfterRequestCompleted
) {
243 store_
->RunCompletionCallback(net::OK
, FAKE_CERTIFICATE
, FAKE_PRIVATE_KEY
);
244 SendCancelRequestToHost();
247 } // namespace content