Bug 1165162 - Serialize originSuffix into .origin. r=gabor,sr=sicking

We also provide an opt-out for the original behavior, and use it in various
consumers that look like they need fixing up. Most of the usage here is in
code with persistence considerations, where we may need some sort of migration
path.
This commit is contained in:
Bobby Holley 2015-05-14 16:55:52 -07:00
parent 6ce4cb3e90
commit 17dddddb65
11 changed files with 50 additions and 29 deletions

View File

@ -74,7 +74,7 @@ let SessionStorageInternal = {
// Get the root domain of the current history entry
// and use that as a key for the per-host storage data.
let origin = principal.jarPrefix + principal.origin;
let origin = principal.jarPrefix + principal.originNoSuffix;
if (visitedOrigins.has(origin)) {
// Don't read a host twice.
return;

View File

@ -56,6 +56,17 @@ OriginAttributes::Deserialize(nsIObjectInputStream* aStream)
NS_IMETHODIMP
BasePrincipal::GetOrigin(nsACString& aOrigin)
{
nsresult rv = GetOriginInternal(aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString suffix;
mOriginAttributes.CreateSuffix(suffix);
aOrigin.Append(suffix);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
{
return GetOriginInternal(aOrigin);
}

View File

@ -63,6 +63,7 @@ public:
bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;

View File

@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, builtinclass, uuid(74fb6760-4ae7-4ec7-8ac7-06817c60a93a)]
[scriptable, builtinclass, uuid(147839d5-e799-4280-831a-dd45946385f9)]
interface nsIPrincipal : nsISerializable
{
/**
@ -65,15 +65,6 @@ interface nsIPrincipal : nsISerializable
*/
[noscript] attribute nsIURI domain;
/**
* The origin of this principal's codebase URI.
* An origin is defined as: scheme + host + port.
*/
// XXXcaa this should probably be turned into an nsIURI.
// The system principal's origin should be some caps namespace
// with a chrome URI. All of chrome should probably be the same.
readonly attribute ACString origin;
/**
* Returns whether the other principal is equal to or weaker than this
* principal. Principals are equal if they are the same object or they
@ -174,6 +165,24 @@ interface nsIPrincipal : nsISerializable
[implicit_jscontext]
readonly attribute jsval originAttributes;
/**
* A canonical representation of the origin for this principal. This
* consists of a base string (which, for codebase principals, is of the
* format scheme://host:port), concatenated with |originAttributes| (see
* below).
*
* We maintain the invariant that principalA.equals(principalB) if and only
* if principalA.origin == principalB.origin.
*/
readonly attribute ACString origin;
/**
* The base part of |origin| without the concatenation with |originSuffix|.
* This doesn't have the important invariants described above with |origin|,
* and as such should only be used for legacy situations.
*/
readonly attribute ACString originNoSuffix;
/**
* A string of the form !key1=value1&key2=value2, where each pair represents
* an attribute with a non-default value. If all attributes have default

View File

@ -983,7 +983,7 @@ BluetoothAdapter::IsBluetoothCertifiedApp()
nsAutoCString appOrigin;
doc->NodePrincipal()->GetAppStatus(&appStatus);
doc->NodePrincipal()->GetOrigin(appOrigin);
doc->NodePrincipal()->GetOriginNoSuffix(appOrigin);
return appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
appOrigin.EqualsLiteral(BLUETOOTH_APP_ORIGIN);

View File

@ -33,7 +33,7 @@ ManagerId::Create(nsIPrincipal* aPrincipal, ManagerId** aManagerIdOut)
// TODO: consider using QuotaManager's modified origin here (bug 1112071)
nsAutoCString origin;
nsresult rv = aPrincipal->GetOrigin(origin);
nsresult rv = aPrincipal->GetOriginNoSuffix(origin);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
uint32_t appId;

View File

@ -150,7 +150,7 @@ PrincipalVerifier::VerifyOnMainThread()
// is a synthetic [System Principal] string.
if (!ssm->IsSystemPrincipal(principal)) {
nsAutoCString origin;
rv = principal->GetOrigin(origin);
rv = principal->GetOriginNoSuffix(origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
DispatchToInitiatingThread(rv);
return;

View File

@ -2636,7 +2636,7 @@ QuotaManager::GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
}
nsCString origin;
rv = aPrincipal->GetOrigin(origin);
rv = aPrincipal->GetOriginNoSuffix(origin);
NS_ENSURE_SUCCESS(rv, rv);
if (origin.EqualsLiteral(kChromeOrigin)) {

View File

@ -209,7 +209,7 @@ this.RequestSyncService = {
principalToKey: function(aPrincipal) {
return aPrincipal.appId + '|' +
aPrincipal.isInBrowserElement + '|' +
aPrincipal.origin;
aPrincipal.originNoSuffix;
},
// Add a task to the _registrations map and create the timer if it's needed.
@ -385,7 +385,7 @@ this.RequestSyncService = {
let dbKey = aData.task + "|" +
aPrincipal.appId + '|' +
aPrincipal.isInBrowserElement + '|' +
aPrincipal.origin;
aPrincipal.originNoSuffix;
let data = { principal: aPrincipal,
dbKey: dbKey,
@ -501,7 +501,7 @@ this.RequestSyncService = {
}
if (aObj.principal.isInBrowserElement != aData.isInBrowserElement ||
aObj.principal.origin != aData.origin) {
aObj.principal.originNoSuffix != aData.origin) {
return;
}
@ -549,7 +549,7 @@ this.RequestSyncService = {
}
if (aObj.principal.isInBrowserElement != aData.isInBrowserElement ||
aObj.principal.origin != aData.origin) {
aObj.principal.originNoSuffix != aData.origin) {
return;
}
@ -594,7 +594,7 @@ this.RequestSyncService = {
let obj = this.createPartialTaskObject(aObj);
obj.app = { manifestURL: '',
origin: aObj.principal.origin,
origin: aObj.principal.originNoSuffix,
isInBrowserElement: aObj.principal.isInBrowserElement };
let app = appsService.getAppByLocalId(aObj.principal.appId);

View File

@ -156,7 +156,7 @@ GetHostForPrincipal(nsIPrincipal* aPrincipal, nsACString& aHost)
}
// Some entries like "file://" uses the origin.
rv = aPrincipal->GetOrigin(aHost);
rv = aPrincipal->GetOriginNoSuffix(aHost);
if (NS_SUCCEEDED(rv) && !aHost.IsEmpty()) {
return NS_OK;
}

View File

@ -784,7 +784,7 @@ this.MobileIdentityManager = {
if (promptResult.serviceId) {
let creds = this.iccInfo[promptResult.serviceId].credentials;
if (creds) {
this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.origin,
this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.originNoSuffix,
creds.sessionToken, this.iccIds);
return creds;
}
@ -797,13 +797,13 @@ this.MobileIdentityManager = {
.then(
(creds) => {
if (creds) {
this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.origin,
this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.originNoSuffix,
creds.sessionToken, this.iccIds);
return creds;
}
// Otherwise, we need to verify the new number selected by the
// user.
return this.verificationFlow(promptResult, aPrincipal.origin);
return this.verificationFlow(promptResult, aPrincipal.originNoSuffix);
}
);
}
@ -916,11 +916,11 @@ this.MobileIdentityManager = {
// First of all we look if we already have credentials for this origin.
// If we don't have credentials it means that it is the first time that
// the caller requested an assertion.
this.credStore.getByOrigin(aPrincipal.origin)
this.credStore.getByOrigin(aPrincipal.originNoSuffix)
.then(
(creds) => {
log.debug("creds ${creds} - ${origin}", { creds: creds,
origin: aPrincipal.origin });
origin: aPrincipal.originNoSuffix });
if (!creds || !creds.sessionToken) {
log.debug("No credentials");
return;
@ -935,7 +935,7 @@ this.MobileIdentityManager = {
.then(
(newCreds) => {
return this.checkNewCredentials(creds, newCreds,
principal.origin);
principal.originNoSuffix);
}
);
}
@ -979,7 +979,7 @@ this.MobileIdentityManager = {
.then(
(newCreds) => {
return this.checkNewCredentials(creds, newCreds,
principal.origin);
principal.originNoSuffix);
}
);
}
@ -1009,7 +1009,7 @@ this.MobileIdentityManager = {
.then(
(creds) => {
if (creds) {
return this.generateAssertion(creds, principal.origin);
return this.generateAssertion(creds, principal.originNoSuffix);
}
return Promise.reject(ERROR_INTERNAL_CANNOT_GENERATE_ASSERTION);
}