summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/browser_insecureLoginForms.js
blob: 72db7dbe6274bab915c21f266b4115372c794af5 (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

// Load directly from the browser-chrome support files of login tests.
const TEST_URL_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";

/**
 * Waits for the given number of occurrences of InsecureLoginFormsStateChange
 * on the given browser element.
 */
function waitForInsecureLoginFormsStateChange(browser, count) {
  return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange",
                                       false, () => --count == 0);
}

/**
 * Checks the insecure login forms logic for the identity block.
 */
add_task(function* test_simple() {
  yield new Promise(resolve => SpecialPowers.pushPrefEnv({
    "set": [["security.insecure_password.ui.enabled", true]],
  }, resolve));

  for (let [origin, expectWarning] of [
    ["http://example.com", true],
    ["http://127.0.0.1", false],
    ["https://example.com", false],
  ]) {
    let testUrlPath = origin + TEST_URL_PATH;
    let tab = gBrowser.addTab(testUrlPath + "form_basic.html");
    let browser = tab.linkedBrowser;
    yield Promise.all([
      BrowserTestUtils.switchTab(gBrowser, tab),
      BrowserTestUtils.browserLoaded(browser),
      // One event is triggered by pageshow and one by DOMFormHasPassword.
      waitForInsecureLoginFormsStateChange(browser, 2),
    ]);

    let { gIdentityHandler } = gBrowser.ownerGlobal;
    gIdentityHandler._identityBox.click();
    document.getElementById("identity-popup-security-expander").click();

    if (expectWarning) {
      is_element_visible(document.getElementById("connection-icon"));
      let connectionIconImage = gBrowser.ownerGlobal
            .getComputedStyle(document.getElementById("connection-icon"), "")
            .getPropertyValue("list-style-image");
      let securityViewBG = gBrowser.ownerGlobal
            .getComputedStyle(document.getElementById("identity-popup-securityView"), "")
            .getPropertyValue("background-image");
      let securityContentBG = gBrowser.ownerGlobal
            .getComputedStyle(document.getElementById("identity-popup-security-content"), "")
            .getPropertyValue("background-image");
      is(connectionIconImage,
         "url(\"chrome://browser/skin/connection-mixed-active-loaded.svg#icon\")",
         "Using expected icon image in the identity block");
      is(securityViewBG,
         "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
         "Using expected icon image in the Control Center main view");
      is(securityContentBG,
         "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
         "Using expected icon image in the Control Center subview");
      is(Array.filter(document.querySelectorAll("[observes=identity-popup-insecure-login-forms-learn-more]"),
                      element => !is_hidden(element)).length, 1,
         "The 'Learn more' link should be visible once.");
    }

    // Messages should be visible when the scheme is HTTP, and invisible when
    // the scheme is HTTPS.
    is(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
                   element => !is_hidden(element)),
       expectWarning,
       "The relevant messages should be visible or hidden.");

    gIdentityHandler._identityPopup.hidden = true;
    gBrowser.removeTab(tab);
  }
});

/**
 * Checks that the insecure login forms logic does not regress mixed content
 * blocking messages when mixed active content is loaded.
 */
add_task(function* test_mixedcontent() {
  yield new Promise(resolve => SpecialPowers.pushPrefEnv({
    "set": [["security.mixed_content.block_active_content", false]],
  }, resolve));

  // Load the page with the subframe in a new tab.
  let testUrlPath = "://example.com" + TEST_URL_PATH;
  let tab = gBrowser.addTab("https" + testUrlPath + "insecure_test.html");
  let browser = tab.linkedBrowser;
  yield Promise.all([
    BrowserTestUtils.switchTab(gBrowser, tab),
    BrowserTestUtils.browserLoaded(browser),
    // Two events are triggered by pageshow and one by DOMFormHasPassword.
    waitForInsecureLoginFormsStateChange(browser, 3),
  ]);

  assertMixedContentBlockingState(browser, { activeLoaded: true,
                                             activeBlocked: false,
                                             passiveLoaded: false });

  gBrowser.removeTab(tab);
});

/**
 * Checks that insecure window.opener does not trigger a warning.
 */
add_task(function* test_ignoring_window_opener() {
  let newTabURL = "https://example.com" + TEST_URL_PATH + "form_basic.html";
  let path = getRootDirectory(gTestPath)
    .replace("chrome://mochitests/content", "http://example.com");
  let url = path + "insecure_opener.html";

  yield BrowserTestUtils.withNewTab(url, function*(browser) {
    // Clicking the link will spawn a new tab.
    let loaded = BrowserTestUtils.waitForNewTab(gBrowser, newTabURL);
    yield ContentTask.spawn(browser, {}, function() {
      content.document.getElementById("link").click();
    });
    let tab = yield loaded;
    browser = tab.linkedBrowser;
    yield waitForInsecureLoginFormsStateChange(browser, 2);

    // Open the identity popup.
    let { gIdentityHandler } = gBrowser.ownerGlobal;
    gIdentityHandler._identityBox.click();
    document.getElementById("identity-popup-security-expander").click();

    ok(is_visible(document.getElementById("connection-icon")),
       "Connection icon is visible");

    // Assert that the identity indicators are still "secure".
    let connectionIconImage = gBrowser.ownerGlobal
          .getComputedStyle(document.getElementById("connection-icon"))
          .getPropertyValue("list-style-image");
    let securityViewBG = gBrowser.ownerGlobal
          .getComputedStyle(document.getElementById("identity-popup-securityView"))
          .getPropertyValue("background-image");
    let securityContentBG = gBrowser.ownerGlobal
          .getComputedStyle(document.getElementById("identity-popup-security-content"))
          .getPropertyValue("background-image");
    is(connectionIconImage,
       "url(\"chrome://browser/skin/connection-secure.svg\")",
       "Using expected icon image in the identity block");
    is(securityViewBG,
       "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
       "Using expected icon image in the Control Center main view");
    is(securityContentBG,
       "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
       "Using expected icon image in the Control Center subview");

    ok(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
                   element => is_hidden(element)),
       "All messages should be hidden.");

    gIdentityHandler._identityPopup.hidden = true;

    yield BrowserTestUtils.removeTab(tab);
  });
});