mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 852599 - Block downloads when they are disallowed globally by the parental control service. r=paolo
This commit is contained in:
parent
ec52aaa08f
commit
33f3a7b648
@ -54,6 +54,8 @@ const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
|
||||
"resource://gre/modules/DownloadIntegration.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
@ -269,6 +271,14 @@ Download.prototype = {
|
||||
yield this._promiseCanceled;
|
||||
}
|
||||
|
||||
// Disallow download if parental controls service restricts it.
|
||||
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
|
||||
let error = new DownloadError(Cr.NS_ERROR_FAILURE, "Download blocked.");
|
||||
error.becauseBlocked = true;
|
||||
error.becauseBlockedByParentalControls = true;
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
// Execute the actual download through the saver object.
|
||||
yield this.saver.execute(DS_setProgressBytes.bind(this));
|
||||
@ -541,6 +551,18 @@ DownloadError.prototype = {
|
||||
* Indicates an error occurred while writing to the local target.
|
||||
*/
|
||||
becauseTargetFailed: false,
|
||||
|
||||
/**
|
||||
* Indicates the download failed because it was blocked. If the reason for
|
||||
* blocking is known, the corresponding property will be also set.
|
||||
*/
|
||||
becauseBlocked: false,
|
||||
|
||||
/**
|
||||
* Indicates the download was blocked because downloads are globally
|
||||
* disallowed by the Parental Controls or Family Safety features on Windows.
|
||||
*/
|
||||
becauseBlockedByParentalControls: false,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -30,7 +30,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadStore",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm")
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
@ -38,6 +40,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "env",
|
||||
"@mozilla.org/process/environment;1",
|
||||
"nsIEnvironment");
|
||||
XPCOMUtils.defineLazyGetter(this, "gParentalControlsService", function() {
|
||||
if ("@mozilla.org/parental-controls-service;1" in Cc) {
|
||||
return Cc["@mozilla.org/parental-controls-service;1"]
|
||||
.createInstance(Ci.nsIParentalControlsService);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
|
||||
return Services.strings.
|
||||
createBundle("chrome://mozapps/locale/downloads/downloads.properties");
|
||||
@ -54,6 +64,8 @@ this.DownloadIntegration = {
|
||||
// For testing only
|
||||
testMode: false,
|
||||
dontLoad: false,
|
||||
dontCheckParentalControls: false,
|
||||
shouldBlockInTest: false,
|
||||
|
||||
/**
|
||||
* Main DownloadStore object for loading and saving the list of persistent
|
||||
@ -182,7 +194,6 @@ this.DownloadIntegration = {
|
||||
directory = Services.prefs.getComplexValue("browser.download.dir",
|
||||
Ci.nsIFile);
|
||||
yield OS.File.makeDir(directory.path, { ignoreExisting: true });
|
||||
|
||||
} catch(ex) {
|
||||
// Either the preference isn't set or the directory cannot be created.
|
||||
directory = yield this.getSystemDownloadsDirectory();
|
||||
@ -221,6 +232,34 @@ this.DownloadIntegration = {
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks to determine whether to block downloads for parental controls.
|
||||
*
|
||||
* aParam aDownload
|
||||
* The download object.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves The boolean indicates to block downloads or not.
|
||||
*/
|
||||
shouldBlockForParentalControls: function DI_shouldBlockForParentalControls(aDownload) {
|
||||
if (this.dontCheckParentalControls) {
|
||||
return Promise.resolve(this.shouldBlockInTest);
|
||||
}
|
||||
|
||||
let isEnabled = gParentalControlsService &&
|
||||
gParentalControlsService.parentalControlsEnabled;
|
||||
let shouldBlock = isEnabled &&
|
||||
gParentalControlsService.blockFileDownloadsEnabled;
|
||||
|
||||
// Log the event if required by parental controls settings.
|
||||
if (isEnabled && gParentalControlsService.loggingEnabled) {
|
||||
gParentalControlsService.log(gParentalControlsService.ePCLog_FileDownload,
|
||||
shouldBlock, aDownload.source.uri, null);
|
||||
}
|
||||
|
||||
return Promise.resolve(shouldBlock);
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether it's a Windows Metro app.
|
||||
*/
|
||||
|
@ -83,6 +83,10 @@ DownloadLegacyTransfer.prototype = {
|
||||
onStateChange: function DLT_onStateChange(aWebProgress, aRequest, aStateFlags,
|
||||
aStatus)
|
||||
{
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
this._componentFailed = true;
|
||||
}
|
||||
|
||||
// Detect when the last file has been received, or the download failed.
|
||||
if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
|
||||
(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
|
||||
@ -113,6 +117,8 @@ DownloadLegacyTransfer.prototype = {
|
||||
// change, but if no network request actually started, it is possible that
|
||||
// we only receive a status change with an error status code.
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
this._componentFailed = true;
|
||||
|
||||
// Wait for the associated Download object to be available.
|
||||
this._deferDownload.promise.then(function DLT_OSC_onDownload(aDownload) {
|
||||
aDownload.saver.onTransferFinished(aRequest, aStatus);
|
||||
@ -160,12 +166,18 @@ DownloadLegacyTransfer.prototype = {
|
||||
saver: { type: "legacy" },
|
||||
}).then(function DLT_I_onDownload(aDownload) {
|
||||
// Now that the saver is available, hook up the cancellation handler.
|
||||
aDownload.saver.deferCanceled.promise
|
||||
.then(function () aCancelable.cancel(Cr.NS_ERROR_ABORT))
|
||||
.then(null, Cu.reportError);
|
||||
aDownload.saver.deferCanceled.promise.then(() => {
|
||||
// Only cancel if the object executing the download is still running.
|
||||
if (!this._componentFailed) {
|
||||
aCancelable.cancel(Cr.NS_ERROR_ABORT);
|
||||
}
|
||||
}).then(null, Cu.reportError);
|
||||
|
||||
// Start the download before allowing it to be controlled.
|
||||
aDownload.start();
|
||||
aDownload.start().then(null, function () {
|
||||
// In case the operation failed, ensure we stop downloading data.
|
||||
aDownload.saver.deferCanceled.resolve();
|
||||
});
|
||||
|
||||
// Start processing all the other events received through nsITransfer.
|
||||
this._deferDownload.resolve(aDownload);
|
||||
@ -189,6 +201,13 @@ DownloadLegacyTransfer.prototype = {
|
||||
* object associated with this nsITransfer instance, when it is available.
|
||||
*/
|
||||
_deferDownload: null,
|
||||
|
||||
/**
|
||||
* Indicates that the component that executes the download has notified a
|
||||
* failure condition. In this case, we should never use the component methods
|
||||
* that cancel the download.
|
||||
*/
|
||||
_componentFailed: false,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -451,4 +451,6 @@ add_task(function test_common_initialize()
|
||||
|
||||
// Disable integration with the host application requiring profile access.
|
||||
DownloadIntegration.dontLoad = true;
|
||||
// Disable the parental controls checking.
|
||||
DownloadIntegration.dontCheckParentalControls = true;
|
||||
});
|
||||
|
@ -873,3 +873,25 @@ add_task(function test_download_cancel_midway_restart_with_content_encoding()
|
||||
yield promiseVerifyContents(download.target.file, TEST_DATA_SHORT);
|
||||
});
|
||||
|
||||
/**
|
||||
* Download with parental controls enabled.
|
||||
*/
|
||||
add_task(function test_download_blocked_parental_controls()
|
||||
{
|
||||
function cleanup() {
|
||||
DownloadIntegration.shouldBlockInTest = false;
|
||||
}
|
||||
do_register_cleanup(cleanup);
|
||||
DownloadIntegration.shouldBlockInTest = true;
|
||||
|
||||
let download = yield promiseSimpleDownload();
|
||||
|
||||
try {
|
||||
yield download.start();
|
||||
do_throw("The download should have blocked.");
|
||||
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
|
||||
do_check_true(ex.becauseBlockedByParentalControls);
|
||||
}
|
||||
cleanup();
|
||||
});
|
||||
|
||||
|
@ -125,7 +125,6 @@ add_task(function test_getUserDownloadsDirectory()
|
||||
cleanup();
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests that the getTemporaryDownloadsDirectory returns a valid nsFile
|
||||
* download directory object.
|
||||
|
@ -353,3 +353,27 @@ add_task(function test_download_public_and_private()
|
||||
cleanup();
|
||||
});
|
||||
|
||||
/**
|
||||
* Download with parental controls enabled.
|
||||
*/
|
||||
add_task(function test_download_blocked_parental_controls()
|
||||
{
|
||||
function cleanup() {
|
||||
DownloadIntegration.shouldBlockInTest = false;
|
||||
}
|
||||
do_register_cleanup(cleanup);
|
||||
DownloadIntegration.shouldBlockInTest = true;
|
||||
|
||||
let download = yield promiseStartLegacyDownload();
|
||||
|
||||
try {
|
||||
yield download.start();
|
||||
do_throw("The download should have blocked.");
|
||||
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
|
||||
do_check_true(ex.becauseBlockedByParentalControls);
|
||||
}
|
||||
|
||||
do_check_false(download.target.file.exists());
|
||||
|
||||
cleanup();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user