summaryrefslogtreecommitdiffstats
path: root/dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js')
-rw-r--r--dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js165
1 files changed, 165 insertions, 0 deletions
diff --git a/dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js b/dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js
new file mode 100644
index 0000000000..e6b01a0cc0
--- /dev/null
+++ b/dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js
@@ -0,0 +1,165 @@
+/* Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+ChromeUtils.defineESModuleGetters(this, {
+ Downloads: "resource://gre/modules/Downloads.sys.mjs",
+ DownloadsCommon: "resource:///modules/DownloadsCommon.sys.mjs",
+});
+
+const { PromptTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/PromptTestUtils.sys.mjs"
+);
+
+let authPromptModalType = Services.prefs.getIntPref(
+ "prompts.modalType.httpAuth"
+);
+
+const downloadMonitoringView = {
+ _listeners: [],
+ onDownloadAdded(download) {
+ for (let listener of this._listeners) {
+ listener(download);
+ }
+ this._listeners = [];
+ },
+ waitForDownload(listener) {
+ this._listeners.push(listener);
+ },
+};
+
+let SECURE_BASE_URL =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content/",
+ "https://example.com/"
+ ) + "file_auth_download_page.html";
+
+/**
+ * Waits until a download is triggered.
+ * It waits until a prompt is shown,
+ * saves and then accepts the dialog.
+ * @returns {Promise} Resolved once done.
+ */
+
+function shouldTriggerDownload() {
+ return new Promise(res => {
+ downloadMonitoringView.waitForDownload(res);
+ });
+}
+function shouldNotifyDownloadUI() {
+ return new Promise(res => {
+ downloadMonitoringView.waitForDownload(async aDownload => {
+ let { error } = aDownload;
+ if (
+ error.becauseBlockedByReputationCheck &&
+ error.reputationCheckVerdict == Downloads.Error.BLOCK_VERDICT_INSECURE
+ ) {
+ // It's an insecure Download, now Check that it has been cleaned up properly
+ if ((await IOUtils.stat(aDownload.target.path)).size != 0) {
+ throw new Error(`Download target is not empty!`);
+ }
+ if ((await IOUtils.stat(aDownload.target.path)).size != 0) {
+ throw new Error(`Download partFile was not cleaned up properly`);
+ }
+ // Assert that the Referrer is present
+ if (!aDownload.source.referrerInfo) {
+ throw new Error("The Blocked download is missing the ReferrerInfo");
+ }
+
+ res(aDownload);
+ } else {
+ ok(false, "No error for download that was expected to error!");
+ }
+ });
+ });
+}
+
+async function resetDownloads() {
+ // Removes all downloads from the download List
+ const types = new Set();
+ let publicList = await Downloads.getList(Downloads.ALL);
+ let downloads = await publicList.getAll();
+ for (let download of downloads) {
+ if (download.contentType) {
+ types.add(download.contentType);
+ }
+ publicList.remove(download);
+ await download.finalize(true);
+ }
+}
+
+async function runTest(url, link, checkFunction, description) {
+ await resetDownloads();
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+ is(
+ gBrowser.currentURI.schemeIs("https"),
+ true,
+ "Scheme of opened tab should be https"
+ );
+ info("Checking: " + description);
+
+ let checkPromise = checkFunction();
+ // Click the Link to trigger the download
+ SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => {
+ content.document.getElementById(contentLink).click();
+ });
+ // Wait for the auth prompt, enter the login details and close the prompt
+ await PromptTestUtils.handleNextPrompt(
+ gBrowser.selectedBrowser,
+ { modalType: authPromptModalType, promptType: "promptUserAndPass" },
+ { buttonNumClick: 0, loginInput: "user", passwordInput: "pass" }
+ );
+ await checkPromise;
+ ok(true, description);
+ // Close download panel
+ DownloadsPanel.hidePanel();
+ is(DownloadsPanel.panel.state, "closed", "Panel should be closed");
+ await BrowserTestUtils.removeTab(tab);
+}
+
+add_setup(async function () {
+ let list = await Downloads.getList(Downloads.ALL);
+ list.addView(downloadMonitoringView);
+ registerCleanupFunction(() => list.removeView(downloadMonitoringView));
+ // Ensure to delete all cached credentials before running test
+ await new Promise(resolve => {
+ Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, resolve);
+ });
+ await SpecialPowers.pushPrefEnv({
+ set: [["dom.block_download_insecure", true]],
+ });
+});
+//Test description:
+// 1. Open "https://example.com".
+// 2. From "https://example.com" download something, but that download is only available via http
+// and with authentication.
+// 3. Login and start download.
+// 4. Mixed-content blocker blocks download.
+// 5. Unblock download and verify the downloaded file.
+add_task(async function test_auth_download() {
+ await runTest(
+ SECURE_BASE_URL,
+ "insecure",
+ async () => {
+ let [, download] = await Promise.all([
+ shouldTriggerDownload(),
+ shouldNotifyDownloadUI(),
+ ]);
+ await download.unblock();
+ ok(download.error == null, "There should be no error after unblocking");
+ info(
+ "Start download to be able to validate the size and the success of the download"
+ );
+ await download.start();
+ is(
+ download.contentType,
+ "text/html",
+ "File contentType should be correct."
+ );
+ ok(download.succeeded, "Download succeeded!");
+ is(download.target.size, 27, "Download has correct size");
+ },
+ "A locked Download from an auth server should succeeded to Download after a Manual unblock"
+ );
+});