Bug 1314361: Part 1 - Generate nsIPrincipal.addonId from AddonPolicyService rather than origin attributes. r=billm draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 05 Nov 2016 22:38:17 -0700
changeset 489858 ead57be1ab6a6fb5a7627dea16d6fec2261c950d
parent 489857 7ef1e9abd296a8edc39b7efc8d637767ba2f77ed
child 489859 abaffcc44d5653e6e479940302d0aae71b0bb880
push id46924
push usermaglione.k@gmail.com
push dateSun, 26 Feb 2017 21:23:01 +0000
reviewersbillm
bugs1314361
milestone54.0a1
Bug 1314361: Part 1 - Generate nsIPrincipal.addonId from AddonPolicyService rather than origin attributes. r=billm MozReview-Commit-ID: 4eaoHG94rdZ
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/nsExpandedPrincipal.cpp
caps/nsExpandedPrincipal.h
caps/nsNullPrincipal.cpp
caps/nsNullPrincipal.h
caps/nsPrincipal.cpp
caps/nsPrincipal.h
caps/nsSystemPrincipal.cpp
caps/nsSystemPrincipal.h
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -580,23 +580,16 @@ BasePrincipal::GetAppId(uint32_t* aAppId
     return NS_OK;
   }
 
   *aAppId = AppId();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-BasePrincipal::GetAddonId(nsAString& aAddonId)
-{
-  aAddonId.Assign(mOriginAttributes.mAddonId);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
 {
   *aUserContextId = UserContextId();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId)
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -239,17 +239,16 @@ public:
   NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
   NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
   NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
   NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override;
   NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
   NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
   NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
   NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
-  NS_IMETHOD GetAddonId(nsAString& aAddonId) final;
   NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) final;
   NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
   NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
   NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
 
   bool EqualsIgnoringAddonId(nsIPrincipal *aOther);
 
   virtual bool AddonHasPermission(const nsAString& aPerm);
--- a/caps/nsExpandedPrincipal.cpp
+++ b/caps/nsExpandedPrincipal.cpp
@@ -155,16 +155,23 @@ nsExpandedPrincipal::GetWhiteList(nsTArr
 }
 
 NS_IMETHODIMP
 nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   return NS_ERROR_NOT_AVAILABLE;
 }
 
+NS_IMETHODIMP
+nsExpandedPrincipal::GetAddonId(nsAString& aAddonId)
+{
+  aAddonId.Truncate();
+  return NS_OK;
+};
+
 bool
 nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
 {
   for (size_t i = 0; i < mPrincipals.Length(); ++i) {
     if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
       return true;
     }
   }
--- a/caps/nsExpandedPrincipal.h
+++ b/caps/nsExpandedPrincipal.h
@@ -24,16 +24,17 @@ public:
   NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
   NS_IMETHOD_(MozExternalRefCountType) Release() override { return nsJSPrincipals::Release(); };
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
+  NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   virtual bool AddonHasPermission(const nsAString& aPerm) override;
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   PrincipalKind Kind() override { return eExpandedPrincipal; }
 
 protected:
   virtual ~nsExpandedPrincipal();
--- a/caps/nsNullPrincipal.cpp
+++ b/caps/nsNullPrincipal.cpp
@@ -151,16 +151,23 @@ nsNullPrincipal::MayLoadInternal(nsIURI*
 
 NS_IMETHODIMP
 nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   // For a null principal, we use our unique uuid as the base domain.
   return mURI->GetPath(aBaseDomain);
 }
 
+NS_IMETHODIMP
+nsNullPrincipal::GetAddonId(nsAString& aAddonId)
+{
+  aAddonId.Truncate();
+  return NS_OK;
+};
+
 /**
  * nsISerializable implementation
  */
 NS_IMETHODIMP
 nsNullPrincipal::Read(nsIObjectInputStream* aStream)
 {
   // Note - nsNullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
   // that the Init() method has already been invoked by the time we deserialize.
--- a/caps/nsNullPrincipal.h
+++ b/caps/nsNullPrincipal.h
@@ -41,16 +41,17 @@ public:
   NS_DECL_NSISERIALIZABLE
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
+  NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
 
   static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIDocShell* aDocShell);
 
   static already_AddRefed<nsNullPrincipal>
   Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes(),
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -22,16 +22,17 @@
 #include "nsIProtocolHandler.h"
 #include "nsError.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsNetCID.h"
 #include "jswrapper.h"
 
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
 static bool gCodeBasePrincipalSupport = false;
 
 static bool URIIsImmutable(nsIURI* aURI)
@@ -39,16 +40,29 @@ static bool URIIsImmutable(nsIURI* aURI)
   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
   bool isMutable;
   return
     mutableObj &&
     NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
     !isMutable;
 }
 
+static nsIAddonPolicyService*
+GetAddonPolicyService(nsresult* aRv)
+{
+  static nsCOMPtr<nsIAddonPolicyService> addonPolicyService;
+
+  *aRv = NS_OK;
+  if (!addonPolicyService) {
+    addonPolicyService = do_GetService("@mozilla.org/addons/policy-service;1", aRv);
+    ClearOnShutdown(&addonPolicyService);
+  }
+  return addonPolicyService;
+}
+
 NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_PRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
                            nsIPrincipal,
                            nsISerializable)
 NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
                             nsIPrincipal,
                             nsISerializable)
@@ -374,16 +388,45 @@ nsPrincipal::GetBaseDomain(nsACString& a
   if (thirdPartyUtil) {
     return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPrincipal::GetAddonId(nsAString& aAddonId)
+{
+  if (mAddonIdCache.isSome()) {
+    aAddonId.Assign(mAddonIdCache.ref());
+    return NS_OK;
+  }
+
+  NS_ENSURE_TRUE(mCodebase, NS_ERROR_FAILURE);
+
+  nsresult rv;
+  bool isMozExt;
+  if (NS_SUCCEEDED(mCodebase->SchemeIs("moz-extension", &isMozExt)) && isMozExt) {
+    nsIAddonPolicyService* addonPolicyService = GetAddonPolicyService(&rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsAutoString addonId;
+    rv = addonPolicyService->ExtensionURIToAddonId(mCodebase, addonId);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    mAddonIdCache.emplace(addonId);
+  } else {
+    mAddonIdCache.emplace();
+  }
+
+  aAddonId.Assign(mAddonIdCache.ref());
+  return NS_OK;
+};
+
+NS_IMETHODIMP
 nsPrincipal::Read(nsIObjectInputStream* aStream)
 {
   nsCOMPtr<nsISupports> supports;
   nsCOMPtr<nsIURI> codebase;
   nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   if (NS_FAILED(rv)) {
     return rv;
   }
--- a/caps/nsPrincipal.h
+++ b/caps/nsPrincipal.h
@@ -20,16 +20,17 @@ class nsPrincipal final : public mozilla
 public:
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
   NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
+  NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   bool IsCodebasePrincipal() const override { return true; }
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   nsPrincipal();
 
   // Init() must be called before the principal is in a usable state.
   nsresult Init(nsIURI* aCodebase,
                 const mozilla::OriginAttributes& aOriginAttributes);
@@ -51,16 +52,19 @@ public:
   bool mDomainImmutable;
   bool mInitialized;
 
 protected:
   virtual ~nsPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
+
+private:
+  mozilla::Maybe<nsString> mAddonIdCache;
 };
 
 #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
 #define NS_PRINCIPAL_CID \
 { 0x653e0e4d, 0x3ee4, 0x45fa, \
   { 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
 
 #endif // nsPrincipal_h__
--- a/caps/nsSystemPrincipal.cpp
+++ b/caps/nsSystemPrincipal.cpp
@@ -108,16 +108,23 @@ nsSystemPrincipal::SetDomain(nsIURI* aDo
 
 NS_IMETHODIMP
 nsSystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
 {
   // No base domain for chrome.
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsSystemPrincipal::GetAddonId(nsAString& aAddonId)
+{
+  aAddonId.Truncate();
+  return NS_OK;
+};
+
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
 nsSystemPrincipal::Read(nsIObjectInputStream* aStream)
 {
     // no-op: CID is sufficient to identify the mSystemPrincipal singleton
--- a/caps/nsSystemPrincipal.h
+++ b/caps/nsSystemPrincipal.h
@@ -29,16 +29,17 @@ public:
   NS_IMETHOD GetURI(nsIURI** aURI) override;
   NS_IMETHOD GetDomain(nsIURI** aDomain) override;
   NS_IMETHOD SetDomain(nsIURI* aDomain) override;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
   NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
   NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
   NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
+  NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
   nsresult GetOriginInternal(nsACString& aOrigin) override;
 
   nsSystemPrincipal() {}
 
   virtual nsresult GetScriptLocation(nsACString &aStr) override;
 
 protected:
   virtual ~nsSystemPrincipal(void) {}