summaryrefslogtreecommitdiffstats
path: root/dom/browser-element/mochitest/browserElement_Auth.js
blob: ef95409be425b7f10b7f773a3980520de173a0f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/* Any copyright is dedicated to the public domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

// Test that auth prompt works.
"use strict";

SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();

const { NetUtil } = SpecialPowers.Cu.import('resource://gre/modules/NetUtil.jsm');

function testFail(msg) {
  ok(false, JSON.stringify(msg));
}

var iframe;

function runTest() {
  iframe = document.createElement('iframe');
  iframe.setAttribute('mozbrowser', 'true');
  document.body.appendChild(iframe);

  // Wait for the initial load to finish, then navigate the page, then start test
  // by loading SJS with http 401 response.
  iframe.addEventListener('mozbrowserloadend', function loadend() {
    iframe.removeEventListener('mozbrowserloadend', loadend);
    iframe.addEventListener('mozbrowserusernameandpasswordrequired', testHttpAuthCancel);
    SimpleTest.executeSoon(function() {
      // Use absolute path because we need to specify host.
      iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
    });
  });
}

function testHttpAuthCancel(e) {
  iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testHttpAuthCancel);
  // Will cancel authentication, but prompt should not be shown again. Instead,
  // we will be led to fail message
  iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
  iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
    iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
    iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
    is(e.detail, 'http auth failed', 'expected authentication to fail');
    iframe.addEventListener('mozbrowserusernameandpasswordrequired', testHttpAuth);
    SimpleTest.executeSoon(function() {
      // Use absolute path because we need to specify host.
      iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
    });
  });

  is(e.detail.realm, 'http_realm', 'expected realm matches');
  is(e.detail.host, 'http://test', 'expected host matches');
  is(e.detail.path,
     '/tests/dom/browser-element/mochitest/file_http_401_response.sjs',
     'expected path matches');
  e.preventDefault();

  SimpleTest.executeSoon(function() {
    e.detail.cancel();
  });
}

function testHttpAuth(e) {
  iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testHttpAuth);

  // Will authenticate with correct password, prompt should not be
  // called again.
  iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
  iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
    iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
    iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
    is(e.detail, 'http auth success', 'expect authentication to succeed');
    SimpleTest.executeSoon(testProxyAuth);
  });

  is(e.detail.realm, 'http_realm', 'expected realm matches');
  is(e.detail.host, 'http://test', 'expected host matches');
  is(e.detail.path,
     '/tests/dom/browser-element/mochitest/file_http_401_response.sjs',
     'expected path matches');
  is(e.detail.isProxy, false, 'expected isProxy is false');
  e.preventDefault();

  SimpleTest.executeSoon(function() {
    e.detail.authenticate("httpuser", "httppass");
  });
}

function testProxyAuth(e) {
  // The testingSJS simulates the 407 proxy authentication required response
  // for proxy server, which will trigger the browser element to send prompt
  // event with proxy infomation.
  var testingSJS = 'http://test/tests/dom/browser-element/mochitest/file_http_407_response.sjs';
  var mozproxy;

  function onUserNameAndPasswordRequired(e) {
    iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
                               onUserNameAndPasswordRequired);
    iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
      iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
      iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
      is(e.detail, 'http auth success', 'expect authentication to succeed');
      SimpleTest.executeSoon(testAuthJarNoInterfere);
    });

    is(e.detail.realm, 'http_realm', 'expected realm matches');
    is(e.detail.host, mozproxy, 'expected host matches');
    is(e.detail.path,
       '/tests/dom/browser-element/mochitest/file_http_407_response.sjs',
       'expected path matches');
    is(e.detail.isProxy, true, 'expected isProxy is true');
    e.preventDefault();

    SimpleTest.executeSoon(function() {
      e.detail.authenticate("proxyuser", "proxypass");
    });
  }

  // Resolve proxy information used by the test suite, we need it to validate
  // whether the proxy information delivered with the prompt event is correct.
  var resolveCallback = SpecialPowers.wrapCallbackObject({
    QueryInterface: function (iid) {
      const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];

      if (!interfaces.some( function(v) { return iid.equals(v) } )) {
        throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
      }
      return this;
    },

    onProxyAvailable: function (req, channel, pi, status) {
      isnot(pi, null, 'expected proxy information available');
      if (pi) {
        mozproxy = "moz-proxy://" + pi.host + ":" + pi.port;
      }
      iframe.addEventListener("mozbrowserusernameandpasswordrequired",
                              onUserNameAndPasswordRequired);

      iframe.src = testingSJS;
    }
  });

  var channel = NetUtil.newChannel({
    uri: testingSJS,
    loadUsingSystemPrincipal: true
  });

  var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"]
            .getService();

  pps.asyncResolve(channel, 0, resolveCallback);
}

function testAuthJarNoInterfere(e) {
  var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
    .getService(SpecialPowers.Ci.nsIHttpAuthManager);
  var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
               .getService(SpecialPowers.Ci.nsIScriptSecurityManager);
  var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
                  .getService(SpecialPowers.Ci.nsIIOService);
  var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs", null, null);

  // Set a bunch of auth data that should not conflict with the correct auth data already
  // stored in the cache.
  var attrs = {appId: 1};
  var principal = secMan.createCodebasePrincipal(uri, attrs);
  authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
                          'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
                          '', 'httpuser', 'wrongpass', false, principal);
  attrs = {appId: 1, inIsolatedMozBrowser: true};
  principal = secMan.createCodebasePrincipal(uri, attrs);
  authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
                          'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
                          '', 'httpuser', 'wrongpass', false, principal);
  principal = secMan.createCodebasePrincipal(uri, {});
  authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
                          'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
                          '', 'httpuser', 'wrongpass', false, principal);

  // Will authenticate with correct password, prompt should not be
  // called again.
  iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
  iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
    iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
    iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
    is(e.detail, 'http auth success', 'expected authentication success');
    SimpleTest.executeSoon(testAuthJarInterfere);
  });

  // Once more with feeling. Ensure that our new auth data doesn't interfere with this mozbrowser's
  // auth data.
  iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
}

function testAuthJarInterfere(e) {
  var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
    .getService(SpecialPowers.Ci.nsIHttpAuthManager);
  var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
               .getService(SpecialPowers.Ci.nsIScriptSecurityManager);
  var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
                  .getService(SpecialPowers.Ci.nsIIOService);
  var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs", null, null);

  // Set some auth data that should overwrite the successful stored details.
  var principal = secMan.createCodebasePrincipal(uri, {inIsolatedMozBrowser: true});
  authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
                          'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
                          '', 'httpuser', 'wrongpass', false, principal);

  // Will authenticate with correct password, prompt should not be
  // called again.
  var gotusernamepasswordrequired = false;
  function onUserNameAndPasswordRequired() {
      gotusernamepasswordrequired = true;
  }
  iframe.addEventListener("mozbrowserusernameandpasswordrequired",
                          onUserNameAndPasswordRequired);
  iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
    iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
    iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
                               onUserNameAndPasswordRequired);
    ok(gotusernamepasswordrequired,
       "Should have dispatched mozbrowserusernameandpasswordrequired event");
    testFinish();
  });

  // Once more with feeling. Ensure that our new auth data interferes with this mozbrowser's
  // auth data.
  iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
}

function testFinish() {
  // Clear login information stored in password manager.
  var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
    .getService(SpecialPowers.Ci.nsIHttpAuthManager);
  authMgr.clearAll();

  var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"]
    .getService(SpecialPowers.Ci.nsILoginManager);
  pwmgr.removeAllLogins();

  SimpleTest.finish();
}

addEventListener('testready', runTest);