Bug 814247 - Add auth cache jars for separate apps. r=mayhemer

This commit is contained in:
Josh Matthews 2012-12-05 02:33:20 -05:00
parent 68a13d6a9f
commit fbf5889d74
9 changed files with 341 additions and 26 deletions

View File

@ -40,7 +40,7 @@ function testHttpAuthCancel(e) {
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(e.detail, 'http auth failed');
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.
@ -48,8 +48,8 @@ function testHttpAuthCancel(e) {
});
});
is(e.detail.realm, 'http_realm');
is(e.detail.host, 'http://test');
is(e.detail.realm, 'http_realm', 'expected realm matches');
is(e.detail.host, 'http://test', 'expected host matches');
e.preventDefault();
SimpleTest.executeSoon(function() {
@ -66,12 +66,12 @@ function testHttpAuth(e) {
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
is(e.detail, 'http auth success');
SimpleTest.executeSoon(testFinish);
is(e.detail, 'http auth success', 'expect authentication to succeed');
SimpleTest.executeSoon(testAuthJarNoInterfere);
});
is(e.detail.realm, 'http_realm');
is(e.detail.host, 'http://test');
is(e.detail.realm, 'http_realm', 'expected realm matches');
is(e.detail.host, 'http://test', 'expected host matches');
e.preventDefault();
SimpleTest.executeSoon(function() {
@ -79,7 +79,77 @@ function testHttpAuth(e) {
});
}
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 principal = secMan.getAppCodebasePrincipal(uri, 1, false);
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
'', 'httpuser', 'wrongpass', false, principal);
principal = secMan.getAppCodebasePrincipal(uri, 1, true);
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
'', 'httpuser', 'wrongpass', false, principal);
principal = secMan.getAppCodebasePrincipal(uri, secMan.NO_APP_ID, false);
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.getAppCodebasePrincipal(uri, secMan.NO_APP_ID, 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.
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFinish);
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
SimpleTest.execute(testFail);
});
// 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() {
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
// Clear login information stored in password manager.
var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
.getService(SpecialPowers.Ci.nsIHttpAuthManager);

View File

@ -2771,12 +2771,16 @@ _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
bool authPrivate = false;
GetPrivacyFromNPP(instance, &authPrivate);
nsIDocument *doc = GetDocumentFromNPP(instance);
NS_ENSURE_TRUE(doc, NPERR_GENERIC_ERROR);
nsIPrincipal *principal = doc->NodePrincipal();
nsAutoString unused, uname16, pwd16;
if (NS_FAILED(authManager->GetAuthIdentity(proto, nsDependentCString(host),
port, nsDependentCString(scheme),
nsDependentCString(realm),
EmptyCString(), unused, uname16,
pwd16, authPrivate))) {
pwd16, authPrivate, principal))) {
return NPERR_GENERIC_ERROR;
}

View File

@ -9,11 +9,20 @@
#include "nsString.h"
#include "nsCRT.h"
#include "prprf.h"
#include "mozIApplicationClearPrivateDataParams.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "nsNetUtil.h"
static inline void
GetAuthKey(const char *scheme, const char *host, int32_t port, nsCString &key)
GetAuthKey(const char *scheme, const char *host, int32_t port, uint32_t appId, bool inBrowserElement, nsCString &key)
{
key.Assign(scheme);
key.Truncate();
key.AppendInt(appId);
key.Append(':');
key.AppendInt(inBrowserElement);
key.Append(':');
key.Append(scheme);
key.AppendLiteral("://");
key.Append(host);
key.Append(':');
@ -41,13 +50,23 @@ StrEquivalent(const PRUnichar *a, const PRUnichar *b)
nsHttpAuthCache::nsHttpAuthCache()
: mDB(nullptr)
, mObserver(new AppDataClearObserver(this))
{
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->AddObserver(mObserver, "webapps-clear-data", false);
}
}
nsHttpAuthCache::~nsHttpAuthCache()
{
if (mDB)
ClearAll();
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->RemoveObserver(mObserver, "webapps-clear-data");
mObserver->mOwner = nullptr;
}
}
nsresult
@ -71,13 +90,15 @@ nsHttpAuthCache::GetAuthEntryForPath(const char *scheme,
const char *host,
int32_t port,
const char *path,
uint32_t appId,
bool inBrowserElement,
nsHttpAuthEntry **entry)
{
LOG(("nsHttpAuthCache::GetAuthEntryForPath [key=%s://%s:%d path=%s]\n",
scheme, host, port, path));
nsAutoCString key;
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
if (!node)
return NS_ERROR_NOT_AVAILABLE;
@ -90,6 +111,8 @@ nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
const char *host,
int32_t port,
const char *realm,
uint32_t appId,
bool inBrowserElement,
nsHttpAuthEntry **entry)
{
@ -97,7 +120,7 @@ nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
scheme, host, port, realm));
nsAutoCString key;
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
if (!node)
return NS_ERROR_NOT_AVAILABLE;
@ -113,6 +136,8 @@ nsHttpAuthCache::SetAuthEntry(const char *scheme,
const char *realm,
const char *creds,
const char *challenge,
uint32_t appId,
bool inBrowserElement,
const nsHttpAuthIdentity *ident,
nsISupports *metadata)
{
@ -127,7 +152,7 @@ nsHttpAuthCache::SetAuthEntry(const char *scheme,
}
nsAutoCString key;
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
if (!node) {
// create a new entry node and set the given entry
@ -149,13 +174,15 @@ void
nsHttpAuthCache::ClearAuthEntry(const char *scheme,
const char *host,
int32_t port,
const char *realm)
const char *realm,
uint32_t appId,
bool inBrowserElement)
{
if (!mDB)
return;
nsAutoCString key;
GetAuthKey(scheme, host, port, key);
GetAuthKey(scheme, host, port, appId, inBrowserElement, key);
PL_HashTableRemove(mDB, key.get());
}
@ -179,12 +206,14 @@ nsHttpAuthNode *
nsHttpAuthCache::LookupAuthNode(const char *scheme,
const char *host,
int32_t port,
uint32_t appId,
bool inBrowserElement,
nsCString &key)
{
if (!mDB)
return nullptr;
GetAuthKey(scheme, host, port, key);
GetAuthKey(scheme, host, port, appId, inBrowserElement, key);
return (nsHttpAuthNode *) PL_HashTableLookup(mDB, key.get());
}
@ -232,6 +261,62 @@ PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
nsHttpAuthCache::FreeEntry
};
NS_IMPL_ISUPPORTS1(nsHttpAuthCache::AppDataClearObserver, nsIObserver)
NS_IMETHODIMP
nsHttpAuthCache::AppDataClearObserver::Observe(nsISupports *subject,
const char * topic,
const PRUnichar * data_unicode)
{
NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_AVAILABLE);
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
do_QueryInterface(subject);
if (!params) {
NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
return NS_ERROR_UNEXPECTED;
}
uint32_t appId;
bool browserOnly;
nsresult rv = params->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
rv = params->GetBrowserOnly(&browserOnly);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(appId != NECKO_UNKNOWN_APP_ID);
mOwner->ClearAppData(appId, browserOnly);
return NS_OK;
}
static int
RemoveEntriesForApp(PLHashEntry *entry, int32_t number, void *arg)
{
nsDependentCString key(static_cast<const char*>(entry->key));
nsAutoCString* prefix = static_cast<nsAutoCString*>(arg);
if (StringBeginsWith(key, *prefix)) {
return HT_ENUMERATE_NEXT | HT_ENUMERATE_REMOVE;
}
return HT_ENUMERATE_NEXT;
}
void
nsHttpAuthCache::ClearAppData(uint32_t appId, bool browserOnly)
{
if (!mDB) {
return;
}
nsAutoCString keyPrefix;
keyPrefix.AppendInt(appId);
keyPrefix.Append(':');
if (browserOnly) {
keyPrefix.AppendInt(browserOnly);
keyPrefix.Append(':');
}
PL_HashTableEnumerateEntries(mDB, RemoveEntriesForApp, &keyPrefix);
}
//-----------------------------------------------------------------------------
// nsHttpAuthIdentity
//-----------------------------------------------------------------------------

View File

@ -15,6 +15,8 @@
#include "nsCOMPtr.h"
#include "plhash.h"
#include "nsCRT.h"
#include "nsIObserver.h"
struct nsHttpAuthPath {
@ -180,6 +182,8 @@ public:
const char *host,
int32_t port,
const char *path,
uint32_t appId,
bool inBrowserElement,
nsHttpAuthEntry **entry);
// |scheme|, |host|, and |port| are required
@ -189,6 +193,8 @@ public:
const char *host,
int32_t port,
const char *realm,
uint32_t appId,
bool inBrowserElement,
nsHttpAuthEntry **entry);
// |scheme|, |host|, and |port| are required
@ -203,13 +209,17 @@ public:
const char *realm,
const char *credentials,
const char *challenge,
uint32_t appId,
bool inBrowserElement,
const nsHttpAuthIdentity *ident,
nsISupports *metadata);
void ClearAuthEntry(const char *scheme,
const char *host,
int32_t port,
const char *realm);
const char *realm,
uint32_t appId,
bool inBrowserElement);
// expire all existing auth list entries including proxy auths.
nsresult ClearAll();
@ -218,6 +228,8 @@ private:
nsHttpAuthNode *LookupAuthNode(const char *scheme,
const char *host,
int32_t port,
uint32_t appId,
bool inBrowserElement,
nsCString &key);
// hash table allocation functions
@ -227,9 +239,21 @@ private:
static void FreeEntry(void *, PLHashEntry *he, unsigned flag);
static PLHashAllocOps gHashAllocOps;
class AppDataClearObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
AppDataClearObserver(nsHttpAuthCache* aOwner) : mOwner(aOwner) {}
virtual ~AppDataClearObserver() {}
nsHttpAuthCache* mOwner;
};
void ClearAppData(uint32_t appId, bool browserOnly);
private:
PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
nsRefPtr<AppDataClearObserver> mObserver;
};
#endif // nsHttpAuthCache_h__

View File

@ -8,6 +8,7 @@
#include "nsHttpAuthManager.h"
#include "nsReadableUtils.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
NS_IMPL_ISUPPORTS1(nsHttpAuthManager, nsIHttpAuthManager)
@ -56,22 +57,32 @@ nsHttpAuthManager::GetAuthIdentity(const nsACString & aScheme,
nsAString & aUserDomain,
nsAString & aUserName,
nsAString & aUserPassword,
bool aIsPrivate)
bool aIsPrivate,
nsIPrincipal* aPrincipal)
{
nsHttpAuthCache* auth_cache = aIsPrivate ? mPrivateAuthCache : mAuthCache;
nsHttpAuthEntry * entry = nullptr;
nsresult rv;
uint32_t appId = NECKO_NO_APP_ID;
bool inBrowserElement = false;
if (aPrincipal) {
appId = aPrincipal->GetAppId();
inBrowserElement = aPrincipal->GetIsInBrowserElement();
}
if (!aPath.IsEmpty())
rv = auth_cache->GetAuthEntryForPath(PromiseFlatCString(aScheme).get(),
PromiseFlatCString(aHost).get(),
aPort,
PromiseFlatCString(aPath).get(),
appId, inBrowserElement,
&entry);
else
rv = auth_cache->GetAuthEntryForDomain(PromiseFlatCString(aScheme).get(),
PromiseFlatCString(aHost).get(),
aPort,
PromiseFlatCString(aRealm).get(),
appId, inBrowserElement,
&entry);
if (NS_FAILED(rv))
@ -95,12 +106,20 @@ nsHttpAuthManager::SetAuthIdentity(const nsACString & aScheme,
const nsAString & aUserDomain,
const nsAString & aUserName,
const nsAString & aUserPassword,
bool aIsPrivate)
bool aIsPrivate,
nsIPrincipal* aPrincipal)
{
nsHttpAuthIdentity ident(PromiseFlatString(aUserDomain).get(),
PromiseFlatString(aUserName).get(),
PromiseFlatString(aUserPassword).get());
uint32_t appId = NECKO_NO_APP_ID;
bool inBrowserElement = false;
if (aPrincipal) {
appId = aPrincipal->GetAppId();
inBrowserElement = aPrincipal->GetIsInBrowserElement();
}
nsHttpAuthCache* auth_cache = aIsPrivate ? mPrivateAuthCache : mAuthCache;
return auth_cache->SetAuthEntry(PromiseFlatCString(aScheme).get(),
PromiseFlatCString(aHost).get(),
@ -109,6 +128,7 @@ nsHttpAuthManager::SetAuthIdentity(const nsACString & aScheme,
PromiseFlatCString(aRealm).get(),
nullptr, // credentials
nullptr, // challenge
appId, inBrowserElement,
&ident,
nullptr); // metadata
}

View File

@ -20,6 +20,23 @@
#include "nsIDNSService.h"
#include "nsNetCID.h"
#include "nsIDNSRecord.h"
#include "nsNetUtil.h"
static void
GetAppIdAndBrowserStatus(nsIChannel* aChan, uint32_t* aAppId, bool* aInBrowserElem)
{
nsCOMPtr<nsILoadContext> loadContext;
if (aChan) {
NS_QueryNotificationCallbacks(aChan, loadContext);
}
if (!loadContext) {
*aAppId = NECKO_NO_APP_ID;
*aInBrowserElem = false;
} else {
loadContext->GetAppId(aAppId);
loadContext->GetIsInBrowserElement(aInBrowserElem);
}
}
nsHttpChannelAuthProvider::nsHttpChannelAuthProvider()
: mAuthChannel(nullptr)
@ -372,6 +389,11 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
// this getter never fails
nsHttpAuthCache *authCache = gHttpHandler->AuthCache(mIsPrivate);
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
uint32_t appId;
bool isInBrowserElement;
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
// create a cache entry. we do this even though we don't yet know that
// these credentials are valid b/c we need to avoid prompting the user
// more than once in case the credentials are valid.
@ -381,6 +403,7 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
saveCreds ? *result : nullptr,
saveChallenge ? challenge : nullptr,
appId, isInBrowserElement,
saveIdentity ? &ident : nullptr,
sessionState);
return rv;
@ -694,6 +717,11 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
uint32_t appId;
bool isInBrowserElement;
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
//
// if we already tried some credentials for this transaction, then
// we need to possibly clear them from the cache, unless the credentials
@ -702,7 +730,8 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
//
nsHttpAuthEntry *entry = nullptr;
authCache->GetAuthEntryForDomain(scheme.get(), host, port,
realm.get(), &entry);
realm.get(), appId,
isInBrowserElement, &entry);
// hold reference to the auth session state (in case we clear our
// reference to the entry).
@ -732,7 +761,8 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
// 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());
port, realm.get(),
appId, isInBrowserElement);
entry = nullptr;
ident->Clear();
}
@ -1057,10 +1087,17 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthAvailable(nsISupports *aContext,
nsAutoCString realm;
ParseRealm(mCurrentChallenge.get(), realm);
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
uint32_t appId;
bool isInBrowserElement;
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
nsHttpAuthCache *authCache = gHttpHandler->AuthCache(mIsPrivate);
nsHttpAuthEntry *entry = nullptr;
authCache->GetAuthEntryForDomain(scheme.get(), host, port,
realm.get(), &entry);
realm.get(), appId,
isInBrowserElement,
&entry);
nsCOMPtr<nsISupports> sessionStateGrip;
if (entry)
@ -1292,7 +1329,13 @@ nsHttpChannelAuthProvider::SetAuthorizationHeader(nsHttpAuthCache *authCache,
continuationState = &mAuthContinuationState;
}
rv = authCache->GetAuthEntryForPath(scheme, host, port, path, &entry);
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
uint32_t appId;
bool isInBrowserElement;
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
rv = authCache->GetAuthEntryForPath(scheme, host, port, path,
appId, isInBrowserElement, &entry);
if (NS_SUCCEEDED(rv)) {
// if we are trying to add a header for origin server auth and if the
// URL contains an explicit username, then try the given username first.

View File

@ -5,6 +5,8 @@
#include "nsISupports.idl"
interface nsIPrincipal;
/**
* nsIHttpAuthManager
*
@ -19,7 +21,7 @@
* Java client fetches content from a HTTP site that the user
* has already logged into.
*/
[scriptable, uuid(1301b517-ac72-48f6-a781-70c196eaaf3d)]
[scriptable, uuid(54f90444-c52b-4d2d-8916-c59a2bb25938)]
interface nsIHttpAuthManager : nsISupports
{
/**
@ -45,6 +47,12 @@ interface nsIHttpAuthManager : nsISupports
* return value containing user name.
* @param aUserPassword
* return value containing user password.
* @param aIsPrivate
* whether to look up a private or public identity (they are
* stored separately, for use by private browsing)
* @param aPrincipal
* the principal from which to derive information about which
* app/mozbrowser is in use for this request
*/
void getAuthIdentity(in ACString aScheme,
in ACString aHost,
@ -55,7 +63,8 @@ interface nsIHttpAuthManager : nsISupports
out AString aUserDomain,
out AString aUserName,
out AString aUserPassword,
[optional] in bool aIsPrivate);
[optional] in bool aIsPrivate,
[optional] in nsIPrincipal aPrincipal);
/**
* Store auth identity.
@ -80,6 +89,12 @@ interface nsIHttpAuthManager : nsISupports
* optional string containing user name.
* @param aUserPassword
* optional string containing user password.
* @param aIsPrivate
* whether to store a private or public identity (they are
* stored separately, for use by private browsing)
* @param aPrincipal
* the principal from which to derive information about which
* app/mozbrowser is in use for this request
*/
void setAuthIdentity(in ACString aScheme,
in ACString aHost,
@ -90,7 +105,8 @@ interface nsIHttpAuthManager : nsISupports
in AString aUserDomain,
in AString aUserName,
in AString aUserPassword,
[optional] in boolean aIsPrivate);
[optional] in boolean aIsPrivate,
[optional] in nsIPrincipal aPrincipal);
/**
* Clear all auth cache.

View File

@ -0,0 +1,52 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function createURI(s) {
let service = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return service.newURI(s, null, null);
}
function run_test() {
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
const kURI1 = "http://example.com";
var app1 = secMan.getAppCodebasePrincipal(createURI(kURI1), 1, false);
var app10 = secMan.getAppCodebasePrincipal(createURI(kURI1), 10, false);
var app1browser = secMan.getAppCodebasePrincipal(createURI(kURI1), 1, true);
var am = Cc["@mozilla.org/network/http-auth-manager;1"].
getService(Ci.nsIHttpAuthManager);
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user", "pass", false, app1);
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user3", "pass3", false, app1browser);
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user2", "pass2", false, app10);
let subject = {
appId: 1,
browserOnly: true,
QueryInterface: XPCOMUtils.generateQI([Ci.mozIApplicationClearPrivateDataParams])
};
Services.obs.notifyObservers(subject, "webapps-clear-data", null);
var domain = {value: ""}, user = {value: ""}, pass = {value: ""};
try {
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app1browser);
do_check_false(true); // no identity should be present
} catch (x) {
do_check_eq(domain.value, "");
do_check_eq(user.value, "");
do_check_eq(pass.value, "");
}
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app1);
do_check_eq(domain.value, "example.com");
do_check_eq(user.value, "user");
do_check_eq(pass.value, "pass");
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app10);
do_check_eq(domain.value, "example.com");
do_check_eq(user.value, "user2");
do_check_eq(pass.value, "pass2");
}

View File

@ -9,6 +9,7 @@ tail =
[test_URIs.js]
[test_aboutblank.js]
[test_assoc.js]
[test_auth_jar.js]
[test_auth_proxy.js]
[test_authentication.js]
# Bug 675039: test hangs consistently on Android