Bug 1165162 - Add nsIPrincipal::cookieJar. r=sicking
authorBobby Holley <bobbyholley@gmail.com>
Mon, 18 May 2015 22:00:07 -0700
changeset 277266 e44ba0c0744aa9ecd6568d462f6d0522f53d50ca
parent 277265 cb2c0a02352edbe4103e32865e7d66c0f83c64b7
child 277267 eabe83ede1e3cd132eaf049ea5f53ce927c0b19f
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1165162
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1165162 - Add nsIPrincipal::cookieJar. r=sicking
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/nsIPrincipal.idl
caps/tests/unit/test_origin.js
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -156,16 +156,25 @@ BasePrincipal::GetOriginAttributes(JSCon
 NS_IMETHODIMP
 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
 {
   mOriginAttributes.CreateSuffix(aOriginAttributes);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+BasePrincipal::GetCookieJar(nsACString& aCookieJar)
+{
+  // We just forward to .jarPrefix for now, which is a nice compact
+  // stringification of the (appId, inBrowser) tuple. This will eventaully be
+  // swapped out for an origin attribute - see the comment in nsIPrincipal.idl.
+  return GetJarPrefix(aCookieJar);
+}
+
+NS_IMETHODIMP
 BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
 {
   if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
     NS_WARNING("Asking for app status on a principal with an unknown app id");
     *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
     return NS_OK;
   }
 
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -69,16 +69,17 @@ public:
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
   NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
   NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
   NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
   NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
   NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
+  NS_IMETHOD GetCookieJar(nsACString& aCookieJar) final;
   NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
   NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
   NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) final;
   NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
 
   virtual bool IsOnCSSUnprefixingWhitelist() override { return false; }
 
   static BasePrincipal* Cast(nsIPrincipal* aPrin) { return static_cast<BasePrincipal*>(aPrin); }
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -15,17 +15,17 @@ struct JSPrincipals;
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
-[scriptable, builtinclass, uuid(147839d5-e799-4280-831a-dd45946385f9)]
+[scriptable, builtinclass, uuid(749f21f5-8ade-4d0b-a590-2b1d18e890d5)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Returns whether the other principal is equivalent to this principal.
      * Principals are considered equal if they are the same principal, or
      * they have the same origin.
      */
     boolean equals(in nsIPrincipal other);
@@ -193,16 +193,40 @@ interface nsIPrincipal : nsISerializable
      * special requirements must inspect and compare .originSuffix manually.
      *
      * originsuffix are intended to be a replacement for jarPrefix, which will
      * eventually be removed.
      */
     readonly attribute AUTF8String originSuffix;
 
     /**
+     * Opaque string token representing the "cookie jar" associated with this
+     * principal. Cookie jars are intended to be a tag associated with persistent
+     * data (like cookies, localStorage data, etc) such that all data associated
+     * with a given cookie jar can be quickly located and (for example) deleted.
+     * Code from many origins may share a given cookie jar, so callers still need
+     * to consult .origin (or equivalent) to compartmentalize data - the cookie
+     * jar should _only_ be used as a tag in the manner described above.
+     *
+     * If two principals are in different cookie jars, they must be cross-origin.
+     * As such, the information making up the cookie jar token must be contained
+     * in the originAttributes (i.e. cookieJar must be a function of / derivable
+     * from originAttributes). Long term, the intention is for the cookie jar
+     * identifier to simply be an origin attribute. But we don't have that
+     * attribute yet, and we also need to concatenate the appId and inBrowser
+     * attributes until those go away.
+     *
+     * This getter is designed to hide these details from consumers so that they
+     * don't need to be updated when we swap out the implementation. For that
+     * reason, callers should treat the string as opaque and not rely on the
+     * current format.
+     */
+    readonly attribute ACString cookieJar;
+
+    /**
      * The base domain of the codebase URI to which this principal pertains
      * (generally the document URI), handling null principals and
      * non-hierarchical schemes correctly.
      */
     readonly attribute ACString baseDomain;
 
     const short APP_STATUS_NOT_INSTALLED = 0;
     const short APP_STATUS_INSTALLED     = 1;
--- a/caps/tests/unit/test_origin.js
+++ b/caps/tests/unit/test_origin.js
@@ -8,16 +8,19 @@ function makeURI(uri) { return Services.
 
 function checkCrossOrigin(a, b) {
   do_check_false(a.equals(b));
   do_check_false(a.equalsConsideringDomain(b));
   do_check_false(a.subsumes(b));
   do_check_false(a.subsumesConsideringDomain(b));
   do_check_false(b.subsumes(a));
   do_check_false(b.subsumesConsideringDomain(a));
+  do_check_eq(a.cookieJar === b.cookieJar,
+              a.originAttributes.appId == b.originAttributes.appId &&
+              a.originAttributes.inBrowser == b.originAttributes.inBrowser);
 }
 
 function checkOriginAttributes(prin, appId, inBrowser, suffix) {
   do_check_eq(prin.originAttributes.appId, appId || 0);
   do_check_eq(prin.originAttributes.inBrowser, inBrowser || false);
   do_check_eq(prin.originSuffix, suffix || '');
 }