browser_identityPopup_HttpsOnlyMode.js (7951B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const HTTPS_ONLY_PERMISSION = "https-only-load-insecure"; 6 const WEBSITE = scheme => `${scheme}://example.com`; 7 8 add_setup(async function () { 9 await SpecialPowers.pushPrefEnv({ 10 set: [["test.wait300msAfterTabSwitch", true]], 11 }); 12 }); 13 14 add_task(async function () { 15 info("Running regular tests"); 16 await runTests(); 17 info("Running tests with view-source: uri"); 18 await runTests({ outerScheme: "view-source" }); 19 }); 20 21 async function runTests(options = {}) { 22 const { outerScheme = "" } = options; 23 const outerSchemePrefix = outerScheme ? outerScheme + ":" : ""; 24 25 await SpecialPowers.pushPrefEnv({ 26 set: [["dom.security.https_only_mode", true]], 27 }); 28 29 // Site is already HTTPS, so the UI should not be visible. 30 await runTest({ 31 name: "No HTTPS-Only UI", 32 initialScheme: outerSchemePrefix + "https", 33 initialPermission: 0, 34 isUiVisible: false, 35 }); 36 37 // Site gets upgraded to HTTPS, so the UI should be visible. 38 // Adding a HTTPS-Only exemption through the menulist should reload the page and 39 // set the permission accordingly. 40 await runTest({ 41 name: "Add HTTPS-Only exemption", 42 initialScheme: outerSchemePrefix + "http", 43 initialPermission: 0, 44 isUiVisible: true, 45 selectPermission: 1, 46 expectReload: true, 47 finalScheme: outerScheme || "https", 48 }); 49 50 // HTTPS-Only Mode is disabled for this site, so the UI should be visible. 51 // Switching HTTPS-Only exemption modes through the menulist should not reload the page 52 // but set the permission accordingly. 53 await runTest({ 54 name: "Switch between HTTPS-Only exemption modes", 55 initialScheme: outerSchemePrefix + "http", 56 initialPermission: 1, 57 isUiVisible: true, 58 selectPermission: 2, 59 expectReload: false, 60 finalScheme: outerScheme || "http", 61 }); 62 63 // HTTPS-Only Mode is disabled for this site, so the UI should be visible. 64 // Disabling HTTPS-Only exemptions through the menulist should reload and upgrade the 65 // page and set the permission accordingly. 66 await runTest({ 67 name: "Remove HTTPS-Only exemption again", 68 initialScheme: outerSchemePrefix + "http", 69 initialPermission: 2, 70 permissionScheme: "http", 71 isUiVisible: true, 72 selectPermission: 0, 73 expectReload: true, 74 finalScheme: outerScheme || "https", 75 }); 76 77 await SpecialPowers.flushPrefEnv(); 78 await SpecialPowers.pushPrefEnv({ 79 set: [["dom.security.https_first", true]], 80 }); 81 82 // Site is already HTTPS, so the UI should not be visible. 83 await runTest({ 84 name: "No HTTPS-Only UI", 85 initialScheme: outerSchemePrefix + "https", 86 initialPermission: 0, 87 permissionScheme: "https", 88 isUiVisible: false, 89 }); 90 91 // Site gets upgraded to HTTPS, so the UI should be visible. 92 // Adding a HTTPS-Only exemption through the menulist should reload the page and 93 // set the permission accordingly. 94 await runTest({ 95 name: "Add HTTPS-Only exemption", 96 initialScheme: outerSchemePrefix + "http", 97 initialPermission: 0, 98 permissionScheme: "https", 99 isUiVisible: true, 100 selectPermission: 1, 101 expectReload: true, 102 finalScheme: outerScheme || "https", 103 }); 104 105 // HTTPS-First Mode is disabled for this site, so the UI should be visible. 106 // Switching HTTPS-Only exemption modes through the menulist should not reload the page 107 // but set the permission accordingly. 108 await runTest({ 109 name: "Switch between HTTPS-Only exemption modes", 110 initialScheme: outerSchemePrefix + "http", 111 initialPermission: 1, 112 permissionScheme: "http", 113 isUiVisible: true, 114 selectPermission: 2, 115 expectReload: false, 116 finalScheme: outerScheme || "http", 117 }); 118 119 // HTTPS-First Mode is disabled for this site, so the UI should be visible. 120 // Disabling HTTPS-Only exemptions through the menulist should reload and upgrade the 121 // page and set the permission accordingly. 122 await runTest({ 123 name: "Remove HTTPS-Only exemption again", 124 initialScheme: outerSchemePrefix + "http", 125 initialPermission: 2, 126 isUiVisible: true, 127 selectPermission: 0, 128 expectReload: true, 129 finalScheme: outerScheme || "https", 130 }); 131 } 132 133 async function runTest(options) { 134 // Set the initial permission 135 setPermission(WEBSITE("http"), options.initialPermission); 136 137 await BrowserTestUtils.withNewTab( 138 WEBSITE(options.initialScheme), 139 async function (browser) { 140 const name = options.name + " | "; 141 142 // Open the identity popup. 143 let { gIdentityHandler } = gBrowser.ownerGlobal; 144 let promisePanelOpen = BrowserTestUtils.waitForEvent( 145 gBrowser.ownerGlobal, 146 "popupshown", 147 true, 148 event => event.target == gIdentityHandler._identityPopup 149 ); 150 gIdentityHandler._identityIconBox.click(); 151 await promisePanelOpen; 152 153 // Check if the HTTPS-Only UI is visible 154 const httpsOnlyUI = document.getElementById( 155 "identity-popup-security-httpsonlymode" 156 ); 157 is( 158 gBrowser.ownerGlobal.getComputedStyle(httpsOnlyUI).display != "none", 159 options.isUiVisible, 160 options.isUiVisible 161 ? name + "HTTPS-Only UI should be visible." 162 : name + "HTTPS-Only UI shouldn't be visible." 163 ); 164 165 // If it's not visible we can't do much else :) 166 if (!options.isUiVisible) { 167 return; 168 } 169 170 // Check if the value of the menulist matches the initial permission 171 const httpsOnlyMenulist = document.getElementById( 172 "identity-popup-security-httpsonlymode-menulist" 173 ); 174 is( 175 parseInt(httpsOnlyMenulist.value, 10), 176 options.initialPermission, 177 name + "Menulist value should match expected permission value." 178 ); 179 180 // Select another HTTPS-Only state and potentially wait for the page to reload 181 if (options.expectReload) { 182 const loaded = BrowserTestUtils.browserLoaded(browser); 183 httpsOnlyMenulist.getItemAtIndex(options.selectPermission).doCommand(); 184 await loaded; 185 } else { 186 httpsOnlyMenulist.getItemAtIndex(options.selectPermission).doCommand(); 187 } 188 189 // Check if the site has the expected scheme 190 is( 191 browser.currentURI.scheme, 192 options.finalScheme, 193 name + "Unexpected scheme after page reloaded." 194 ); 195 196 // Check if the permission was sucessfully changed 197 is( 198 getPermission(WEBSITE("http")), 199 options.selectPermission, 200 name + "Set permission should match the one selected from the menulist." 201 ); 202 } 203 ); 204 205 // Reset permission 206 Services.perms.removeAll(); 207 } 208 209 function setPermission(url, newValue) { 210 let uri = Services.io.newURI(url); 211 let principal = Services.scriptSecurityManager.createContentPrincipal( 212 uri, 213 {} 214 ); 215 if (newValue === 0) { 216 Services.perms.removeFromPrincipal(principal, HTTPS_ONLY_PERMISSION); 217 } else if (newValue === 1) { 218 Services.perms.addFromPrincipal( 219 principal, 220 HTTPS_ONLY_PERMISSION, 221 Ci.nsIHttpsOnlyModePermission.LOAD_INSECURE_ALLOW, 222 Ci.nsIPermissionManager.EXPIRE_NEVER 223 ); 224 } else { 225 Services.perms.addFromPrincipal( 226 principal, 227 HTTPS_ONLY_PERMISSION, 228 Ci.nsIHttpsOnlyModePermission.LOAD_INSECURE_ALLOW_SESSION, 229 Ci.nsIPermissionManager.EXPIRE_SESSION 230 ); 231 } 232 } 233 234 function getPermission(url) { 235 let uri = Services.io.newURI(url); 236 let principal = Services.scriptSecurityManager.createContentPrincipal( 237 uri, 238 {} 239 ); 240 const state = Services.perms.testPermissionFromPrincipal( 241 principal, 242 HTTPS_ONLY_PERMISSION 243 ); 244 switch (state) { 245 case Ci.nsIHttpsOnlyModePermission.LOAD_INSECURE_ALLOW_SESSION: 246 return 2; // Off temporarily 247 case Ci.nsIHttpsOnlyModePermission.LOAD_INSECURE_ALLOW: 248 return 1; // Off 249 default: 250 return 0; // On 251 } 252 }