Bug 1446880: updated IDP interface to use RTCIdentityProviderOptions. r=mt draft
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Tue, 20 Mar 2018 11:15:10 +0000
changeset 777652 043a2217af0735ad0a5d0d72398e7771fd055105
parent 777651 b597b7fe0daff9b6fead92b3cc9c2da3e45a671c
child 777653 84f63a03e84fd8cb620c606b2eede78db187ce2d
push id105260
push userdrno@ohlmeier.org
push dateThu, 05 Apr 2018 03:49:09 +0000
reviewersmt
bugs1446880
milestone61.0a1
Bug 1446880: updated IDP interface to use RTCIdentityProviderOptions. r=mt MozReview-Commit-ID: 2xwDYR2kk27
dom/media/PeerConnectionIdp.jsm
dom/media/tests/mochitest/identity/idp.js
dom/media/tests/mochitest/identity/test_fingerprints.html
dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
dom/media/tests/mochitest/identity/test_idpproxy.html
dom/media/webrtc/RTCIdentityProviderRegistrar.cpp
dom/media/webrtc/RTCIdentityProviderRegistrar.h
--- a/dom/media/PeerConnectionIdp.jsm
+++ b/dom/media/PeerConnectionIdp.jsm
@@ -65,16 +65,18 @@ PeerConnectionIdp.prototype = {
         throw new this._win.DOMException(e.message, "IdpError");
       });
   },
 
   close() {
     this._resetAssertion();
     this.provider = null;
     this.protocol = null;
+    this.username = null;
+    this.peeridentity = null;
     if (this._idp) {
       this._idp.stop();
       this._idp = null;
     }
   },
 
   _getFingerprintsFromSdp(sdp) {
     let fingerprints = {};
@@ -278,19 +280,25 @@ PeerConnectionIdp.prototype = {
       fingerprint: [{
         algorithm,
         digest
       }]
     };
 
     this._resetAssertion();
     let p = this.start()
-        .then(idp => this._wrapCrossCompartmentPromise(
-          idp.generateAssertion(JSON.stringify(content),
-                                origin, this.username)))
+        .then(idp => {
+          let options = { protocol: this.protocol,
+                          usernameHint: this.username,
+                          peerIdentity: this.peeridentity };
+          return this._wrapCrossCompartmentPromise(
+            idp.generateAssertion(JSON.stringify(content),
+                                  origin,
+                                  options));
+        })
         .then(assertion => {
           if (!this._isValidAssertion(assertion)) {
             throw new this._win.DOMException("IdP generated invalid assertion",
                                              "IdpError");
           }
           // save the base64+JSON assertion, since that is all that is used
           this.assertion = btoa(JSON.stringify(assertion));
           return this.assertion;
--- a/dom/media/tests/mochitest/identity/idp.js
+++ b/dom/media/tests/mochitest/identity/idp.js
@@ -51,41 +51,43 @@
       if (instructions.some(is('hang'))) {
         return new Promise(r => {});
       }
       dump('idp: result=' + JSON.stringify(result) + '\n');
       return Promise.resolve(result);
     },
 
     _selectUsername: function(usernameHint) {
+      dump('_selectUsername: usernameHint(' + usernameHint + ')\n');
       var username = 'someone@' + this.domain;
       if (usernameHint) {
         var at = usernameHint.indexOf('@');
         if (at < 0) {
           username = usernameHint + '@' + this.domain;
         } else if (usernameHint.substring(at + 1) === this.domain) {
           username = usernameHint;
         }
       }
       return username;
     },
 
-    generateAssertion: function(payload, origin, usernameHint) {
-      dump('idp: generateAssertion(' + payload + ')\n');
+    generateAssertion: function(payload, origin, options) {
+      dump('idp: generateAssertion(' + payload + ', ' + origin + ', '
+           + JSON.stringify(options) + ')\n');
       var idpDetails = {
         domain: this.domain,
         protocol: this.protocol
       };
       if (instructions.some(is('bad-assert'))) {
         idpDetails = {};
       }
       return this.borkResult({
         idp: idpDetails,
         assertion: JSON.stringify({
-          username: this._selectUsername(usernameHint),
+          username: this._selectUsername(options.usernameHint),
           contents: payload
         })
       });
     },
 
     validateAssertion: function(assertion, origin) {
       dump('idp: validateAssertion(' + assertion + ')\n');
       var assertion = JSON.parse(assertion);
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -11,17 +11,18 @@
 // here we call the identity provider directly
 function getIdentityAssertion(fpArray) {
   var Cu = SpecialPowers.Cu;
   var rtcid = Cu.import('resource://gre/modules/media/IdpSandbox.jsm');
   var sandbox = new rtcid.IdpSandbox('example.com', 'idp.js', window);
   return sandbox.start()
     .then(idp => SpecialPowers.wrap(idp)
                    .generateAssertion(JSON.stringify({ fingerprint: fpArray }),
-                                      'https://example.com'))
+                                      'https://example.com',
+                                      {}))
     .then(assertion => {
       assertion = SpecialPowers.wrap(assertion);
       var assertionString = btoa(JSON.stringify(assertion));
       sandbox.stop();
       return assertionString;
     });
 }
 
--- a/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
+++ b/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
@@ -16,16 +16,18 @@ function checkIdentity(assertion, identi
   // here we dig into the payload, which means we need to know something
   // about how the IdP actually works (not good in general, but OK here)
   var assertion = JSON.parse(atob(assertion)).assertion;
   var user = JSON.parse(assertion).username;
   is(user, identity, 'id should be "' + identity + '" is "' + user + '"');
 }
 
 function getAssertion(t, instructions, userHint) {
+  dump('instructions: ' + instructions + '\n');
+  dump('userHint: ' + userHint + '\n');
   t.pcLocal.setIdentityProvider('example.com',
                                 { protocol: 'idp.js' + instructions,
                                   usernameHint: userHint });
   return t.pcLocal._pc.getIdentityAssertion();
 }
 
 var test;
 function theTest() {
--- a/dom/media/tests/mochitest/identity/test_idpproxy.html
+++ b/dom/media/tests/mochitest/identity/test_idpproxy.html
@@ -58,33 +58,35 @@ function makeSandbox(js) {
   info('Creating a sandbox for the protocol: ' + name);
   var sandbox = new IdpSandbox('example.com', name, window);
   return sandbox.start().then(idp => SpecialPowers.wrap(idp));
 }
 
 function test_generate_assertion() {
   return makeSandbox()
     .then(idp => idp.generateAssertion(dummyPayload,
-                                       'https://example.net'))
+                                       'https://example.net',
+                                        {}))
     .then(response => {
       response = SpecialPowers.wrap(response);
       is(response.idp.domain, 'example.com', 'domain is correct');
       is(response.idp.protocol, 'idp.js', 'protocol is correct');
       ok(typeof response.assertion === 'string', 'assertion is present');
     });
 }
 
 // test that the test IdP can eat its own dogfood; which is the only way to test
 // validateAssertion, since that consumes the output of generateAssertion (in
 // theory, generateAssertion could identify a different IdP domain).
 
 function test_validate_assertion() {
   return makeSandbox()
     .then(idp => idp.generateAssertion(dummyPayload,
-                                       'https://example.net', 'user'))
+                                       'https://example.net',
+                                       { usernameHint: 'user' }))
     .then(assertion => {
       var wrapped = SpecialPowers.wrap(assertion);
       return makeSandbox()
         .then(idp => idp.validateAssertion(wrapped.assertion,
                                            'https://example.net'));
     }).then(response => {
       response = SpecialPowers.wrap(response);
       is(response.identity, 'user@example.com');
@@ -92,17 +94,17 @@ function test_validate_assertion() {
     });
 }
 
 // We don't want to test the #bad or the #hang instructions,
 // errors of the sort those generate aren't handled by the sandbox code.
 function test_assertion_failure(reason) {
   return () => {
     return makeSandbox(idpName(reason))
-      .then(idp => idp.generateAssertion('hello', 'example.net'))
+      .then(idp => idp.generateAssertion('hello', 'example.net', {}))
       .then(r => ok(false, 'should not succeed on ' + reason),
             e => ok(true, 'failed correctly on ' + reason));
   };
 }
 
 function test_load_failure() {
   return makeSandbox('non-existent-file')
     .then(() => ok(false, 'Should fail to load non-existent file'),
--- a/dom/media/webrtc/RTCIdentityProviderRegistrar.cpp
+++ b/dom/media/webrtc/RTCIdentityProviderRegistrar.cpp
@@ -58,23 +58,23 @@ bool
 RTCIdentityProviderRegistrar::HasIdp() const
 {
   return mGenerateAssertionCallback && mValidateAssertionCallback;
 }
 
 already_AddRefed<Promise>
 RTCIdentityProviderRegistrar::GenerateAssertion(
   const nsAString& aContents, const nsAString& aOrigin,
-  const Optional<nsAString>& aUsernameHint, ErrorResult& aRv)
+  const RTCIdentityProviderOptions& aOptions, ErrorResult& aRv)
 {
   if (!mGenerateAssertionCallback) {
     aRv.Throw(NS_ERROR_NOT_INITIALIZED);
     return nullptr;
   }
-  return mGenerateAssertionCallback->Call(aContents, aOrigin, aUsernameHint, aRv);
+  return mGenerateAssertionCallback->Call(aContents, aOrigin, aOptions, aRv);
 }
 already_AddRefed<Promise>
 RTCIdentityProviderRegistrar::ValidateAssertion(
   const nsAString& aAssertion, const nsAString& aOrigin, ErrorResult& aRv)
 {
   if (!mValidateAssertionCallback) {
     aRv.Throw(NS_ERROR_NOT_INITIALIZED);
     return nullptr;
--- a/dom/media/webrtc/RTCIdentityProviderRegistrar.h
+++ b/dom/media/webrtc/RTCIdentityProviderRegistrar.h
@@ -35,17 +35,18 @@ public:
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   // setter and checker
   void Register(const RTCIdentityProvider& aIdp);
   bool HasIdp() const;
 
   already_AddRefed<Promise>
   GenerateAssertion(const nsAString& aContents, const nsAString& aOrigin,
-                    const Optional<nsAString>& aUsernameHint, ErrorResult& aRv);
+                    const RTCIdentityProviderOptions& aOptions,
+                    ErrorResult& aRv);
   already_AddRefed<Promise>
   ValidateAssertion(const nsAString& assertion, const nsAString& origin,
                     ErrorResult& aRv);
 
 private:
   ~RTCIdentityProviderRegistrar();
 
   nsCOMPtr<nsIGlobalObject> mGlobal;