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
09d5621e94
commit
688f174edb
@ -54,6 +54,8 @@ const Cr = Components.results;
|
|||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
|
||||||
|
"resource://gre/modules/DownloadIntegration.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||||
"resource://gre/modules/NetUtil.jsm");
|
"resource://gre/modules/NetUtil.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||||
@ -269,6 +271,14 @@ Download.prototype = {
|
|||||||
yield this._promiseCanceled;
|
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 {
|
try {
|
||||||
// Execute the actual download through the saver object.
|
// Execute the actual download through the saver object.
|
||||||
yield this.saver.execute(DS_setProgressBytes.bind(this));
|
yield this.saver.execute(DS_setProgressBytes.bind(this));
|
||||||
@ -541,6 +551,18 @@ DownloadError.prototype = {
|
|||||||
* Indicates an error occurred while writing to the local target.
|
* Indicates an error occurred while writing to the local target.
|
||||||
*/
|
*/
|
||||||
becauseTargetFailed: false,
|
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",
|
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||||
"resource://gre/modules/FileUtils.jsm");
|
"resource://gre/modules/FileUtils.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
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",
|
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||||
"resource://gre/modules/Services.jsm");
|
"resource://gre/modules/Services.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||||
@ -38,6 +40,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
|||||||
XPCOMUtils.defineLazyServiceGetter(this, "env",
|
XPCOMUtils.defineLazyServiceGetter(this, "env",
|
||||||
"@mozilla.org/process/environment;1",
|
"@mozilla.org/process/environment;1",
|
||||||
"nsIEnvironment");
|
"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() {
|
XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
|
||||||
return Services.strings.
|
return Services.strings.
|
||||||
createBundle("chrome://mozapps/locale/downloads/downloads.properties");
|
createBundle("chrome://mozapps/locale/downloads/downloads.properties");
|
||||||
@ -54,6 +64,8 @@ this.DownloadIntegration = {
|
|||||||
// For testing only
|
// For testing only
|
||||||
testMode: false,
|
testMode: false,
|
||||||
dontLoad: false,
|
dontLoad: false,
|
||||||
|
dontCheckParentalControls: false,
|
||||||
|
shouldBlockInTest: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main DownloadStore object for loading and saving the list of persistent
|
* Main DownloadStore object for loading and saving the list of persistent
|
||||||
@ -182,7 +194,6 @@ this.DownloadIntegration = {
|
|||||||
directory = Services.prefs.getComplexValue("browser.download.dir",
|
directory = Services.prefs.getComplexValue("browser.download.dir",
|
||||||
Ci.nsIFile);
|
Ci.nsIFile);
|
||||||
yield OS.File.makeDir(directory.path, { ignoreExisting: true });
|
yield OS.File.makeDir(directory.path, { ignoreExisting: true });
|
||||||
|
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
// Either the preference isn't set or the directory cannot be created.
|
// Either the preference isn't set or the directory cannot be created.
|
||||||
directory = yield this.getSystemDownloadsDirectory();
|
directory = yield this.getSystemDownloadsDirectory();
|
||||||
@ -221,6 +232,34 @@ this.DownloadIntegration = {
|
|||||||
}.bind(this));
|
}.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.
|
* Determines whether it's a Windows Metro app.
|
||||||
*/
|
*/
|
||||||
|
@ -83,6 +83,10 @@ DownloadLegacyTransfer.prototype = {
|
|||||||
onStateChange: function DLT_onStateChange(aWebProgress, aRequest, aStateFlags,
|
onStateChange: function DLT_onStateChange(aWebProgress, aRequest, aStateFlags,
|
||||||
aStatus)
|
aStatus)
|
||||||
{
|
{
|
||||||
|
if (!Components.isSuccessCode(aStatus)) {
|
||||||
|
this._componentFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Detect when the last file has been received, or the download failed.
|
// Detect when the last file has been received, or the download failed.
|
||||||
if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
|
if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
|
||||||
(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
|
(aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
|
||||||
@ -113,6 +117,8 @@ DownloadLegacyTransfer.prototype = {
|
|||||||
// change, but if no network request actually started, it is possible that
|
// change, but if no network request actually started, it is possible that
|
||||||
// we only receive a status change with an error status code.
|
// we only receive a status change with an error status code.
|
||||||
if (!Components.isSuccessCode(aStatus)) {
|
if (!Components.isSuccessCode(aStatus)) {
|
||||||
|
this._componentFailed = true;
|
||||||
|
|
||||||
// Wait for the associated Download object to be available.
|
// Wait for the associated Download object to be available.
|
||||||
this._deferDownload.promise.then(function DLT_OSC_onDownload(aDownload) {
|
this._deferDownload.promise.then(function DLT_OSC_onDownload(aDownload) {
|
||||||
aDownload.saver.onTransferFinished(aRequest, aStatus);
|
aDownload.saver.onTransferFinished(aRequest, aStatus);
|
||||||
@ -160,12 +166,18 @@ DownloadLegacyTransfer.prototype = {
|
|||||||
saver: { type: "legacy" },
|
saver: { type: "legacy" },
|
||||||
}).then(function DLT_I_onDownload(aDownload) {
|
}).then(function DLT_I_onDownload(aDownload) {
|
||||||
// Now that the saver is available, hook up the cancellation handler.
|
// Now that the saver is available, hook up the cancellation handler.
|
||||||
aDownload.saver.deferCanceled.promise
|
aDownload.saver.deferCanceled.promise.then(() => {
|
||||||
.then(function () aCancelable.cancel(Cr.NS_ERROR_ABORT))
|
// Only cancel if the object executing the download is still running.
|
||||||
.then(null, Cu.reportError);
|
if (!this._componentFailed) {
|
||||||
|
aCancelable.cancel(Cr.NS_ERROR_ABORT);
|
||||||
|
}
|
||||||
|
}).then(null, Cu.reportError);
|
||||||
|
|
||||||
// Start the download before allowing it to be controlled.
|
// 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.
|
// Start processing all the other events received through nsITransfer.
|
||||||
this._deferDownload.resolve(aDownload);
|
this._deferDownload.resolve(aDownload);
|
||||||
@ -189,6 +201,13 @@ DownloadLegacyTransfer.prototype = {
|
|||||||
* object associated with this nsITransfer instance, when it is available.
|
* object associated with this nsITransfer instance, when it is available.
|
||||||
*/
|
*/
|
||||||
_deferDownload: null,
|
_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.
|
// Disable integration with the host application requiring profile access.
|
||||||
DownloadIntegration.dontLoad = true;
|
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);
|
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();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that the getTemporaryDownloadsDirectory returns a valid nsFile
|
* Tests that the getTemporaryDownloadsDirectory returns a valid nsFile
|
||||||
* download directory object.
|
* download directory object.
|
||||||
|
@ -353,3 +353,27 @@ add_task(function test_download_public_and_private()
|
|||||||
cleanup();
|
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