1 // Copyright 2014 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 "extensions/common/api/sockets/sockets_manifest_permission.h"
11 #include "extensions/common/manifest_constants.h"
12 #include "ipc/ipc_message.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 using content::SocketPermissionRequest
;
17 namespace extensions
{
21 const char kUdpBindPermission
[] =
22 "{ \"udp\": { \"bind\": [\"127.0.0.1:3007\", \"a.com:80\"] } }";
24 const char kUdpSendPermission
[] =
25 "{ \"udp\": { \"send\": [\"\", \"a.com:80\"] } }";
27 const char kTcpConnectPermission
[] =
28 "{ \"tcp\": { \"connect\": [\"127.0.0.1:80\", \"a.com:80\"] } }";
30 const char kTcpServerListenPermission
[] =
31 "{ \"tcpServer\": { \"listen\": [\"127.0.0.1:80\", \"a.com:80\"] } }";
33 static void AssertEmptyPermission(const SocketsManifestPermission
* permission
) {
34 EXPECT_TRUE(permission
);
35 EXPECT_EQ(std::string(extensions::manifest_keys::kSockets
), permission
->id());
36 EXPECT_EQ(permission
->id(), permission
->name());
37 EXPECT_FALSE(permission
->HasMessages());
38 EXPECT_EQ(0u, permission
->entries().size());
41 static scoped_ptr
<base::Value
> ParsePermissionJSON(const std::string
& json
) {
42 scoped_ptr
<base::Value
> result(base::JSONReader::Read(json
));
43 EXPECT_TRUE(result
) << "Invalid JSON string: " << json
;
47 static scoped_ptr
<SocketsManifestPermission
> PermissionFromValue(
48 const base::Value
& value
) {
49 base::string16 error16
;
50 scoped_ptr
<SocketsManifestPermission
> permission(
51 SocketsManifestPermission::FromValue(value
, &error16
));
52 EXPECT_TRUE(permission
) << "Error parsing Value into permission: " << error16
;
53 return permission
.Pass();
56 static scoped_ptr
<SocketsManifestPermission
> PermissionFromJSON(
57 const std::string
& json
) {
58 scoped_ptr
<base::Value
> value(ParsePermissionJSON(json
));
59 return PermissionFromValue(*value
);
62 struct CheckFormatEntry
{
63 CheckFormatEntry(SocketPermissionRequest::OperationType operation_type
,
64 std::string host_pattern
)
65 : operation_type(operation_type
), host_pattern(host_pattern
) {}
67 // operators <, == are needed by container std::set and algorithms
68 // std::set_includes and std::set_differences.
69 bool operator<(const CheckFormatEntry
& rhs
) const {
70 if (operation_type
== rhs
.operation_type
)
71 return host_pattern
< rhs
.host_pattern
;
73 return operation_type
< rhs
.operation_type
;
76 bool operator==(const CheckFormatEntry
& rhs
) const {
77 return operation_type
== rhs
.operation_type
&&
78 host_pattern
== rhs
.host_pattern
;
81 SocketPermissionRequest::OperationType operation_type
;
82 std::string host_pattern
;
85 static testing::AssertionResult
CheckFormat(
86 std::multiset
<CheckFormatEntry
> permissions
,
87 const std::string
& json
) {
88 scoped_ptr
<SocketsManifestPermission
> permission(PermissionFromJSON(json
));
90 return testing::AssertionFailure() << "Invalid permission " << json
;
92 if (permissions
.size() != permission
->entries().size()) {
93 return testing::AssertionFailure()
94 << "Incorrect # of entries in json: " << json
;
97 // Note: We use multiset because SocketsManifestPermission does not have to
98 // store entries in the order found in the json message.
99 std::multiset
<CheckFormatEntry
> parsed_permissions
;
100 for (SocketsManifestPermission::SocketPermissionEntrySet::const_iterator it
=
101 permission
->entries().begin();
102 it
!= permission
->entries().end();
104 parsed_permissions
.insert(
105 CheckFormatEntry(it
->pattern().type
, it
->GetHostPatternAsString()));
109 permissions
.begin(), permissions
.end(), parsed_permissions
.begin())) {
110 return testing::AssertionFailure() << "Incorrect socket operations.";
112 return testing::AssertionSuccess();
115 static testing::AssertionResult
CheckFormat(const std::string
& json
) {
116 return CheckFormat(std::multiset
<CheckFormatEntry
>(), json
);
119 static testing::AssertionResult
CheckFormat(const std::string
& json
,
120 const CheckFormatEntry
& op1
) {
121 CheckFormatEntry entries
[] = {op1
};
123 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
127 static testing::AssertionResult
CheckFormat(const std::string
& json
,
128 const CheckFormatEntry
& op1
,
129 const CheckFormatEntry
& op2
) {
130 CheckFormatEntry entries
[] = {op1
, op2
};
132 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
136 static testing::AssertionResult
CheckFormat(const std::string
& json
,
137 const CheckFormatEntry
& op1
,
138 const CheckFormatEntry
& op2
,
139 const CheckFormatEntry
& op3
,
140 const CheckFormatEntry
& op4
,
141 const CheckFormatEntry
& op5
,
142 const CheckFormatEntry
& op6
,
143 const CheckFormatEntry
& op7
,
144 const CheckFormatEntry
& op8
,
145 const CheckFormatEntry
& op9
) {
146 CheckFormatEntry entries
[] = {op1
, op2
, op3
, op4
, op5
, op6
, op7
, op8
, op9
};
148 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
154 TEST(SocketsManifestPermissionTest
, Empty
) {
156 scoped_ptr
<SocketsManifestPermission
> permission(
157 new SocketsManifestPermission());
158 AssertEmptyPermission(permission
.get());
161 scoped_ptr
<SocketsManifestPermission
> clone(
162 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
163 AssertEmptyPermission(clone
.get());
165 EXPECT_TRUE(permission
->Equal(clone
.get()));
167 // ToValue()/FromValue()
168 scoped_ptr
<const base::Value
> value(permission
->ToValue());
169 EXPECT_TRUE(value
.get());
171 scoped_ptr
<SocketsManifestPermission
> permission2(
172 new SocketsManifestPermission());
173 EXPECT_TRUE(permission2
->FromValue(value
.get()));
174 AssertEmptyPermission(permission2
.get());
176 // Union/Diff/Intersection
177 scoped_ptr
<SocketsManifestPermission
> diff_perm(
178 static_cast<SocketsManifestPermission
*>(permission
->Diff(clone
.get())));
179 AssertEmptyPermission(diff_perm
.get());
181 scoped_ptr
<SocketsManifestPermission
> union_perm(
182 static_cast<SocketsManifestPermission
*>(permission
->Union(clone
.get())));
183 AssertEmptyPermission(union_perm
.get());
185 scoped_ptr
<SocketsManifestPermission
> intersect_perm(
186 static_cast<SocketsManifestPermission
*>(
187 permission
->Intersect(clone
.get())));
188 AssertEmptyPermission(intersect_perm
.get());
191 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
192 new SocketsManifestPermission());
193 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
194 new SocketsManifestPermission());
198 PickleIterator
iter(m
);
199 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
200 AssertEmptyPermission(ipc_perm2
.get());
203 TEST(SocketsManifestPermissionTest
, JSONFormats
) {
204 EXPECT_TRUE(CheckFormat(
205 "{\"udp\":{\"send\":\"\"}}",
206 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
207 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[]}}"));
208 EXPECT_TRUE(CheckFormat(
209 "{\"udp\":{\"send\":[\"\"]}}",
210 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
211 EXPECT_TRUE(CheckFormat(
212 "{\"udp\":{\"send\":[\"a:80\", \"b:10\"]}}",
213 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
214 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10")));
217 CheckFormat("{\"udp\":{\"bind\":\"\"}}",
218 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
219 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[]}}"));
221 CheckFormat("{\"udp\":{\"bind\":[\"\"]}}",
222 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
224 CheckFormat("{\"udp\":{\"bind\":[\"a:80\", \"b:10\"]}}",
225 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
226 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10")));
228 EXPECT_TRUE(CheckFormat(
229 "{\"udp\":{\"multicastMembership\":\"\"}}",
230 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
231 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[]}}"));
232 EXPECT_TRUE(CheckFormat(
233 "{\"udp\":{\"multicastMembership\":[\"\"]}}",
234 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
235 EXPECT_TRUE(CheckFormat(
236 "{\"udp\":{\"multicastMembership\":[\"\", \"\"]}}",
237 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
239 EXPECT_TRUE(CheckFormat(
240 "{\"tcp\":{\"connect\":\"\"}}",
241 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
242 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[]}}"));
243 EXPECT_TRUE(CheckFormat(
244 "{\"tcp\":{\"connect\":[\"\"]}}",
245 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
246 EXPECT_TRUE(CheckFormat(
247 "{\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}}",
248 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
249 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10")));
251 EXPECT_TRUE(CheckFormat(
252 "{\"tcpServer\":{\"listen\":\"\"}}",
253 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
254 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[]}}"));
255 EXPECT_TRUE(CheckFormat(
256 "{\"tcpServer\":{\"listen\":[\"\"]}}",
257 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
258 EXPECT_TRUE(CheckFormat(
259 "{\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}}",
260 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
261 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
263 EXPECT_TRUE(CheckFormat(
266 "\"send\":[\"a:80\", \"b:10\"],"
267 "\"bind\":[\"a:80\", \"b:10\"],"
268 "\"multicastMembership\":\"\""
270 "\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]},"
271 "\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}"
273 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
274 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10"),
275 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
276 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10"),
277 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, ""),
278 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
279 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10"),
280 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
281 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
284 TEST(SocketsManifestPermissionTest
, FromToValue
) {
285 scoped_ptr
<base::Value
> udp_send(ParsePermissionJSON(kUdpBindPermission
));
286 scoped_ptr
<base::Value
> udp_bind(ParsePermissionJSON(kUdpSendPermission
));
287 scoped_ptr
<base::Value
> tcp_connect(
288 ParsePermissionJSON(kTcpConnectPermission
));
289 scoped_ptr
<base::Value
> tcp_server_listen(
290 ParsePermissionJSON(kTcpServerListenPermission
));
293 scoped_ptr
<SocketsManifestPermission
> permission1(
294 new SocketsManifestPermission());
295 EXPECT_TRUE(permission1
->FromValue(udp_send
.get()));
296 EXPECT_EQ(2u, permission1
->entries().size());
298 scoped_ptr
<SocketsManifestPermission
> permission2(
299 new SocketsManifestPermission());
300 EXPECT_TRUE(permission2
->FromValue(udp_bind
.get()));
301 EXPECT_EQ(2u, permission2
->entries().size());
303 scoped_ptr
<SocketsManifestPermission
> permission3(
304 new SocketsManifestPermission());
305 EXPECT_TRUE(permission3
->FromValue(tcp_connect
.get()));
306 EXPECT_EQ(2u, permission3
->entries().size());
308 scoped_ptr
<SocketsManifestPermission
> permission4(
309 new SocketsManifestPermission());
310 EXPECT_TRUE(permission4
->FromValue(tcp_server_listen
.get()));
311 EXPECT_EQ(2u, permission4
->entries().size());
314 scoped_ptr
<base::Value
> value1
= permission1
->ToValue();
316 scoped_ptr
<SocketsManifestPermission
> permission1_1(
317 new SocketsManifestPermission());
318 EXPECT_TRUE(permission1_1
->FromValue(value1
.get()));
319 EXPECT_TRUE(permission1
->Equal(permission1_1
.get()));
321 scoped_ptr
<base::Value
> value2
= permission2
->ToValue();
323 scoped_ptr
<SocketsManifestPermission
> permission2_1(
324 new SocketsManifestPermission());
325 EXPECT_TRUE(permission2_1
->FromValue(value2
.get()));
326 EXPECT_TRUE(permission2
->Equal(permission2_1
.get()));
328 scoped_ptr
<base::Value
> value3
= permission3
->ToValue();
330 scoped_ptr
<SocketsManifestPermission
> permission3_1(
331 new SocketsManifestPermission());
332 EXPECT_TRUE(permission3_1
->FromValue(value3
.get()));
333 EXPECT_TRUE(permission3
->Equal(permission3_1
.get()));
335 scoped_ptr
<base::Value
> value4
= permission4
->ToValue();
337 scoped_ptr
<SocketsManifestPermission
> permission4_1(
338 new SocketsManifestPermission());
339 EXPECT_TRUE(permission4_1
->FromValue(value4
.get()));
340 EXPECT_TRUE(permission4
->Equal(permission4_1
.get()));
343 TEST(SocketsManifestPermissionTest
, SetOperations
) {
344 scoped_ptr
<SocketsManifestPermission
> permission1(
345 PermissionFromJSON(kUdpBindPermission
));
346 scoped_ptr
<SocketsManifestPermission
> permission2(
347 PermissionFromJSON(kUdpSendPermission
));
348 scoped_ptr
<SocketsManifestPermission
> permission3(
349 PermissionFromJSON(kTcpConnectPermission
));
350 scoped_ptr
<SocketsManifestPermission
> permission4(
351 PermissionFromJSON(kTcpServerListenPermission
));
354 scoped_ptr
<SocketsManifestPermission
> union_perm(
355 static_cast<SocketsManifestPermission
*>(
356 permission1
->Union(permission2
.get())));
357 EXPECT_TRUE(union_perm
);
358 EXPECT_EQ(4u, union_perm
->entries().size());
360 EXPECT_TRUE(union_perm
->Contains(permission1
.get()));
361 EXPECT_TRUE(union_perm
->Contains(permission2
.get()));
362 EXPECT_FALSE(union_perm
->Contains(permission3
.get()));
363 EXPECT_FALSE(union_perm
->Contains(permission4
.get()));
366 scoped_ptr
<SocketsManifestPermission
> diff_perm1(
367 static_cast<SocketsManifestPermission
*>(
368 permission1
->Diff(permission2
.get())));
369 EXPECT_TRUE(diff_perm1
);
370 EXPECT_EQ(2u, diff_perm1
->entries().size());
372 EXPECT_TRUE(permission1
->Equal(diff_perm1
.get()));
373 EXPECT_TRUE(diff_perm1
->Equal(permission1
.get()));
375 scoped_ptr
<SocketsManifestPermission
> diff_perm2(
376 static_cast<SocketsManifestPermission
*>(
377 permission1
->Diff(union_perm
.get())));
378 EXPECT_TRUE(diff_perm2
);
379 AssertEmptyPermission(diff_perm2
.get());
382 scoped_ptr
<SocketsManifestPermission
> intersect_perm1(
383 static_cast<SocketsManifestPermission
*>(
384 union_perm
->Intersect(permission1
.get())));
385 EXPECT_TRUE(intersect_perm1
);
386 EXPECT_EQ(2u, intersect_perm1
->entries().size());
388 EXPECT_TRUE(permission1
->Equal(intersect_perm1
.get()));
389 EXPECT_TRUE(intersect_perm1
->Equal(permission1
.get()));
392 TEST(SocketsManifestPermissionTest
, IPC
) {
393 scoped_ptr
<SocketsManifestPermission
> permission(
394 PermissionFromJSON(kUdpBindPermission
));
396 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
397 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
398 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
399 new SocketsManifestPermission());
403 PickleIterator
iter(m
);
404 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
405 EXPECT_TRUE(permission
->Equal(ipc_perm2
.get()));
408 } // namespace extensions