summaryrefslogtreecommitdiffstats
path: root/dom/media/tests/mochitest/identity/test_idpproxy.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/tests/mochitest/identity/test_idpproxy.html')
-rw-r--r--dom/media/tests/mochitest/identity/test_idpproxy.html176
1 files changed, 176 insertions, 0 deletions
diff --git a/dom/media/tests/mochitest/identity/test_idpproxy.html b/dom/media/tests/mochitest/identity/test_idpproxy.html
new file mode 100644
index 000000000..c8860d1f4
--- /dev/null
+++ b/dom/media/tests/mochitest/identity/test_idpproxy.html
@@ -0,0 +1,176 @@
+<html>
+<head>
+<meta charset="utf-8" />
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+ <script class="testbody" type="application/javascript">
+"use strict";
+var Cu = SpecialPowers.Cu;
+var rtcid = Cu.import("resource://gre/modules/media/IdpSandbox.jsm");
+var IdpSandbox = rtcid.IdpSandbox;
+var dummyPayload = JSON.stringify({
+ this: 'is',
+ a: ['stu', 6],
+ obj: null
+});
+
+function test_domain_sandbox() {
+ var diabolical = {
+ toString : function() {
+ return 'example.com/path';
+ }
+ };
+ var domains = [ 'ex/foo', 'user@ex', 'user:pass@ex', 'ex#foo', 'ex?foo',
+ '', 12, null, diabolical, true ];
+ domains.forEach(function(domain) {
+ try {
+ var idp = new IdpSandbox(domain, undefined, window);
+ ok(false, 'IdpSandbox allowed a bad domain: ' + domain);
+ } catch (e) {
+ var str = (typeof domain === 'string') ? domain : typeof domain;
+ ok(true, 'Evil domain "' + str + '" raises exception');
+ }
+ });
+}
+
+function test_protocol_sandbox() {
+ var protos = [ '../evil/proto', '..%2Fevil%2Fproto',
+ '\\evil', '%5cevil', 12, true, {} ];
+ protos.forEach(function(proto) {
+ try {
+ var idp = new IdpSandbox('example.com', proto, window);
+ ok(false, 'IdpSandbox allowed a bad protocol: ' + proto);
+ } catch (e) {
+ var str = (typeof proto === 'string') ? proto : typeof proto;
+ ok(true, 'Evil protocol "' + proto + '" raises exception');
+ }
+ });
+}
+
+function idpName(hash) {
+ return 'idp.js' + (hash ? ('#' + hash) : '');
+}
+
+function makeSandbox(js) {
+ var name = js || idpName();
+ 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'))
+ .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'))
+ .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');
+ is(response.contents, dummyPayload);
+ });
+}
+
+// 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(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'),
+ e => ok(e, 'Should fail to load non-existent file'));
+}
+
+function test_redirect_ok(from) {
+ return () => {
+ return makeSandbox(from)
+ .then(idp => idp.generateAssertion('hello', 'example.net'))
+ .then(r => ok(SpecialPowers.wrap(r).assertion,
+ 'Redirect to https should be OK'));
+ };
+}
+
+function test_redirect_fail(from) {
+ return () => {
+ return makeSandbox(from)
+ .then(() => ok(false, 'Redirect to https should fail'),
+ e => ok(e, 'Redirect to https should fail'));
+ };
+}
+
+function test_bad_js() {
+ return makeSandbox('idp-bad.js')
+ .then(() => ok(false, 'Bad JS should not load'),
+ e => ok(e, 'Bad JS should not load'));
+}
+
+function run_all_tests() {
+ [
+ test_domain_sandbox,
+ test_protocol_sandbox,
+ test_generate_assertion,
+ test_validate_assertion,
+
+ // fail of the IdP fails
+ test_assertion_failure('fail'),
+ // fail if the IdP throws
+ test_assertion_failure('throw'),
+ // fail if the IdP is not ready
+ test_assertion_failure('not_ready'),
+
+ test_load_failure(),
+ // Test a redirect to an HTTPS origin, which should be OK
+ test_redirect_ok('idp-redirect-https.js'),
+ // Two redirects is fine too
+ test_redirect_ok('idp-redirect-https-double.js'),
+ // A secure redirect to a path other than /.well-known/idp-proxy/* should
+ // also work fine.
+ test_redirect_ok('idp-redirect-https-odd-path.js'),
+ // A redirect to HTTP is not-cool
+ test_redirect_fail('idp-redirect-http.js'),
+ // Also catch tricks like https->http->https
+ test_redirect_fail('idp-redirect-http-trick.js'),
+
+ test_bad_js
+ ].reduce((p, test) => {
+ return p.then(test)
+ .catch(e => ok(false, test.name + ' failed: ' +
+ SpecialPowers.wrap(e).message + '\n' +
+ SpecialPowers.wrap(e).stack));
+ }, Promise.resolve())
+ .then(() => SimpleTest.finish());
+}
+
+SimpleTest.waitForExplicitFinish();
+run_all_tests();
+</script>
+ </body>
+</html>