dom/devicestorage/test/test_fs_app_permissions.html

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:404240261537
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=910412
5 -->
6 <head>
7 <meta charset="utf-8">
8 <title>Permission test of FileSystem API for Device Storage</title>
9 <script type="application/javascript"
10 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
11 <link rel="stylesheet" type="text/css"
12 href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
13 </head>
14 <body>
15 <a target="_blank"
16 href="https://bugzilla.mozilla.org/show_bug.cgi?id=910412">Mozilla Bug 910412</a>
17 <p id="display"></p>
18 <div id="content">
19
20 </div>
21 <pre id="test">
22 <script type="application/javascript;version=1.7">
23
24 function randomFilename(l) {
25 let set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
26 let result = "";
27 for (let i=0; i<l; i++) {
28 let r = Math.floor(set.length * Math.random());
29 result += set.substring(r, r + 1);
30 }
31 return result;
32 }
33
34 function getRandomBuffer() {
35 var size = 1024;
36 var buffer = new ArrayBuffer(size);
37 var view = new Uint8Array(buffer);
38 for (var i = 0; i < size; i++) {
39 view[i] = parseInt(Math.random() * 255);
40 }
41 return buffer;
42 }
43
44 function createRandomBlob(mime) {
45 let size = 1024;
46 let buffer = new ArrayBuffer(size);
47 let view = new Uint8Array(buffer);
48 for (let i = 0; i < size; i++) {
49 view[i] = parseInt(Math.random() * 255);
50 }
51 return blob = new Blob([buffer], {type: mime});
52 }
53
54 let MockPermissionPrompt = SpecialPowers.MockPermissionPrompt;
55 MockPermissionPrompt.init();
56
57 SimpleTest.waitForExplicitFinish();
58
59 function TestCreateDirectory(iframe, data) {
60 function cbError(e) {
61 is(e.name, "SecurityError", "[TestCreateDirectory] Should fire a SecurityError for type " + data.type);
62 is(data.shouldPass, false, "[TestCreateDirectory] Error callback was called for type " + data.type + '. Error: ' + e.name);
63 testComplete(iframe, data);
64 }
65
66 let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
67 isnot(storage, null, "[TestCreateDirectory] Should be able to get storage object for " + data.type);
68
69 if (!storage) {
70 testComplete(iframe, data);
71 return;
72 }
73
74 storage.getRoot().then(function(root) {
75 is(data.shouldPass, true, "[TestCreateDirectory] Success callback was called for type " + data.type);
76 let filename = randomFilename(100);
77 root.createDirectory(filename).then(function(d) {
78 let passed = d && (d.name === filename);
79 is(data.shouldPass, passed, "[TestCreateDirectory] Success callback was called for type " + data.type);
80 testComplete(iframe, data);
81 }, cbError);
82 }, cbError);
83 }
84
85 function TestGet(iframe, data) {
86 function cbError(e) {
87 is(e.name, "SecurityError", "[TestGet] Should fire a SecurityError for type " + data.type);
88 is(data.shouldPass, false, "[TestGet] Error callback was called for type " + data.type + '. Error: ' + e.name);
89 testComplete(iframe, data);
90 }
91
92 createTestFile(data.fileExtension);
93
94 let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
95 isnot(storage, null, "[TestGet] Should be able to get storage object for " + data.type);
96
97 if (!storage) {
98 testComplete(iframe, data);
99 return;
100 }
101
102 storage.getRoot().then(function(root) {
103 ok(true, "[TestGet] Success callback of getRoot was called for type " + data.type);
104 root.get("testfile" + data.fileExtension).then(function() {
105 is(data.shouldPass, true, "[TestGet] Success callback was called for type " + data.type);
106 testComplete(iframe, data);
107 }, cbError);
108 }, cbError);
109 }
110
111 function TestCreateFile(iframe, data) {
112 function cbError(e) {
113 is(e.name, "SecurityError", "[TestCreateFile] Should fire a SecurityError for type " + data.type);
114 is(data.shouldPass, false, "[TestCreateFile] Error callback was called for type " + data.type + '. Error: ' + e.name);
115 testComplete(iframe, data);
116 }
117
118 let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
119 isnot(storage, null, "[TestCreateFile] Should be able to get storage object for " + data.type);
120
121 if (!storage) {
122 testComplete(iframe, data);
123 return;
124 }
125
126 storage.getRoot().then(function(root) {
127 ok(true, "[TestCreateFile] Success callback of getRoot was called for type " + data.type);
128 let filename = randomFilename(100) + data.fileExtension;
129 root.createFile(filename, {
130 data: createRandomBlob(data.mimeType),
131 ifExists: "replace"
132 }).then(function() {
133 is(data.shouldPass, true, "[TestCreateFile] Success callback was called for type " + data.type);
134 testComplete(iframe, data);
135 }, cbError);
136 }, cbError);
137 }
138
139 function TestRemove(iframe, data) {
140 function cbError(e) {
141 is(e.name, "SecurityError", "[TestRemove] Should fire a SecurityError for type " + data.type);
142 is(data.shouldPass, false, "[TestRemove] Error callback was called for type " + data.type + '. Error: ' + e.name);
143 testComplete(iframe, data);
144 }
145
146 createTestFile(data.fileExtension);
147
148 let storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
149 isnot(storage, null, "[TestRemove] Should be able to get storage object for " + data.type);
150
151 if (!storage) {
152 testComplete(iframe, data);
153 return;
154 }
155
156 storage.getRoot().then(function(root) {
157 ok(true, "[TestRemove] Success callback of getRoot was called for type " + data.type);
158 root.remove("testfile" + data.fileExtension).then(function() {
159 is(data.shouldPass, true, "[TestRemove] Success callback was called for type " + data.type);
160 testComplete(iframe, data);
161 }, cbError);
162 }, cbError);
163 }
164
165 let gTestUri = "https://example.com/tests/dom/devicestorage/test/test_fs_app_permissions.html"
166
167 let gData = [
168
169 // Directory#get
170
171 // Web applications with no permissions
172 {
173 type: 'pictures',
174 shouldPass: false,
175 fileExtension: '.png',
176 test: TestGet
177 },
178 {
179 type: 'videos',
180 shouldPass: false,
181 fileExtension: '.ogv',
182 test: TestGet
183 },
184 {
185 type: 'videos',
186 shouldPass: false,
187 fileExtension: '.ogg',
188 test: TestGet
189 },
190 {
191 type: 'music',
192 shouldPass: false,
193 fileExtension: '.ogg',
194 test: TestGet
195 },
196 {
197 type: 'music',
198 shouldPass: false,
199 fileExtension: '.txt',
200 test: TestGet
201 },
202 {
203 type: 'sdcard',
204 shouldPass: false,
205 fileExtension: '.txt',
206 test: TestGet
207 },
208
209 // Web applications with permission granted
210 {
211 type: 'pictures',
212 shouldPass: true,
213 fileExtension: '.png',
214
215 permissions: ["device-storage:pictures"],
216
217 test: TestGet
218 },
219 {
220 type: 'videos',
221 shouldPass: true,
222 fileExtension: '.ogv',
223
224 permissions: ["device-storage:videos"],
225
226 test: TestGet
227 },
228 {
229 type: 'videos',
230 shouldPass: true,
231 fileExtension: '.ogg',
232
233 permissions: ["device-storage:videos"],
234
235 test: TestGet
236 },
237 {
238 type: 'music',
239 shouldPass: true,
240 fileExtension: '.ogg',
241
242 permissions: ["device-storage:music"],
243
244 test: TestGet
245 },
246 {
247 type: 'music',
248 shouldPass: false,
249 fileExtension: '.txt',
250
251 permissions: ["device-storage:music"],
252
253 test: TestGet
254 },
255 {
256 type: 'sdcard',
257 shouldPass: true,
258 fileExtension: '.txt',
259
260 permissions: ["device-storage:sdcard"],
261
262 test: TestGet
263 },
264
265 // Certified application with permision granted
266 {
267 type: 'pictures',
268 shouldPass: true,
269 fileExtension: '.png',
270
271 app: "https://example.com/manifest_cert.webapp",
272 permissions: ["device-storage:pictures"],
273
274 test: TestGet
275 },
276 {
277 type: 'videos',
278 shouldPass: true,
279 fileExtension: '.ogv',
280
281 app: "https://example.com/manifest_cert.webapp",
282 permissions: ["device-storage:videos"],
283
284 test: TestGet
285 },
286 {
287 type: 'videos',
288 shouldPass: true,
289 fileExtension: '.ogg',
290
291 app: "https://example.com/manifest_cert.webapp",
292 permissions: ["device-storage:videos"],
293
294 test: TestGet
295 },
296 {
297 type: 'music',
298 shouldPass: true,
299 fileExtension: '.ogg',
300
301 app: "https://example.com/manifest_cert.webapp",
302 permissions: ["device-storage:music"],
303
304 test: TestGet
305 },
306 {
307 type: 'music',
308 shouldPass: false,
309 fileExtension: '.txt',
310
311 app: "https://example.com/manifest_cert.webapp",
312 permissions: ["device-storage:music"],
313
314 test: TestGet
315 },
316 {
317 type: 'sdcard',
318 shouldPass: true,
319 fileExtension: '.txt',
320
321 app: "https://example.com/manifest_cert.webapp",
322 permissions: ["device-storage:sdcard"],
323
324 test: TestGet
325 },
326
327 // Directory#createDirectory
328
329 // Web applications with no permissions
330 {
331 type: 'pictures',
332 shouldPass: false,
333 test: TestCreateDirectory
334 },
335 {
336 type: 'videos',
337 shouldPass: false,
338 test: TestCreateDirectory
339 },
340 {
341 type: 'music',
342 shouldPass: false,
343 test: TestCreateDirectory
344 },
345 {
346 type: 'sdcard',
347 shouldPass: false,
348 test: TestCreateDirectory
349 },
350
351 // Web applications with permission granted
352 {
353 type: 'pictures',
354 shouldPass: true,
355
356 permissions: ["device-storage:pictures"],
357
358 test: TestCreateDirectory
359 },
360 {
361 type: 'videos',
362 shouldPass: true,
363
364 permissions: ["device-storage:videos"],
365
366 test: TestCreateDirectory
367 },
368 {
369 type: 'music',
370 shouldPass: true,
371
372 permissions: ["device-storage:music"],
373
374 test: TestCreateDirectory
375 },
376 {
377 type: 'sdcard',
378 shouldPass: true,
379
380 permissions: ["device-storage:sdcard"],
381
382 test: TestCreateDirectory
383 },
384
385 // Certified application with permision granted
386 {
387 type: 'pictures',
388 shouldPass: true,
389
390 app: "https://example.com/manifest_cert.webapp",
391 permissions: ["device-storage:pictures"],
392
393 test: TestCreateDirectory
394 },
395 {
396 type: 'videos',
397 shouldPass: true,
398
399 app: "https://example.com/manifest_cert.webapp",
400 permissions: ["device-storage:videos"],
401
402 test: TestCreateDirectory
403 },
404 {
405 type: 'music',
406 shouldPass: true,
407
408 app: "https://example.com/manifest_cert.webapp",
409 permissions: ["device-storage:music"],
410
411 test: TestCreateDirectory
412 },
413 {
414 type: 'sdcard',
415 shouldPass: true,
416
417 app: "https://example.com/manifest_cert.webapp",
418 permissions: ["device-storage:sdcard"],
419
420 test: TestCreateDirectory
421 },
422
423 // Directory#createFile
424
425 // Web applications with no permissions
426 {
427 type: 'pictures',
428 mimeType: 'image/png',
429 shouldPass: false,
430 fileExtension: '.png',
431 test: TestCreateFile
432 },
433 {
434 type: 'videos',
435 mimeType: 'video/ogv',
436 shouldPass: false,
437 fileExtension: '.ogv',
438 test: TestCreateFile
439 },
440 {
441 type: 'videos',
442 mimeType: 'video/ogg',
443 shouldPass: false,
444 fileExtension: '.ogg',
445 test: TestCreateFile
446 },
447 {
448 type: 'music',
449 mimeType: 'audio/ogg',
450 shouldPass: false,
451 fileExtension: '.ogg',
452 test: TestCreateFile
453 },
454 {
455 type: 'music',
456 mimeType: 'audio/ogg',
457 shouldPass: false,
458 fileExtension: '.txt',
459 test: TestCreateFile
460 },
461 {
462 type: 'sdcard',
463 mimeType: 'text/plain',
464 shouldPass: false,
465 fileExtension: '.txt',
466 test: TestCreateFile
467 },
468
469 // Web applications with permission granted
470 {
471 type: 'pictures',
472 mimeType: 'image/png',
473 shouldPass: true,
474 fileExtension: '.png',
475
476 permissions: ["device-storage:pictures"],
477
478 test: TestCreateFile
479 },
480 {
481 type: 'videos',
482 mimeType: 'video/ogv',
483 shouldPass: true,
484 fileExtension: '.ogv',
485
486 permissions: ["device-storage:videos"],
487
488 test: TestCreateFile
489 },
490 {
491 type: 'videos',
492 mimeType: 'video/ogg',
493 shouldPass: true,
494 fileExtension: '.ogg',
495
496 permissions: ["device-storage:videos"],
497
498 test: TestCreateFile
499 },
500 {
501 type: 'music',
502 mimeType: 'audio/ogg',
503 shouldPass: true,
504 fileExtension: '.ogg',
505
506 permissions: ["device-storage:music"],
507
508 test: TestCreateFile
509 },
510 {
511 type: 'music',
512 mimeType: 'audio/ogg',
513 shouldPass: false,
514 fileExtension: '.txt',
515
516 permissions: ["device-storage:music"],
517
518 test: TestCreateFile
519 },
520 {
521 type: 'sdcard',
522 mimeType: 'text/plain',
523 shouldPass: true,
524 fileExtension: '.txt',
525
526 permissions: ["device-storage:sdcard"],
527
528 test: TestCreateFile
529 },
530
531 // Certified application with permision granted
532 {
533 type: 'pictures',
534 mimeType: 'image/png',
535 shouldPass: true,
536 fileExtension: '.png',
537
538 app: "https://example.com/manifest_cert.webapp",
539 permissions: ["device-storage:pictures"],
540
541 test: TestCreateFile
542 },
543 {
544 type: 'videos',
545 mimeType: 'video/ogv',
546 shouldPass: true,
547 fileExtension: '.ogv',
548
549 app: "https://example.com/manifest_cert.webapp",
550 permissions: ["device-storage:videos"],
551
552 test: TestCreateFile
553 },
554 {
555 type: 'videos',
556 mimeType: 'video/ogg',
557 shouldPass: true,
558 fileExtension: '.ogg',
559
560 app: "https://example.com/manifest_cert.webapp",
561 permissions: ["device-storage:videos"],
562
563 test: TestCreateFile
564 },
565 {
566 type: 'music',
567 mimeType: 'audio/ogg',
568 shouldPass: true,
569 fileExtension: '.ogg',
570
571 app: "https://example.com/manifest_cert.webapp",
572 permissions: ["device-storage:music"],
573
574 test: TestCreateFile
575 },
576 {
577 type: 'music',
578 mimeType: 'audio/ogg',
579 shouldPass: false,
580 fileExtension: '.txt',
581
582 app: "https://example.com/manifest_cert.webapp",
583 permissions: ["device-storage:music"],
584
585 test: TestCreateFile
586 },
587 {
588 type: 'sdcard',
589 mimeType: 'text/plain',
590 shouldPass: true,
591 fileExtension: '.txt',
592
593 app: "https://example.com/manifest_cert.webapp",
594 permissions: ["device-storage:sdcard"],
595
596 test: TestCreateFile
597 },
598
599 // Directory#remove
600
601 // Web applications with no permissions
602 {
603 type: 'pictures',
604 shouldPass: false,
605 fileExtension: '.png',
606 test: TestRemove
607 },
608 {
609 type: 'videos',
610 shouldPass: false,
611 fileExtension: '.ogv',
612 test: TestRemove
613 },
614 {
615 type: 'videos',
616 shouldPass: false,
617 fileExtension: '.ogg',
618 test: TestRemove
619 },
620 {
621 type: 'music',
622 shouldPass: false,
623 fileExtension: '.ogg',
624 test: TestRemove
625 },
626 {
627 type: 'music',
628 shouldPass: false,
629 fileExtension: '.txt',
630 test: TestRemove
631 },
632 {
633 type: 'sdcard',
634 shouldPass: false,
635 fileExtension: '.txt',
636 test: TestRemove
637 },
638
639 // Web applications with permission granted
640 {
641 type: 'pictures',
642 shouldPass: true,
643 fileExtension: '.png',
644
645 permissions: ["device-storage:pictures"],
646
647 test: TestRemove
648 },
649 {
650 type: 'videos',
651 shouldPass: true,
652 fileExtension: '.ogv',
653
654 permissions: ["device-storage:videos"],
655
656 test: TestRemove
657 },
658 {
659 type: 'videos',
660 shouldPass: true,
661 fileExtension: '.ogg',
662
663 permissions: ["device-storage:videos"],
664
665 test: TestRemove
666 },
667 {
668 type: 'music',
669 shouldPass: true,
670 fileExtension: '.ogg',
671
672 permissions: ["device-storage:music"],
673
674 test: TestRemove
675 },
676 {
677 type: 'music',
678 shouldPass: false,
679 fileExtension: '.txt',
680
681 permissions: ["device-storage:music"],
682
683 test: TestRemove
684 },
685 {
686 type: 'sdcard',
687 shouldPass: true,
688 fileExtension: '.txt',
689
690 permissions: ["device-storage:sdcard"],
691
692 test: TestRemove
693 },
694
695 // Certified application with permision granted
696 {
697 type: 'pictures',
698 shouldPass: true,
699 fileExtension: '.png',
700
701 app: "https://example.com/manifest_cert.webapp",
702 permissions: ["device-storage:pictures"],
703
704 test: TestRemove
705 },
706 {
707 type: 'videos',
708 shouldPass: true,
709 fileExtension: '.ogv',
710
711 app: "https://example.com/manifest_cert.webapp",
712 permissions: ["device-storage:videos"],
713
714 test: TestRemove
715 },
716 {
717 type: 'videos',
718 shouldPass: true,
719 fileExtension: '.ogg',
720
721 app: "https://example.com/manifest_cert.webapp",
722 permissions: ["device-storage:videos"],
723
724 test: TestRemove
725 },
726 {
727 type: 'music',
728 shouldPass: true,
729 fileExtension: '.ogg',
730
731 app: "https://example.com/manifest_cert.webapp",
732 permissions: ["device-storage:music"],
733
734 test: TestRemove
735 },
736 {
737 type: 'music',
738 shouldPass: false,
739 fileExtension: '.txt',
740
741 app: "https://example.com/manifest_cert.webapp",
742 permissions: ["device-storage:music"],
743
744 test: TestRemove
745 },
746 {
747 type: 'sdcard',
748 shouldPass: true,
749 fileExtension: '.txt',
750
751 app: "https://example.com/manifest_cert.webapp",
752 permissions: ["device-storage:sdcard"],
753
754 test: TestRemove
755 }
756
757 ];
758
759 function setupTest(iframe,data) {
760 if (data.permissions) {
761 for (let j in data.permissions) {
762 SpecialPowers.addPermission(data.permissions[j], true, iframe.contentDocument);
763 }
764 }
765 }
766
767 function testComplete(iframe, data) {
768 if (data.permissions) {
769 for (let j in data.permissions) {
770 SpecialPowers.removePermission(data.permissions[j], iframe.contentDocument);
771 }
772 }
773
774 document.getElementById('content').removeChild(iframe);
775
776 if (gData.length == 0) {
777 SimpleTest.finish();
778 } else {
779 gTestRunner.next();
780 }
781 }
782
783 function runTest() {
784 while (gData.length > 0) {
785 let iframe = document.createElement('iframe');
786 let data = gData.shift();
787
788 iframe.setAttribute('mozbrowser', '');
789 if (data.app) {
790 iframe.setAttribute('mozapp', data.app);
791 }
792
793 iframe.src = gTestUri;
794
795 iframe.addEventListener('load', function(e) {
796 setupTest(iframe, data)
797 data.test(iframe, data);
798 });
799
800 document.getElementById('content').appendChild(iframe);
801 yield undefined;
802 }
803 }
804
805 function createTestFile(extension) {
806 try {
807 const Cc = SpecialPowers.Cc;
808 const Ci = SpecialPowers.Ci;
809 let directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
810 let f = directoryService.get("TmpD", Ci.nsIFile);
811 f.appendRelativePath("device-storage-testing");
812 f.remove(true);
813 f.appendRelativePath("testfile" + extension);
814 f.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
815 } catch(e) {}
816 }
817
818 let gTestRunner = runTest();
819 SpecialPowers.addPermission("browser", true, gTestUri);
820
821 // We are more permissive with CSP in our testing environment....
822 const DEFAULT_CSP_PRIV = "default-src *; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'";
823 const DEFAULT_CSP_CERT = "default-src *; script-src 'self'; style-src 'self'; object-src 'none'";
824
825 SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
826 ["device.storage.enabled", true],
827 ["device.storage.testing", true],
828 ["device.storage.prompt.testing", false],
829 ["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
830 ["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
831 function() { gTestRunner.next(); });
832
833 </script>
834 </pre>
835 </body>
836 </html>

mercurial