Bug 776171 - Don't delete cached credentials when having ident from URI, XHR auth didn't work after first time, r=cbiesinger
authorHonza Bambas <honzab.moz@firemni.cz>
Tue, 23 Oct 2012 17:03:49 +0200
changeset 111285 4dc26e9f31899456fcbee2758db97e1def607264
parent 111284 49ce8e5bd309fcd3144c2e1862803b462d26dd06
child 111286 6f1121e69ee9736920f37167aae5d0d257f61ca9
child 111291 0bb8f7bb9347fee6afb2514304eb8a793590a11e
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewerscbiesinger
bugs776171
milestone19.0a1
Bug 776171 - Don't delete cached credentials when having ident from URI, XHR auth didn't work after first time, r=cbiesinger
netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
toolkit/components/passwordmgr/test/Makefile.in
toolkit/components/passwordmgr/test/auth2/Makefile.in
toolkit/components/passwordmgr/test/auth2/authenticate.sjs
toolkit/components/passwordmgr/test/test_bug_776171.html
--- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
+++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
@@ -713,23 +713,25 @@ nsHttpChannelAuthProvider::GetCredential
     sessionStateGrip.swap(sessionState);
     if (NS_FAILED(rv)) return rv;
 
     LOG(("  identity invalid = %d\n", identityInvalid));
 
     if (identityInvalid) {
         if (entry) {
             if (ident->Equals(entry->Identity())) {
-                LOG(("  clearing bad auth cache entry\n"));
-                // ok, we've already tried this user identity, so clear the
-                // corresponding entry from the auth cache.
-                authCache->ClearAuthEntry(scheme.get(), host,
-                                          port, realm.get());
-                entry = nullptr;
-                ident->Clear();
+                if (!identFromURI) {
+                    LOG(("  clearing bad auth cache entry\n"));
+                    // ok, we've already tried this user identity, so clear the
+                    // corresponding entry from the auth cache.
+                    authCache->ClearAuthEntry(scheme.get(), host,
+                                              port, realm.get());
+                    entry = nullptr;
+                    ident->Clear();
+                }
             }
             else if (!identFromURI ||
                      nsCRT::strcmp(ident->User(),
                                    entry->Identity().User()) == 0) {
                 LOG(("  taking identity from auth cache\n"));
                 // the password from the auth cache is more likely to be
                 // correct than the one in the URL.  at least, we know that it
                 // works with the given username.  it is possible for a server
--- a/toolkit/components/passwordmgr/test/Makefile.in
+++ b/toolkit/components/passwordmgr/test/Makefile.in
@@ -8,16 +8,17 @@ topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
 relativesrcdir = @relativesrcdir@
 
 include $(topsrcdir)/config/config.mk
 
 DIRS = \
     browser \
+    auth2 \
     $(NULL)
 
 # Module name for xpcshell tests.
 MODULE = test_passwordmgr
 XPCSHELL_TESTS = unit
 
 # Mochitest tests
 MOCHITEST_FILES = \
@@ -38,16 +39,17 @@ MOCHITEST_FILES = \
     test_bug_227640.html \
     test_bug_242956.html \
     test_bug_360493_1.html \
     test_bug_360493_2.html \
     test_bug_391514.html \
     test_bug_427033.html \
     test_bug_444968.html \
     test_bug_627616.html \
+    test_bug_776171.html \
     test_master_password.html \
     test_master_password_cleanup.html \
     test_maxforms_1.html \
     test_maxforms_2.html \
     test_maxforms_3.html \
     test_notifications.html \
     test_notifications_popup.html \
     test_privbrowsing.html \
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/auth2/Makefile.in
@@ -0,0 +1,17 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH		= ../../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MOCHITEST_FILES = \
+    authenticate.sjs \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
copy from toolkit/components/passwordmgr/test/authenticate.sjs
copy to toolkit/components/passwordmgr/test/auth2/authenticate.sjs
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/test_bug_776171.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=776171
+-->
+<head>
+  <title>Test for Bug 776171</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="startTest()">
+<script class="testbody" type="text/javascript">
+
+/**
+ * This test checks we correctly ignore authentication entry
+ * for a subpath and use creds from the URL when provided when XHR
+ * is used with filled user name and password.
+ *
+ * 1. connect auth2/authenticate.sjs that excepts user1:pass1 password
+ * 2. connect a dummy URL at the same path
+ * 3. connect authenticate.sjs that again expects user1:pass1 password
+ *    in this case, however, we have an entry without an identity
+ *    for this path (that is a parent for auth2 path in the first step)
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+function clearAuthCache()
+{
+  var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
+                             .getService(Components.interfaces.nsIHttpAuthManager);
+  authMgr.clearAll();
+}
+
+function doxhr(URL, user, pass, next)
+{
+  var xhr = new XMLHttpRequest();
+  if (user && pass)
+    xhr.open("POST", URL, true, user, pass);
+  else
+    xhr.open("POST", URL, true);
+  xhr.onload = function()
+  {
+    is(xhr.status, 200, "Got status 200");
+    next();
+  }
+  xhr.onerror = function()
+  {
+    ok(false, "request passed");
+    finishTest();
+  }
+  xhr.send();
+}
+
+function startTest()
+{
+  clearAuthCache();
+  doxhr("auth2/authenticate.sjs?user=user1&pass=pass1&realm=realm1", "user1", "pass1", function() {
+    doxhr("auth2", null, null, function() {
+      doxhr("authenticate.sjs?user=user1&pass=pass1&realm=realm1", "user1", "pass1", finishTest);
+    });
+  });
+}
+
+function finishTest()
+{
+  clearAuthCache();
+  SimpleTest.finish();
+}
+
+</script>
+</body>
+</html>
+