dom/devicestorage/test/test_fs_app_permissions.html

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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">
    20 </div>
    21 <pre id="test">
    22 <script type="application/javascript;version=1.7">
    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 }
    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 }
    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 }
    54 let MockPermissionPrompt = SpecialPowers.MockPermissionPrompt;
    55 MockPermissionPrompt.init();
    57 SimpleTest.waitForExplicitFinish();
    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   }
    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);
    69   if (!storage) {
    70     testComplete(iframe, data);
    71     return;
    72   }
    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 }
    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   }
    92   createTestFile(data.fileExtension);
    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);
    97   if (!storage) {
    98     testComplete(iframe, data);
    99     return;
   100   }
   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 }
   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   }
   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);
   121   if (!storage) {
   122     testComplete(iframe, data);
   123     return;
   124   }
   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 }
   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   }
   146   createTestFile(data.fileExtension);
   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);
   151   if (!storage) {
   152     testComplete(iframe, data);
   153     return;
   154   }
   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 }
   165 let gTestUri = "https://example.com/tests/dom/devicestorage/test/test_fs_app_permissions.html"
   167 let gData = [
   169   // Directory#get
   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   },
   209   // Web applications with permission granted
   210   {
   211     type: 'pictures',
   212     shouldPass: true,
   213     fileExtension: '.png',
   215     permissions: ["device-storage:pictures"],
   217     test: TestGet
   218   },
   219   {
   220     type: 'videos',
   221     shouldPass: true,
   222     fileExtension: '.ogv',
   224     permissions: ["device-storage:videos"],
   226     test: TestGet
   227   },
   228   {
   229     type: 'videos',
   230     shouldPass: true,
   231     fileExtension: '.ogg',
   233     permissions: ["device-storage:videos"],
   235     test: TestGet
   236   },
   237   {
   238     type: 'music',
   239     shouldPass: true,
   240     fileExtension: '.ogg',
   242     permissions: ["device-storage:music"],
   244     test: TestGet
   245   },
   246   {
   247     type: 'music',
   248     shouldPass: false,
   249     fileExtension: '.txt',
   251     permissions: ["device-storage:music"],
   253     test: TestGet
   254   },
   255   {
   256     type: 'sdcard',
   257     shouldPass: true,
   258     fileExtension: '.txt',
   260     permissions: ["device-storage:sdcard"],
   262     test: TestGet
   263   },
   265   // Certified application with permision granted
   266   {
   267     type: 'pictures',
   268     shouldPass: true,
   269     fileExtension: '.png',
   271     app: "https://example.com/manifest_cert.webapp",
   272     permissions: ["device-storage:pictures"],
   274     test: TestGet
   275   },
   276   {
   277     type: 'videos',
   278     shouldPass: true,
   279     fileExtension: '.ogv',
   281     app: "https://example.com/manifest_cert.webapp",
   282     permissions: ["device-storage:videos"],
   284     test: TestGet
   285   },
   286   {
   287     type: 'videos',
   288     shouldPass: true,
   289     fileExtension: '.ogg',
   291     app: "https://example.com/manifest_cert.webapp",
   292     permissions: ["device-storage:videos"],
   294     test: TestGet
   295   },
   296   {
   297     type: 'music',
   298     shouldPass: true,
   299     fileExtension: '.ogg',
   301     app: "https://example.com/manifest_cert.webapp",
   302     permissions: ["device-storage:music"],
   304     test: TestGet
   305   },
   306   {
   307     type: 'music',
   308     shouldPass: false,
   309     fileExtension: '.txt',
   311     app: "https://example.com/manifest_cert.webapp",
   312     permissions: ["device-storage:music"],
   314     test: TestGet
   315   },
   316   {
   317     type: 'sdcard',
   318     shouldPass: true,
   319     fileExtension: '.txt',
   321     app: "https://example.com/manifest_cert.webapp",
   322     permissions: ["device-storage:sdcard"],
   324     test: TestGet
   325   },
   327   // Directory#createDirectory
   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   },
   351   // Web applications with permission granted
   352   {
   353     type: 'pictures',
   354     shouldPass: true,
   356     permissions: ["device-storage:pictures"],
   358     test: TestCreateDirectory
   359   },
   360   {
   361     type: 'videos',
   362     shouldPass: true,
   364     permissions: ["device-storage:videos"],
   366     test: TestCreateDirectory
   367   },
   368   {
   369     type: 'music',
   370     shouldPass: true,
   372     permissions: ["device-storage:music"],
   374     test: TestCreateDirectory
   375   },
   376   {
   377     type: 'sdcard',
   378     shouldPass: true,
   380     permissions: ["device-storage:sdcard"],
   382     test: TestCreateDirectory
   383   },
   385   // Certified application with permision granted
   386   {
   387     type: 'pictures',
   388     shouldPass: true,
   390     app: "https://example.com/manifest_cert.webapp",
   391     permissions: ["device-storage:pictures"],
   393     test: TestCreateDirectory
   394   },
   395   {
   396     type: 'videos',
   397     shouldPass: true,
   399     app: "https://example.com/manifest_cert.webapp",
   400     permissions: ["device-storage:videos"],
   402     test: TestCreateDirectory
   403   },
   404   {
   405     type: 'music',
   406     shouldPass: true,
   408     app: "https://example.com/manifest_cert.webapp",
   409     permissions: ["device-storage:music"],
   411     test: TestCreateDirectory
   412   },
   413   {
   414     type: 'sdcard',
   415     shouldPass: true,
   417     app: "https://example.com/manifest_cert.webapp",
   418     permissions: ["device-storage:sdcard"],
   420     test: TestCreateDirectory
   421   },
   423   // Directory#createFile
   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   },
   469   // Web applications with permission granted
   470   {
   471     type: 'pictures',
   472     mimeType: 'image/png',
   473     shouldPass: true,
   474     fileExtension: '.png',
   476     permissions: ["device-storage:pictures"],
   478     test: TestCreateFile
   479   },
   480   {
   481     type: 'videos',
   482     mimeType: 'video/ogv',
   483     shouldPass: true,
   484     fileExtension: '.ogv',
   486     permissions: ["device-storage:videos"],
   488     test: TestCreateFile
   489   },
   490   {
   491     type: 'videos',
   492     mimeType: 'video/ogg',
   493     shouldPass: true,
   494     fileExtension: '.ogg',
   496     permissions: ["device-storage:videos"],
   498     test: TestCreateFile
   499   },
   500   {
   501     type: 'music',
   502     mimeType: 'audio/ogg',
   503     shouldPass: true,
   504     fileExtension: '.ogg',
   506     permissions: ["device-storage:music"],
   508     test: TestCreateFile
   509   },
   510   {
   511     type: 'music',
   512     mimeType: 'audio/ogg',
   513     shouldPass: false,
   514     fileExtension: '.txt',
   516     permissions: ["device-storage:music"],
   518     test: TestCreateFile
   519   },
   520   {
   521     type: 'sdcard',
   522     mimeType: 'text/plain',
   523     shouldPass: true,
   524     fileExtension: '.txt',
   526     permissions: ["device-storage:sdcard"],
   528     test: TestCreateFile
   529   },
   531   // Certified application with permision granted
   532   {
   533     type: 'pictures',
   534     mimeType: 'image/png',
   535     shouldPass: true,
   536     fileExtension: '.png',
   538     app: "https://example.com/manifest_cert.webapp",
   539     permissions: ["device-storage:pictures"],
   541     test: TestCreateFile
   542   },
   543   {
   544     type: 'videos',
   545     mimeType: 'video/ogv',
   546     shouldPass: true,
   547     fileExtension: '.ogv',
   549     app: "https://example.com/manifest_cert.webapp",
   550     permissions: ["device-storage:videos"],
   552     test: TestCreateFile
   553   },
   554   {
   555     type: 'videos',
   556     mimeType: 'video/ogg',
   557     shouldPass: true,
   558     fileExtension: '.ogg',
   560     app: "https://example.com/manifest_cert.webapp",
   561     permissions: ["device-storage:videos"],
   563     test: TestCreateFile
   564   },
   565   {
   566     type: 'music',
   567     mimeType: 'audio/ogg',
   568     shouldPass: true,
   569     fileExtension: '.ogg',
   571     app: "https://example.com/manifest_cert.webapp",
   572     permissions: ["device-storage:music"],
   574     test: TestCreateFile
   575   },
   576   {
   577     type: 'music',
   578     mimeType: 'audio/ogg',
   579     shouldPass: false,
   580     fileExtension: '.txt',
   582     app: "https://example.com/manifest_cert.webapp",
   583     permissions: ["device-storage:music"],
   585     test: TestCreateFile
   586   },
   587   {
   588     type: 'sdcard',
   589     mimeType: 'text/plain',
   590     shouldPass: true,
   591     fileExtension: '.txt',
   593     app: "https://example.com/manifest_cert.webapp",
   594     permissions: ["device-storage:sdcard"],
   596     test: TestCreateFile
   597   },
   599   // Directory#remove
   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   },
   639   // Web applications with permission granted
   640   {
   641     type: 'pictures',
   642     shouldPass: true,
   643     fileExtension: '.png',
   645     permissions: ["device-storage:pictures"],
   647     test: TestRemove
   648   },
   649   {
   650     type: 'videos',
   651     shouldPass: true,
   652     fileExtension: '.ogv',
   654     permissions: ["device-storage:videos"],
   656     test: TestRemove
   657   },
   658   {
   659     type: 'videos',
   660     shouldPass: true,
   661     fileExtension: '.ogg',
   663     permissions: ["device-storage:videos"],
   665     test: TestRemove
   666   },
   667   {
   668     type: 'music',
   669     shouldPass: true,
   670     fileExtension: '.ogg',
   672     permissions: ["device-storage:music"],
   674     test: TestRemove
   675   },
   676   {
   677     type: 'music',
   678     shouldPass: false,
   679     fileExtension: '.txt',
   681     permissions: ["device-storage:music"],
   683     test: TestRemove
   684   },
   685   {
   686     type: 'sdcard',
   687     shouldPass: true,
   688     fileExtension: '.txt',
   690     permissions: ["device-storage:sdcard"],
   692     test: TestRemove
   693   },
   695   // Certified application with permision granted
   696   {
   697     type: 'pictures',
   698     shouldPass: true,
   699     fileExtension: '.png',
   701     app: "https://example.com/manifest_cert.webapp",
   702     permissions: ["device-storage:pictures"],
   704     test: TestRemove
   705   },
   706   {
   707     type: 'videos',
   708     shouldPass: true,
   709     fileExtension: '.ogv',
   711     app: "https://example.com/manifest_cert.webapp",
   712     permissions: ["device-storage:videos"],
   714     test: TestRemove
   715   },
   716   {
   717     type: 'videos',
   718     shouldPass: true,
   719     fileExtension: '.ogg',
   721     app: "https://example.com/manifest_cert.webapp",
   722     permissions: ["device-storage:videos"],
   724     test: TestRemove
   725   },
   726   {
   727     type: 'music',
   728     shouldPass: true,
   729     fileExtension: '.ogg',
   731     app: "https://example.com/manifest_cert.webapp",
   732     permissions: ["device-storage:music"],
   734     test: TestRemove
   735   },
   736   {
   737     type: 'music',
   738     shouldPass: false,
   739     fileExtension: '.txt',
   741     app: "https://example.com/manifest_cert.webapp",
   742     permissions: ["device-storage:music"],
   744     test: TestRemove
   745   },
   746   {
   747     type: 'sdcard',
   748     shouldPass: true,
   749     fileExtension: '.txt',
   751     app: "https://example.com/manifest_cert.webapp",
   752     permissions: ["device-storage:sdcard"],
   754     test: TestRemove
   755   }
   757 ];
   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 }
   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   }
   774   document.getElementById('content').removeChild(iframe);
   776   if (gData.length == 0) {
   777     SimpleTest.finish();
   778   } else {
   779     gTestRunner.next();
   780   }
   781 }
   783 function runTest() {
   784   while (gData.length > 0) {
   785     let iframe = document.createElement('iframe');
   786     let data = gData.shift();
   788     iframe.setAttribute('mozbrowser', '');
   789     if (data.app) {
   790       iframe.setAttribute('mozapp', data.app);
   791     }
   793     iframe.src = gTestUri;
   795     iframe.addEventListener('load', function(e) {
   796       setupTest(iframe, data)
   797       data.test(iframe, data);
   798     });
   800     document.getElementById('content').appendChild(iframe);
   801     yield undefined;
   802   }
   803 }
   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 }
   818 let gTestRunner = runTest();
   819 SpecialPowers.addPermission("browser", true, gTestUri);
   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'";
   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(); });
   833 </script>
   834 </pre>
   835 </body>
   836 </html>

mercurial