test_auth_dialog_permission.js (7163B)
1 // This file tests authentication prompt depending on pref 2 // network.auth.subresource-http-auth-allow: 3 // 0 - don't allow sub-resources to open HTTP authentication credentials 4 // dialogs 5 // 1 - allow sub-resources to open HTTP authentication credentials dialogs, 6 // but don't allow it for cross-origin sub-resources 7 // 2 - allow the cross-origin authentication as well. 8 9 "use strict"; 10 11 const { HttpServer } = ChromeUtils.importESModule( 12 "resource://testing-common/httpd.sys.mjs" 13 ); 14 15 var prefs = Services.prefs; 16 17 // Since this test creates a TYPE_DOCUMENT channel via javascript, it will 18 // end up using the wrong LoadInfo constructor. Setting this pref will disable 19 // the ContentPolicyType assertion in the constructor. 20 prefs.setBoolPref("network.loadinfo.skip_type_assertion", true); 21 22 function authHandler(metadata, response) { 23 // btoa("guest:guest"), but that function is not available here 24 var expectedHeader = "Basic Z3Vlc3Q6Z3Vlc3Q="; 25 26 var body; 27 if ( 28 metadata.hasHeader("Authorization") && 29 metadata.getHeader("Authorization") == expectedHeader 30 ) { 31 response.setStatusLine(metadata.httpVersion, 200, "OK, authorized"); 32 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); 33 response.setHeader("Content-Type", "text/javascript", false); 34 35 body = "success"; 36 } else { 37 // didn't know guest:guest, failure 38 response.setStatusLine(metadata.httpVersion, 401, "Unauthorized"); 39 response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false); 40 response.setHeader("Content-Type", "text/javascript", false); 41 42 body = "failed"; 43 } 44 45 response.bodyOutputStream.write(body, body.length); 46 } 47 48 var httpserv = new HttpServer(); 49 httpserv.registerPathHandler("/auth", authHandler); 50 httpserv.start(-1); 51 52 ChromeUtils.defineLazyGetter(this, "URL", function () { 53 return "http://localhost:" + httpserv.identity.primaryPort; 54 }); 55 56 function AuthPrompt(promptExpected) { 57 this.promptExpected = promptExpected; 58 } 59 60 AuthPrompt.prototype = { 61 user: "guest", 62 pass: "guest", 63 64 QueryInterface: ChromeUtils.generateQI(["nsIAuthPrompt"]), 65 66 prompt() { 67 do_throw("unexpected prompt call"); 68 }, 69 70 promptUsernameAndPassword(title, text, realm, savePW, user, pw) { 71 Assert.ok(this.promptExpected, "Not expected the authentication prompt."); 72 73 user.value = this.user; 74 pw.value = this.pass; 75 return true; 76 }, 77 78 promptPassword() { 79 do_throw("unexpected promptPassword call"); 80 }, 81 }; 82 83 function Requestor(promptExpected) { 84 this.promptExpected = promptExpected; 85 } 86 87 Requestor.prototype = { 88 QueryInterface: ChromeUtils.generateQI(["nsIInterfaceRequestor"]), 89 90 getInterface(iid) { 91 if (iid.equals(Ci.nsIAuthPrompt)) { 92 this.prompter = new AuthPrompt(this.promptExpected); 93 return this.prompter; 94 } 95 96 throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); 97 }, 98 99 prompter: null, 100 }; 101 102 function make_uri(url) { 103 return Services.io.newURI(url); 104 } 105 106 function makeChan(loadingUrl, url, contentPolicy) { 107 var uri = make_uri(loadingUrl); 108 var principal = Services.scriptSecurityManager.createContentPrincipal( 109 uri, 110 {} 111 ); 112 113 return NetUtil.newChannel({ 114 uri: url, 115 loadingPrincipal: principal, 116 securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT, 117 contentPolicyType: contentPolicy, 118 }).QueryInterface(Ci.nsIHttpChannel); 119 } 120 121 function Test( 122 subresource_http_auth_allow_pref, 123 loadingUri, 124 uri, 125 contentPolicy, 126 expectedCode 127 ) { 128 this._subresource_http_auth_allow_pref = subresource_http_auth_allow_pref; 129 this._loadingUri = loadingUri; 130 this._uri = uri; 131 this._contentPolicy = contentPolicy; 132 this._expectedCode = expectedCode; 133 } 134 135 Test.prototype = { 136 _subresource_http_auth_allow_pref: 1, 137 _loadingUri: null, 138 _uri: null, 139 _contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER, 140 _expectedCode: 200, 141 142 onStartRequest(request) { 143 try { 144 if (!Components.isSuccessCode(request.status)) { 145 do_throw("Channel should have a success code!"); 146 } 147 148 if (!(request instanceof Ci.nsIHttpChannel)) { 149 do_throw("Expecting an HTTP channel"); 150 } 151 152 Assert.equal(request.responseStatus, this._expectedCode); 153 // The request should be succeeded iff we expect 200 154 Assert.equal(request.requestSucceeded, this._expectedCode == 200); 155 } catch (e) { 156 do_throw("Unexpected exception: " + e); 157 } 158 159 throw Components.Exception("", Cr.NS_ERROR_ABORT); 160 }, 161 162 onDataAvailable() { 163 do_throw("Should not get any data!"); 164 }, 165 166 onStopRequest(request, status) { 167 Assert.equal(status, Cr.NS_ERROR_ABORT); 168 169 // Clear the auth cache. 170 Cc["@mozilla.org/network/http-auth-manager;1"] 171 .getService(Ci.nsIHttpAuthManager) 172 .clearAll(); 173 174 do_timeout(0, run_next_test); 175 }, 176 177 run() { 178 dump( 179 "Run test: " + 180 this._subresource_http_auth_allow_pref + 181 this._loadingUri + 182 this._uri + 183 this._contentPolicy + 184 this._expectedCode + 185 " \n" 186 ); 187 188 prefs.setIntPref( 189 "network.auth.subresource-http-auth-allow", 190 this._subresource_http_auth_allow_pref 191 ); 192 let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy); 193 chan.notificationCallbacks = new Requestor(this._expectedCode == 200); 194 chan.asyncOpen(this); 195 }, 196 }; 197 198 var tests = [ 199 // For the next 3 tests the preference is set to 2 - allow the cross-origin 200 // authentication as well. 201 202 // A cross-origin request. 203 new Test( 204 2, 205 "http://example.com", 206 URL + "/auth", 207 Ci.nsIContentPolicy.TYPE_OTHER, 208 200 209 ), 210 // A non cross-origin sub-resource request. 211 new Test(2, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 200), 212 // A top level document. 213 new Test( 214 2, 215 URL + "/auth", 216 URL + "/auth", 217 Ci.nsIContentPolicy.TYPE_DOCUMENT, 218 200 219 ), 220 221 // For the next 3 tests the preference is set to 1 - allow sub-resources to 222 // open HTTP authentication credentials dialogs, but don't allow it for 223 // cross-origin sub-resources 224 225 // A cross-origin request. 226 new Test( 227 1, 228 "http://example.com", 229 URL + "/auth", 230 Ci.nsIContentPolicy.TYPE_OTHER, 231 401 232 ), 233 // A non cross-origin sub-resource request. 234 new Test(1, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 200), 235 // A top level document. 236 new Test( 237 1, 238 URL + "/auth", 239 URL + "/auth", 240 Ci.nsIContentPolicy.TYPE_DOCUMENT, 241 200 242 ), 243 244 // For the next 3 tests the preference is set to 0 - don't allow sub-resources 245 // to open HTTP authentication credentials dialogs. 246 247 // A cross-origin request. 248 new Test( 249 0, 250 "http://example.com", 251 URL + "/auth", 252 Ci.nsIContentPolicy.TYPE_OTHER, 253 401 254 ), 255 // A sub-resource request. 256 new Test(0, URL + "/", URL + "/auth", Ci.nsIContentPolicy.TYPE_OTHER, 401), 257 // A top level request. 258 new Test( 259 0, 260 URL + "/auth", 261 URL + "/auth", 262 Ci.nsIContentPolicy.TYPE_DOCUMENT, 263 200 264 ), 265 ]; 266 267 function run_next_test() { 268 var nextTest = tests.shift(); 269 if (!nextTest) { 270 httpserv.stop(do_test_finished); 271 return; 272 } 273 274 nextTest.run(); 275 } 276 277 function run_test() { 278 do_test_pending(); 279 run_next_test(); 280 }