Bug 1446880: updated IDP interface to use RTCIdentityProviderOptions. r=mt
MozReview-Commit-ID: 2xwDYR2kk27
--- 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;