OLD | NEW |
| (Empty) |
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 <set> | |
6 | |
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" | |
15 | |
16 using content::SocketPermissionRequest; | |
17 | |
18 namespace extensions { | |
19 | |
20 namespace { | |
21 | |
22 const char kUdpBindPermission[]= | |
23 "{ \"udp\": { \"bind\": [\"127.0.0.1:3007\", \"a.com:80\"] } }"; | |
24 | |
25 const char kUdpSendPermission[]= | |
26 "{ \"udp\": { \"send\": [\"\", \"a.com:80\"] } }"; | |
27 | |
28 const char kTcpConnectPermission[]= | |
29 "{ \"tcp\": { \"connect\": [\"127.0.0.1:80\", \"a.com:80\"] } }"; | |
30 | |
31 const char kTcpServerListenPermission[]= | |
32 "{ \"tcpServer\": { \"listen\": [\"127.0.0.1:80\", \"a.com:80\"] } }"; | |
33 | |
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()); | |
40 } | |
41 | |
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; | |
45 return result.Pass(); | |
46 } | |
47 | |
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(); | |
56 } | |
57 | |
58 static scoped_ptr<SocketsManifestPermission> PermissionFromJSON( | |
59 const std::string& json) { | |
60 scoped_ptr<base::Value> value(ParsePermissionJSON(json)); | |
61 return PermissionFromValue(*value); | |
62 } | |
63 | |
64 struct CheckFormatEntry { | |
65 CheckFormatEntry(SocketPermissionRequest::OperationType operation_type, | |
66 std::string host_pattern) | |
67 : operation_type(operation_type), | |
68 host_pattern(host_pattern) { | |
69 } | |
70 | |
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; | |
76 | |
77 return operation_type < rhs.operation_type; | |
78 } | |
79 | |
80 bool operator==(const CheckFormatEntry& rhs) const { | |
81 return operation_type == rhs.operation_type && | |
82 host_pattern == rhs.host_pattern; | |
83 } | |
84 | |
85 SocketPermissionRequest::OperationType operation_type; | |
86 std::string host_pattern; | |
87 }; | |
88 | |
89 static testing::AssertionResult CheckFormat( | |
90 std::multiset<CheckFormatEntry> permissions, | |
91 const std::string& json) { | |
92 scoped_ptr<SocketsManifestPermission> permission(PermissionFromJSON(json)); | |
93 if (!permission) | |
94 return testing::AssertionFailure() << "Invalid permission " << json; | |
95 | |
96 if (permissions.size() != permission->entries().size()) { | |
97 return testing::AssertionFailure() | |
98 << "Incorrect # of entries in json: " << json; | |
99 } | |
100 | |
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(); | |
106 ++it) { | |
107 parsed_permissions.insert( | |
108 CheckFormatEntry(it->pattern().type, it->GetHostPatternAsString())); | |
109 } | |
110 | |
111 if (!std::equal(permissions.begin(), permissions.end(), | |
112 parsed_permissions.begin())) { | |
113 return testing::AssertionFailure() << "Incorrect socket operations."; | |
114 } | |
115 return testing::AssertionSuccess(); | |
116 } | |
117 | |
118 static testing::AssertionResult CheckFormat(const std::string& json) { | |
119 return CheckFormat(std::multiset<CheckFormatEntry>(), json); | |
120 } | |
121 | |
122 static testing::AssertionResult CheckFormat( | |
123 const std::string& json, | |
124 const CheckFormatEntry& op1) { | |
125 CheckFormatEntry entries[] = { | |
126 op1 | |
127 }; | |
128 return CheckFormat(std::multiset<CheckFormatEntry>( | |
129 entries, entries + arraysize(entries)), json); | |
130 } | |
131 | |
132 static testing::AssertionResult CheckFormat( | |
133 const std::string& json, | |
134 const CheckFormatEntry& op1, | |
135 const CheckFormatEntry& op2) { | |
136 CheckFormatEntry entries[] = { | |
137 op1, op2 | |
138 }; | |
139 return CheckFormat(std::multiset<CheckFormatEntry>( | |
140 entries, entries + arraysize(entries)), json); | |
141 } | |
142 | |
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 | |
156 }; | |
157 return CheckFormat(std::multiset<CheckFormatEntry>( | |
158 entries, entries + arraysize(entries)), json); | |
159 } | |
160 | |
161 } // namespace | |
162 | |
163 TEST(SocketsManifestPermissionTest, Empty) { | |
164 // Construction | |
165 scoped_ptr<SocketsManifestPermission> permission( | |
166 new SocketsManifestPermission()); | |
167 AssertEmptyPermission(permission.get()); | |
168 | |
169 // Clone()/Equal() | |
170 scoped_ptr<SocketsManifestPermission> clone( | |
171 static_cast<SocketsManifestPermission*>(permission->Clone())); | |
172 AssertEmptyPermission(clone.get()); | |
173 | |
174 EXPECT_TRUE(permission->Equal(clone.get())); | |
175 | |
176 // ToValue()/FromValue() | |
177 scoped_ptr<const base::Value> value(permission->ToValue()); | |
178 EXPECT_TRUE(value.get()); | |
179 | |
180 scoped_ptr<SocketsManifestPermission> permission2( | |
181 new SocketsManifestPermission()); | |
182 EXPECT_TRUE(permission2->FromValue(value.get())); | |
183 AssertEmptyPermission(permission2.get()); | |
184 | |
185 // Union/Diff/Intersection | |
186 scoped_ptr<SocketsManifestPermission> diff_perm( | |
187 static_cast<SocketsManifestPermission*>(permission->Diff(clone.get()))); | |
188 AssertEmptyPermission(diff_perm.get()); | |
189 | |
190 scoped_ptr<SocketsManifestPermission> union_perm( | |
191 static_cast<SocketsManifestPermission*>(permission->Union(clone.get()))); | |
192 AssertEmptyPermission(union_perm.get()); | |
193 | |
194 scoped_ptr<SocketsManifestPermission> intersect_perm( | |
195 static_cast<SocketsManifestPermission*>( | |
196 permission->Intersect(clone.get()))); | |
197 AssertEmptyPermission(intersect_perm.get()); | |
198 | |
199 // IPC | |
200 scoped_ptr<SocketsManifestPermission> ipc_perm( | |
201 new SocketsManifestPermission()); | |
202 scoped_ptr<SocketsManifestPermission> ipc_perm2( | |
203 new SocketsManifestPermission()); | |
204 | |
205 IPC::Message m; | |
206 ipc_perm->Write(&m); | |
207 PickleIterator iter(m); | |
208 EXPECT_TRUE(ipc_perm2->Read(&m, &iter)); | |
209 AssertEmptyPermission(ipc_perm2.get()); | |
210 } | |
211 | |
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"))); | |
221 | |
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"))); | |
230 | |
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, ""))); | |
238 | |
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"))); | |
247 | |
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"))); | |
256 | |
257 EXPECT_TRUE(CheckFormat( | |
258 "{" | |
259 "\"udp\":{" | |
260 "\"send\":[\"a:80\", \"b:10\"]," | |
261 "\"bind\":[\"a:80\", \"b:10\"]," | |
262 "\"multicastMembership\":\"\"" | |
263 "}," | |
264 "\"tcp\":{\"connect\":[\"a:80\", \"b:10\"]}," | |
265 "\"tcpServer\":{\"listen\":[\"a:80\", \"b:10\"]}" | |
266 "}", | |
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"))); | |
276 | |
277 } | |
278 | |
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)); | |
286 | |
287 // FromValue() | |
288 scoped_ptr<SocketsManifestPermission> permission1( | |
289 new SocketsManifestPermission()); | |
290 EXPECT_TRUE(permission1->FromValue(udp_send.get())); | |
291 EXPECT_EQ(2u, permission1->entries().size()); | |
292 | |
293 scoped_ptr<SocketsManifestPermission> permission2( | |
294 new SocketsManifestPermission()); | |
295 EXPECT_TRUE(permission2->FromValue(udp_bind.get())); | |
296 EXPECT_EQ(2u, permission2->entries().size()); | |
297 | |
298 scoped_ptr<SocketsManifestPermission> permission3( | |
299 new SocketsManifestPermission()); | |
300 EXPECT_TRUE(permission3->FromValue(tcp_connect.get())); | |
301 EXPECT_EQ(2u, permission3->entries().size()); | |
302 | |
303 scoped_ptr<SocketsManifestPermission> permission4( | |
304 new SocketsManifestPermission()); | |
305 EXPECT_TRUE(permission4->FromValue(tcp_server_listen.get())); | |
306 EXPECT_EQ(2u, permission4->entries().size()); | |
307 | |
308 // ToValue() | |
309 scoped_ptr<base::Value> value1 = permission1->ToValue(); | |
310 EXPECT_TRUE(value1); | |
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())); | |
315 | |
316 scoped_ptr<base::Value> value2 = permission2->ToValue(); | |
317 EXPECT_TRUE(value2); | |
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())); | |
322 | |
323 scoped_ptr<base::Value> value3 = permission3->ToValue(); | |
324 EXPECT_TRUE(value3); | |
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())); | |
329 | |
330 scoped_ptr<base::Value> value4 = permission4->ToValue(); | |
331 EXPECT_TRUE(value4); | |
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())); | |
336 } | |
337 | |
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)); | |
347 | |
348 // Union | |
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()); | |
354 | |
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())); | |
359 | |
360 // Diff | |
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()); | |
366 | |
367 EXPECT_TRUE(permission1->Equal(diff_perm1.get())); | |
368 EXPECT_TRUE(diff_perm1->Equal(permission1.get())); | |
369 | |
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()); | |
375 | |
376 // Intersection | |
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()); | |
382 | |
383 EXPECT_TRUE(permission1->Equal(intersect_perm1.get())); | |
384 EXPECT_TRUE(intersect_perm1->Equal(permission1.get())); | |
385 } | |
386 | |
387 TEST(SocketsManifestPermissionTest, IPC) { | |
388 scoped_ptr<SocketsManifestPermission> permission( | |
389 PermissionFromJSON(kUdpBindPermission)); | |
390 | |
391 scoped_ptr<SocketsManifestPermission> ipc_perm( | |
392 static_cast<SocketsManifestPermission*>(permission->Clone())); | |
393 scoped_ptr<SocketsManifestPermission> ipc_perm2( | |
394 new SocketsManifestPermission()); | |
395 | |
396 IPC::Message m; | |
397 ipc_perm->Write(&m); | |
398 PickleIterator iter(m); | |
399 EXPECT_TRUE(ipc_perm2->Read(&m, &iter)); | |
400 EXPECT_TRUE(permission->Equal(ipc_perm2.get())); | |
401 } | |
402 | |
403 } // namespace extensions | |
OLD | NEW |