diff options
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/identity/test_idpproxy.html')
-rw-r--r-- | dom/media/webrtc/tests/mochitests/identity/test_idpproxy.html | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/identity/test_idpproxy.html b/dom/media/webrtc/tests/mochitests/identity/test_idpproxy.html new file mode 100644 index 0000000000..065501b8a4 --- /dev/null +++ b/dom/media/webrtc/tests/mochitests/identity/test_idpproxy.html @@ -0,0 +1,178 @@ +<html> +<head> +<meta charset="utf-8" /> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +</head> +<body> + <script class="testbody" type="application/javascript"> +"use strict"; +var { IdpSandbox } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/media/IdpSandbox.jsm" +); +var dummyPayload = JSON.stringify({ + this: 'is', + a: ['stu', 6], + obj: null +}); + +function test_domain_sandbox() { + var diabolical = { + toString() { + 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', + { 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'); + 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> |