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 "base/json/json_reader.h"
8 #include "base/pickle.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/api/sockets/sockets_manifest_permission.h"
11 #include "extensions/common/extension_messages.h"
12 #include "extensions/common/manifest_constants.h"
13 #include "ipc/ipc_message.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 using content::SocketPermissionRequest
;
18 namespace extensions
{
22 const char kUdpBindPermission
[]=
23 "{ \"udp\": { \"bind\": [\"127.0.0.1:3007\", \"a.com:80\"] } }";
25 const char kUdpSendPermission
[]=
26 "{ \"udp\": { \"send\": [\"\", \"a.com:80\"] } }";
28 const char kTcpConnectPermission
[]=
29 "{ \"tcp\": { \"connect\": [\"127.0.0.1:80\", \"a.com:80\"] } }";
31 const char kTcpServerListenPermission
[]=
32 "{ \"tcpServer\": { \"listen\": [\"127.0.0.1:80\", \"a.com:80\"] } }";
34 static void AssertEmptyPermission(const SocketsManifestPermission
* permission
) {
35 EXPECT_TRUE(permission
);
36 EXPECT_EQ(std::string(extensions::manifest_keys::kSockets
), permission
->id());
37 EXPECT_EQ(permission
->id(), permission
->name());
38 EXPECT_FALSE(permission
->HasMessages());
39 EXPECT_EQ(0u, permission
->entries().size());
42 static scoped_ptr
<base::Value
> ParsePermissionJSON(const std::string
& json
) {
43 scoped_ptr
<base::Value
> result(base::JSONReader::Read(json
));
44 EXPECT_TRUE(result
) << "Invalid JSON string: " << json
;
48 static scoped_ptr
<SocketsManifestPermission
> PermissionFromValue(
49 const base::Value
& value
) {
50 base::string16 error16
;
51 scoped_ptr
<SocketsManifestPermission
> permission(
52 SocketsManifestPermission::FromValue(value
, &error16
));
53 EXPECT_TRUE(permission
)
54 << "Error parsing Value into permission: " << error16
;
55 return permission
.Pass();
58 static scoped_ptr
<SocketsManifestPermission
> PermissionFromJSON(
59 const std::string
& json
) {
60 scoped_ptr
<base::Value
> value(ParsePermissionJSON(json
));
61 return PermissionFromValue(*value
);
64 struct CheckFormatEntry
{
65 CheckFormatEntry(SocketPermissionRequest::OperationType operation_type
,
66 std::string host_pattern
)
67 : operation_type(operation_type
),
68 host_pattern(host_pattern
) {
71 // operators <, == are needed by container std::set and algorithms
72 // std::set_includes and std::set_differences.
73 bool operator<(const CheckFormatEntry
& rhs
) const {
74 if (operation_type
== rhs
.operation_type
)
75 return host_pattern
< rhs
.host_pattern
;
77 return operation_type
< rhs
.operation_type
;
80 bool operator==(const CheckFormatEntry
& rhs
) const {
81 return operation_type
== rhs
.operation_type
&&
82 host_pattern
== rhs
.host_pattern
;
85 SocketPermissionRequest::OperationType operation_type
;
86 std::string host_pattern
;
89 static testing::AssertionResult
CheckFormat(
90 std::multiset
<CheckFormatEntry
> permissions
,
91 const std::string
& json
) {
92 scoped_ptr
<SocketsManifestPermission
> permission(PermissionFromJSON(json
));
94 return testing::AssertionFailure() << "Invalid permission " << json
;
96 if (permissions
.size() != permission
->entries().size()) {
97 return testing::AssertionFailure()
98 << "Incorrect # of entries in json: " << json
;
101 // Note: We use multiset because SocketsManifestPermission does not have to
102 // store entries in the order found in the json message.
103 std::multiset
<CheckFormatEntry
> parsed_permissions
;
104 for (SocketsManifestPermission::SocketPermissionEntrySet::const_iterator
105 it
= permission
->entries().begin(); it
!= permission
->entries().end();
107 parsed_permissions
.insert(
108 CheckFormatEntry(it
->pattern().type
, it
->GetHostPatternAsString()));
111 if (!std::equal(permissions
.begin(), permissions
.end(),
112 parsed_permissions
.begin())) {
113 return testing::AssertionFailure() << "Incorrect socket operations.";
115 return testing::AssertionSuccess();
118 static testing::AssertionResult
CheckFormat(const std::string
& json
) {
119 return CheckFormat(std::multiset
<CheckFormatEntry
>(), json
);
122 static testing::AssertionResult
CheckFormat(
123 const std::string
& json
,
124 const CheckFormatEntry
& op1
) {
125 CheckFormatEntry entries
[] = {
128 return CheckFormat(std::multiset
<CheckFormatEntry
>(
129 entries
, entries
+ arraysize(entries
)), json
);
132 static testing::AssertionResult
CheckFormat(
133 const std::string
& json
,
134 const CheckFormatEntry
& op1
,
135 const CheckFormatEntry
& op2
) {
136 CheckFormatEntry entries
[] = {
139 return CheckFormat(std::multiset
<CheckFormatEntry
>(
140 entries
, entries
+ arraysize(entries
)), json
);
143 static testing::AssertionResult
CheckFormat(
144 const std::string
& json
,
145 const CheckFormatEntry
& op1
,
146 const CheckFormatEntry
& op2
,
147 const CheckFormatEntry
& op3
,
148 const CheckFormatEntry
& op4
,
149 const CheckFormatEntry
& op5
,
150 const CheckFormatEntry
& op6
,
151 const CheckFormatEntry
& op7
,
152 const CheckFormatEntry
& op8
,
153 const CheckFormatEntry
& op9
) {
154 CheckFormatEntry entries
[] = {
155 op1
, op2
, op3
, op4
, op5
, op6
, op7
, op8
, op9
157 return CheckFormat(std::multiset
<CheckFormatEntry
>(
158 entries
, entries
+ arraysize(entries
)), json
);
163 TEST(SocketsManifestPermissionTest
, Empty
) {
165 scoped_ptr
<SocketsManifestPermission
> permission(
166 new SocketsManifestPermission());
167 AssertEmptyPermission(permission
.get());
170 scoped_ptr
<SocketsManifestPermission
> clone(
171 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
172 AssertEmptyPermission(clone
.get());
174 EXPECT_TRUE(permission
->Equal(clone
.get()));
176 // ToValue()/FromValue()
177 scoped_ptr
<const base::Value
> value(permission
->ToValue());
178 EXPECT_TRUE(value
.get());
180 scoped_ptr
<SocketsManifestPermission
> permission2(
181 new SocketsManifestPermission());
182 EXPECT_TRUE(permission2
->FromValue(value
.get()));
183 AssertEmptyPermission(permission2
.get());
185 // Union/Diff/Intersection
186 scoped_ptr
<SocketsManifestPermission
> diff_perm(
187 static_cast<SocketsManifestPermission
*>(permission
->Diff(clone
.get())));
188 AssertEmptyPermission(diff_perm
.get());
190 scoped_ptr
<SocketsManifestPermission
> union_perm(
191 static_cast<SocketsManifestPermission
*>(permission
->Union(clone
.get())));
192 AssertEmptyPermission(union_perm
.get());
194 scoped_ptr
<SocketsManifestPermission
> intersect_perm(
195 static_cast<SocketsManifestPermission
*>(
196 permission
->Intersect(clone
.get())));
197 AssertEmptyPermission(intersect_perm
.get());
200 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
201 new SocketsManifestPermission());
202 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
203 new SocketsManifestPermission());
207 PickleIterator
iter(m
);
208 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
209 AssertEmptyPermission(ipc_perm2
.get());
212 TEST(SocketsManifestPermissionTest
, JSONFormats
) {
213 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":\"\"}}",
214 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
215 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[]}}"));
216 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[\"\"]}}",
217 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
218 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[\"a:80\", \"b:10\"]}}",
219 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
220 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10")));
222 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":\"\"}}",
223 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
224 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[]}}"));
225 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[\"\"]}}",
226 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
227 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[\"a:80\", \"b:10\"]}}",
228 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
229 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10")));
231 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":\"\"}}",
232 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
233 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[]}}"));
234 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[\"\"]}}",
235 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
236 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[\"\", \"\"]}}",
237 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
239 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":\"\"}}",
240 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
241 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[]}}"));
242 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[\"\"]}}",
243 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
244 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}}",
245 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
246 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10")));
248 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":\"\"}}",
249 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
250 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[]}}"));
251 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[\"\"]}}",
252 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
253 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}}",
254 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
255 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
257 EXPECT_TRUE(CheckFormat(
260 "\"send\":[\"a:80\", \"b:10\"],"
261 "\"bind\":[\"a:80\", \"b:10\"],"
262 "\"multicastMembership\":\"\""
264 "\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]},"
265 "\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}"
267 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
268 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10"),
269 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
270 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10"),
271 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, ""),
272 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
273 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10"),
274 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
275 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
279 TEST(SocketsManifestPermissionTest
, FromToValue
) {
280 scoped_ptr
<base::Value
> udp_send(ParsePermissionJSON(kUdpBindPermission
));
281 scoped_ptr
<base::Value
> udp_bind(ParsePermissionJSON(kUdpSendPermission
));
282 scoped_ptr
<base::Value
> tcp_connect(
283 ParsePermissionJSON(kTcpConnectPermission
));
284 scoped_ptr
<base::Value
> tcp_server_listen(
285 ParsePermissionJSON(kTcpServerListenPermission
));
288 scoped_ptr
<SocketsManifestPermission
> permission1(
289 new SocketsManifestPermission());
290 EXPECT_TRUE(permission1
->FromValue(udp_send
.get()));
291 EXPECT_EQ(2u, permission1
->entries().size());
293 scoped_ptr
<SocketsManifestPermission
> permission2(
294 new SocketsManifestPermission());
295 EXPECT_TRUE(permission2
->FromValue(udp_bind
.get()));
296 EXPECT_EQ(2u, permission2
->entries().size());
298 scoped_ptr
<SocketsManifestPermission
> permission3(
299 new SocketsManifestPermission());
300 EXPECT_TRUE(permission3
->FromValue(tcp_connect
.get()));
301 EXPECT_EQ(2u, permission3
->entries().size());
303 scoped_ptr
<SocketsManifestPermission
> permission4(
304 new SocketsManifestPermission());
305 EXPECT_TRUE(permission4
->FromValue(tcp_server_listen
.get()));
306 EXPECT_EQ(2u, permission4
->entries().size());
309 scoped_ptr
<base::Value
> value1
= permission1
->ToValue();
311 scoped_ptr
<SocketsManifestPermission
> permission1_1(
312 new SocketsManifestPermission());
313 EXPECT_TRUE(permission1_1
->FromValue(value1
.get()));
314 EXPECT_TRUE(permission1
->Equal(permission1_1
.get()));
316 scoped_ptr
<base::Value
> value2
= permission2
->ToValue();
318 scoped_ptr
<SocketsManifestPermission
> permission2_1(
319 new SocketsManifestPermission());
320 EXPECT_TRUE(permission2_1
->FromValue(value2
.get()));
321 EXPECT_TRUE(permission2
->Equal(permission2_1
.get()));
323 scoped_ptr
<base::Value
> value3
= permission3
->ToValue();
325 scoped_ptr
<SocketsManifestPermission
> permission3_1(
326 new SocketsManifestPermission());
327 EXPECT_TRUE(permission3_1
->FromValue(value3
.get()));
328 EXPECT_TRUE(permission3
->Equal(permission3_1
.get()));
330 scoped_ptr
<base::Value
> value4
= permission4
->ToValue();
332 scoped_ptr
<SocketsManifestPermission
> permission4_1(
333 new SocketsManifestPermission());
334 EXPECT_TRUE(permission4_1
->FromValue(value4
.get()));
335 EXPECT_TRUE(permission4
->Equal(permission4_1
.get()));
338 TEST(SocketsManifestPermissionTest
, SetOperations
) {
339 scoped_ptr
<SocketsManifestPermission
> permission1(
340 PermissionFromJSON(kUdpBindPermission
));
341 scoped_ptr
<SocketsManifestPermission
> permission2(
342 PermissionFromJSON(kUdpSendPermission
));
343 scoped_ptr
<SocketsManifestPermission
> permission3(
344 PermissionFromJSON(kTcpConnectPermission
));
345 scoped_ptr
<SocketsManifestPermission
> permission4(
346 PermissionFromJSON(kTcpServerListenPermission
));
349 scoped_ptr
<SocketsManifestPermission
> union_perm(
350 static_cast<SocketsManifestPermission
*>(
351 permission1
->Union(permission2
.get())));
352 EXPECT_TRUE(union_perm
);
353 EXPECT_EQ(4u, union_perm
->entries().size());
355 EXPECT_TRUE(union_perm
->Contains(permission1
.get()));
356 EXPECT_TRUE(union_perm
->Contains(permission2
.get()));
357 EXPECT_FALSE(union_perm
->Contains(permission3
.get()));
358 EXPECT_FALSE(union_perm
->Contains(permission4
.get()));
361 scoped_ptr
<SocketsManifestPermission
> diff_perm1(
362 static_cast<SocketsManifestPermission
*>(
363 permission1
->Diff(permission2
.get())));
364 EXPECT_TRUE(diff_perm1
);
365 EXPECT_EQ(2u, diff_perm1
->entries().size());
367 EXPECT_TRUE(permission1
->Equal(diff_perm1
.get()));
368 EXPECT_TRUE(diff_perm1
->Equal(permission1
.get()));
370 scoped_ptr
<SocketsManifestPermission
> diff_perm2(
371 static_cast<SocketsManifestPermission
*>(
372 permission1
->Diff(union_perm
.get())));
373 EXPECT_TRUE(diff_perm2
);
374 AssertEmptyPermission(diff_perm2
.get());
377 scoped_ptr
<SocketsManifestPermission
> intersect_perm1(
378 static_cast<SocketsManifestPermission
*>(
379 union_perm
->Intersect(permission1
.get())));
380 EXPECT_TRUE(intersect_perm1
);
381 EXPECT_EQ(2u, intersect_perm1
->entries().size());
383 EXPECT_TRUE(permission1
->Equal(intersect_perm1
.get()));
384 EXPECT_TRUE(intersect_perm1
->Equal(permission1
.get()));
387 TEST(SocketsManifestPermissionTest
, IPC
) {
388 scoped_ptr
<SocketsManifestPermission
> permission(
389 PermissionFromJSON(kUdpBindPermission
));
391 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
392 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
393 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
394 new SocketsManifestPermission());
398 PickleIterator
iter(m
);
399 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
400 EXPECT_TRUE(permission
->Equal(ipc_perm2
.get()));
403 } // namespace extensions