Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import re
import sys
from pathlib import Path
sys.path.append(os.fspath(Path(__file__).parents[3] / "quota/test/marionette"))
from quota_test_case import QuotaTestCase
OPFS_PBM_PREF = "dom.fs.privateBrowsing.enabled"
QM_TESTING_PREF = "dom.quotaManager.testing"
class OPFSSyncAccessHandleEncryptionPBM(QuotaTestCase):
"""
Bug2070040: Ensure the file contents a sync access handle writes get
encrypted in Private Browsing Mode. This covers the file entries
themselves, unlike test_OPFS_encryption_PBM, which covers their names in
the metadata database.
"""
def setUp(self):
super().setUp()
self.testHTML = "dom/fs/syncAccessHandleOPFS_PBM.html"
self.fileName = "test_OPFS_SyncAccessHandle_Encryption_PBM.txt"
self.fileContents = "test_OPFS_SyncAccessHandle_Encryption_PBM"
self.databaseFileName = "metadata.sqlite"
self.fsStoragePath = None
self.profilePath = self.marionette.instance.profile.profile
self.defaultOPFSPrefValue = self.marionette.get_pref(OPFS_PBM_PREF)
self.marionette.set_pref(OPFS_PBM_PREF, True)
self.defaultQMPrefValue = self.marionette.get_pref(QM_TESTING_PREF)
self.marionette.set_pref(QM_TESTING_PREF, True)
def tearDown(self):
super().tearDown()
self.marionette.set_pref(OPFS_PBM_PREF, self.defaultOPFSPrefValue)
self.marionette.set_pref(QM_TESTING_PREF, self.defaultQMPrefValue)
def test_ensure_raw_OPFS_file_contents_ondisk_not_in_PBM(self):
"""
A non-private origin's file entries are plaintext. Finding the contents
here is what makes the private case below meaningful: without it, a
passing test could just mean the file was never written.
"""
with self.using_new_window(self.testHTML, private=False) as (
self.origin,
self.persistenceType,
):
self.runAndValidate(
lambda exists: self.assertTrue(
exists, "Failed to find expected data on disk"
)
)
def test_ensure_encrypted_OPFS_file_contents_ondisk_in_PBM(self):
with self.using_new_window(self.testHTML, private=True) as (
self.origin,
self.persistenceType,
):
self.runAndValidate(
lambda exists: self.assertFalse(exists, "Data on disk is not encrypted")
)
def runAndValidate(self, validator):
error = self.marionette.execute_async_script(
"""
const [name, value, resolve] = arguments;
window.wrappedJSObject.writeFileWithSyncAccessHandle(name, value)
.then(() => resolve(null), e => resolve(String(e)));
""",
script_args=(self.fileName, self.fileContents),
)
self.assertIsNone(error)
self.validateFileEntries(validator)
def validateFileEntries(self, validator):
self.resetStoragesForClient(self.persistenceType, self.origin, "fs")
self.ensureInvariantHolds(lambda _: self.findFileEntry() is not None)
with open(self.findFileEntry(), "rb") as f_binary:
foundRawValue = (
re.search(self.fileContents.encode("ascii"), f_binary.read())
is not None
)
validator(foundRawValue)
def findFileEntry(self):
"""
A file entry is not stored under the name it was created with, so find
it by elimination: everything below the fs directory which isn't the
metadata database is a file entry, and this test only ever creates one.
"""
for root, _, files in os.walk(self.getFsStoragePath()):
for name in files:
if name.startswith(self.databaseFileName):
continue
return os.path.join(root, name)
return None
def getFsStoragePath(self):
if self.fsStoragePath is not None:
return self.fsStoragePath
assert self.origin is not None
assert self.persistenceType is not None
self.fsStoragePath = self.getStoragePath(
self.profilePath, self.origin, self.persistenceType, "fs"
)
self.logger.info(f"fs origin directory = {self.fsStoragePath}")
return self.fsStoragePath