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/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
) << "Error parsing Value into permission: " << error16
;
54 return permission
.Pass();
57 static scoped_ptr
<SocketsManifestPermission
> PermissionFromJSON(
58 const std::string
& json
) {
59 scoped_ptr
<base::Value
> value(ParsePermissionJSON(json
));
60 return PermissionFromValue(*value
);
63 struct CheckFormatEntry
{
64 CheckFormatEntry(SocketPermissionRequest::OperationType operation_type
,
65 std::string host_pattern
)
66 : operation_type(operation_type
), host_pattern(host_pattern
) {}
68 // operators <, == are needed by container std::set and algorithms
69 // std::set_includes and std::set_differences.
70 bool operator<(const CheckFormatEntry
& rhs
) const {
71 if (operation_type
== rhs
.operation_type
)
72 return host_pattern
< rhs
.host_pattern
;
74 return operation_type
< rhs
.operation_type
;
77 bool operator==(const CheckFormatEntry
& rhs
) const {
78 return operation_type
== rhs
.operation_type
&&
79 host_pattern
== rhs
.host_pattern
;
82 SocketPermissionRequest::OperationType operation_type
;
83 std::string host_pattern
;
86 static testing::AssertionResult
CheckFormat(
87 std::multiset
<CheckFormatEntry
> permissions
,
88 const std::string
& json
) {
89 scoped_ptr
<SocketsManifestPermission
> permission(PermissionFromJSON(json
));
91 return testing::AssertionFailure() << "Invalid permission " << json
;
93 if (permissions
.size() != permission
->entries().size()) {
94 return testing::AssertionFailure()
95 << "Incorrect # of entries in json: " << json
;
98 // Note: We use multiset because SocketsManifestPermission does not have to
99 // store entries in the order found in the json message.
100 std::multiset
<CheckFormatEntry
> parsed_permissions
;
101 for (SocketsManifestPermission::SocketPermissionEntrySet::const_iterator it
=
102 permission
->entries().begin();
103 it
!= permission
->entries().end();
105 parsed_permissions
.insert(
106 CheckFormatEntry(it
->pattern().type
, it
->GetHostPatternAsString()));
110 permissions
.begin(), permissions
.end(), parsed_permissions
.begin())) {
111 return testing::AssertionFailure() << "Incorrect socket operations.";
113 return testing::AssertionSuccess();
116 static testing::AssertionResult
CheckFormat(const std::string
& json
) {
117 return CheckFormat(std::multiset
<CheckFormatEntry
>(), json
);
120 static testing::AssertionResult
CheckFormat(const std::string
& json
,
121 const CheckFormatEntry
& op1
) {
122 CheckFormatEntry entries
[] = {op1
};
124 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
128 static testing::AssertionResult
CheckFormat(const std::string
& json
,
129 const CheckFormatEntry
& op1
,
130 const CheckFormatEntry
& op2
) {
131 CheckFormatEntry entries
[] = {op1
, op2
};
133 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
137 static testing::AssertionResult
CheckFormat(const std::string
& json
,
138 const CheckFormatEntry
& op1
,
139 const CheckFormatEntry
& op2
,
140 const CheckFormatEntry
& op3
,
141 const CheckFormatEntry
& op4
,
142 const CheckFormatEntry
& op5
,
143 const CheckFormatEntry
& op6
,
144 const CheckFormatEntry
& op7
,
145 const CheckFormatEntry
& op8
,
146 const CheckFormatEntry
& op9
) {
147 CheckFormatEntry entries
[] = {op1
, op2
, op3
, op4
, op5
, op6
, op7
, op8
, op9
};
149 std::multiset
<CheckFormatEntry
>(entries
, entries
+ arraysize(entries
)),
155 TEST(SocketsManifestPermissionTest
, Empty
) {
157 scoped_ptr
<SocketsManifestPermission
> permission(
158 new SocketsManifestPermission());
159 AssertEmptyPermission(permission
.get());
162 scoped_ptr
<SocketsManifestPermission
> clone(
163 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
164 AssertEmptyPermission(clone
.get());
166 EXPECT_TRUE(permission
->Equal(clone
.get()));
168 // ToValue()/FromValue()
169 scoped_ptr
<const base::Value
> value(permission
->ToValue());
170 EXPECT_TRUE(value
.get());
172 scoped_ptr
<SocketsManifestPermission
> permission2(
173 new SocketsManifestPermission());
174 EXPECT_TRUE(permission2
->FromValue(value
.get()));
175 AssertEmptyPermission(permission2
.get());
177 // Union/Diff/Intersection
178 scoped_ptr
<SocketsManifestPermission
> diff_perm(
179 static_cast<SocketsManifestPermission
*>(permission
->Diff(clone
.get())));
180 AssertEmptyPermission(diff_perm
.get());
182 scoped_ptr
<SocketsManifestPermission
> union_perm(
183 static_cast<SocketsManifestPermission
*>(permission
->Union(clone
.get())));
184 AssertEmptyPermission(union_perm
.get());
186 scoped_ptr
<SocketsManifestPermission
> intersect_perm(
187 static_cast<SocketsManifestPermission
*>(
188 permission
->Intersect(clone
.get())));
189 AssertEmptyPermission(intersect_perm
.get());
192 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
193 new SocketsManifestPermission());
194 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
195 new SocketsManifestPermission());
199 PickleIterator
iter(m
);
200 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
201 AssertEmptyPermission(ipc_perm2
.get());
204 TEST(SocketsManifestPermissionTest
, JSONFormats
) {
205 EXPECT_TRUE(CheckFormat(
206 "{\"udp\":{\"send\":\"\"}}",
207 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
208 EXPECT_TRUE(CheckFormat("{\"udp\":{\"send\":[]}}"));
209 EXPECT_TRUE(CheckFormat(
210 "{\"udp\":{\"send\":[\"\"]}}",
211 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "*:*")));
212 EXPECT_TRUE(CheckFormat(
213 "{\"udp\":{\"send\":[\"a:80\", \"b:10\"]}}",
214 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
215 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10")));
218 CheckFormat("{\"udp\":{\"bind\":\"\"}}",
219 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
220 EXPECT_TRUE(CheckFormat("{\"udp\":{\"bind\":[]}}"));
222 CheckFormat("{\"udp\":{\"bind\":[\"\"]}}",
223 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "*:*")));
225 CheckFormat("{\"udp\":{\"bind\":[\"a:80\", \"b:10\"]}}",
226 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
227 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10")));
229 EXPECT_TRUE(CheckFormat(
230 "{\"udp\":{\"multicastMembership\":\"\"}}",
231 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
232 EXPECT_TRUE(CheckFormat("{\"udp\":{\"multicastMembership\":[]}}"));
233 EXPECT_TRUE(CheckFormat(
234 "{\"udp\":{\"multicastMembership\":[\"\"]}}",
235 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
236 EXPECT_TRUE(CheckFormat(
237 "{\"udp\":{\"multicastMembership\":[\"\", \"\"]}}",
238 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, "")));
240 EXPECT_TRUE(CheckFormat(
241 "{\"tcp\":{\"connect\":\"\"}}",
242 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
243 EXPECT_TRUE(CheckFormat("{\"tcp\":{\"connect\":[]}}"));
244 EXPECT_TRUE(CheckFormat(
245 "{\"tcp\":{\"connect\":[\"\"]}}",
246 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "*:*")));
247 EXPECT_TRUE(CheckFormat(
248 "{\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}}",
249 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
250 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10")));
252 EXPECT_TRUE(CheckFormat(
253 "{\"tcpServer\":{\"listen\":\"\"}}",
254 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
255 EXPECT_TRUE(CheckFormat("{\"tcpServer\":{\"listen\":[]}}"));
256 EXPECT_TRUE(CheckFormat(
257 "{\"tcpServer\":{\"listen\":[\"\"]}}",
258 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "*:*")));
259 EXPECT_TRUE(CheckFormat(
260 "{\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}}",
261 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
262 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
264 EXPECT_TRUE(CheckFormat(
267 "\"send\":[\"a:80\", \"b:10\"],"
268 "\"bind\":[\"a:80\", \"b:10\"],"
269 "\"multicastMembership\":\"\""
271 "\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]},"
272 "\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}"
274 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "a:80"),
275 CheckFormatEntry(SocketPermissionRequest::UDP_SEND_TO
, "b:10"),
276 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "a:80"),
277 CheckFormatEntry(SocketPermissionRequest::UDP_BIND
, "b:10"),
278 CheckFormatEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP
, ""),
279 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "a:80"),
280 CheckFormatEntry(SocketPermissionRequest::TCP_CONNECT
, "b:10"),
281 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "a:80"),
282 CheckFormatEntry(SocketPermissionRequest::TCP_LISTEN
, "b:10")));
285 TEST(SocketsManifestPermissionTest
, FromToValue
) {
286 scoped_ptr
<base::Value
> udp_send(ParsePermissionJSON(kUdpBindPermission
));
287 scoped_ptr
<base::Value
> udp_bind(ParsePermissionJSON(kUdpSendPermission
));
288 scoped_ptr
<base::Value
> tcp_connect(
289 ParsePermissionJSON(kTcpConnectPermission
));
290 scoped_ptr
<base::Value
> tcp_server_listen(
291 ParsePermissionJSON(kTcpServerListenPermission
));
294 scoped_ptr
<SocketsManifestPermission
> permission1(
295 new SocketsManifestPermission());
296 EXPECT_TRUE(permission1
->FromValue(udp_send
.get()));
297 EXPECT_EQ(2u, permission1
->entries().size());
299 scoped_ptr
<SocketsManifestPermission
> permission2(
300 new SocketsManifestPermission());
301 EXPECT_TRUE(permission2
->FromValue(udp_bind
.get()));
302 EXPECT_EQ(2u, permission2
->entries().size());
304 scoped_ptr
<SocketsManifestPermission
> permission3(
305 new SocketsManifestPermission());
306 EXPECT_TRUE(permission3
->FromValue(tcp_connect
.get()));
307 EXPECT_EQ(2u, permission3
->entries().size());
309 scoped_ptr
<SocketsManifestPermission
> permission4(
310 new SocketsManifestPermission());
311 EXPECT_TRUE(permission4
->FromValue(tcp_server_listen
.get()));
312 EXPECT_EQ(2u, permission4
->entries().size());
315 scoped_ptr
<base::Value
> value1
= permission1
->ToValue();
317 scoped_ptr
<SocketsManifestPermission
> permission1_1(
318 new SocketsManifestPermission());
319 EXPECT_TRUE(permission1_1
->FromValue(value1
.get()));
320 EXPECT_TRUE(permission1
->Equal(permission1_1
.get()));
322 scoped_ptr
<base::Value
> value2
= permission2
->ToValue();
324 scoped_ptr
<SocketsManifestPermission
> permission2_1(
325 new SocketsManifestPermission());
326 EXPECT_TRUE(permission2_1
->FromValue(value2
.get()));
327 EXPECT_TRUE(permission2
->Equal(permission2_1
.get()));
329 scoped_ptr
<base::Value
> value3
= permission3
->ToValue();
331 scoped_ptr
<SocketsManifestPermission
> permission3_1(
332 new SocketsManifestPermission());
333 EXPECT_TRUE(permission3_1
->FromValue(value3
.get()));
334 EXPECT_TRUE(permission3
->Equal(permission3_1
.get()));
336 scoped_ptr
<base::Value
> value4
= permission4
->ToValue();
338 scoped_ptr
<SocketsManifestPermission
> permission4_1(
339 new SocketsManifestPermission());
340 EXPECT_TRUE(permission4_1
->FromValue(value4
.get()));
341 EXPECT_TRUE(permission4
->Equal(permission4_1
.get()));
344 TEST(SocketsManifestPermissionTest
, SetOperations
) {
345 scoped_ptr
<SocketsManifestPermission
> permission1(
346 PermissionFromJSON(kUdpBindPermission
));
347 scoped_ptr
<SocketsManifestPermission
> permission2(
348 PermissionFromJSON(kUdpSendPermission
));
349 scoped_ptr
<SocketsManifestPermission
> permission3(
350 PermissionFromJSON(kTcpConnectPermission
));
351 scoped_ptr
<SocketsManifestPermission
> permission4(
352 PermissionFromJSON(kTcpServerListenPermission
));
355 scoped_ptr
<SocketsManifestPermission
> union_perm(
356 static_cast<SocketsManifestPermission
*>(
357 permission1
->Union(permission2
.get())));
358 EXPECT_TRUE(union_perm
);
359 EXPECT_EQ(4u, union_perm
->entries().size());
361 EXPECT_TRUE(union_perm
->Contains(permission1
.get()));
362 EXPECT_TRUE(union_perm
->Contains(permission2
.get()));
363 EXPECT_FALSE(union_perm
->Contains(permission3
.get()));
364 EXPECT_FALSE(union_perm
->Contains(permission4
.get()));
367 scoped_ptr
<SocketsManifestPermission
> diff_perm1(
368 static_cast<SocketsManifestPermission
*>(
369 permission1
->Diff(permission2
.get())));
370 EXPECT_TRUE(diff_perm1
);
371 EXPECT_EQ(2u, diff_perm1
->entries().size());
373 EXPECT_TRUE(permission1
->Equal(diff_perm1
.get()));
374 EXPECT_TRUE(diff_perm1
->Equal(permission1
.get()));
376 scoped_ptr
<SocketsManifestPermission
> diff_perm2(
377 static_cast<SocketsManifestPermission
*>(
378 permission1
->Diff(union_perm
.get())));
379 EXPECT_TRUE(diff_perm2
);
380 AssertEmptyPermission(diff_perm2
.get());
383 scoped_ptr
<SocketsManifestPermission
> intersect_perm1(
384 static_cast<SocketsManifestPermission
*>(
385 union_perm
->Intersect(permission1
.get())));
386 EXPECT_TRUE(intersect_perm1
);
387 EXPECT_EQ(2u, intersect_perm1
->entries().size());
389 EXPECT_TRUE(permission1
->Equal(intersect_perm1
.get()));
390 EXPECT_TRUE(intersect_perm1
->Equal(permission1
.get()));
393 TEST(SocketsManifestPermissionTest
, IPC
) {
394 scoped_ptr
<SocketsManifestPermission
> permission(
395 PermissionFromJSON(kUdpBindPermission
));
397 scoped_ptr
<SocketsManifestPermission
> ipc_perm(
398 static_cast<SocketsManifestPermission
*>(permission
->Clone()));
399 scoped_ptr
<SocketsManifestPermission
> ipc_perm2(
400 new SocketsManifestPermission());
404 PickleIterator
iter(m
);
405 EXPECT_TRUE(ipc_perm2
->Read(&m
, &iter
));
406 EXPECT_TRUE(permission
->Equal(ipc_perm2
.get()));
409 } // namespace extensions