summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/mochitest/test_ext_identity.html
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/mochitest/test_ext_identity.html')
-rw-r--r--toolkit/components/extensions/test/mochitest/test_ext_identity.html390
1 files changed, 390 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_identity.html b/toolkit/components/extensions/test/mochitest/test_ext_identity.html
new file mode 100644
index 0000000000..7aa590ec22
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_identity.html
@@ -0,0 +1,390 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for WebExtension Identity</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script src="head.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+add_task(async function setup() {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["extensions.webextensions.identity.redirectDomain", "example.com"],
+ // Disable the network cache first-party partition during this
+ // test (TODO: look more closely to how that is affecting the intermittency
+ // of this test on MacOS, see Bug 1626482).
+ ["privacy.partition.network_state", false],
+ ],
+ });
+});
+
+add_task(async function test_noPermission() {
+ let extension = ExtensionTestUtils.loadExtension({
+ background() {
+ browser.test.assertEq(
+ undefined,
+ browser.identity,
+ "No identity api without permission"
+ );
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function test_getRedirectURL() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["identity", "https://example.com/"],
+ },
+ async background() {
+ let redirect_base =
+ "https://35b64b676900f491c00e7f618d43f7040e88422e.example.com/";
+ await browser.test.assertEq(
+ redirect_base,
+ browser.identity.getRedirectURL(),
+ "redirect url ok"
+ );
+ await browser.test.assertEq(
+ redirect_base,
+ browser.identity.getRedirectURL(""),
+ "redirect url ok"
+ );
+ await browser.test.assertEq(
+ redirect_base + "foobar",
+ browser.identity.getRedirectURL("foobar"),
+ "redirect url ok"
+ );
+ await browser.test.assertEq(
+ redirect_base + "callback",
+ browser.identity.getRedirectURL("/callback"),
+ "redirect url ok"
+ );
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function test_badAuthURI() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["identity", "https://example.com/"],
+ },
+ async background() {
+ for (let url of [
+ "foobar",
+ "about:addons",
+ "about:blank",
+ "ftp://example.com/test",
+ ]) {
+ await browser.test.assertThrows(
+ () => {
+ browser.identity.launchWebAuthFlow({ interactive: true, url });
+ },
+ /Type error for parameter details/,
+ "details.url is invalid"
+ );
+ }
+
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function test_badRequestURI() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["identity", "https://example.com/"],
+ },
+ async background() {
+ let base_uri =
+ "https://example.com/tests/toolkit/components/extensions/test/mochitest/";
+ let url = `${base_uri}?redirect_uri=badrobot}`;
+ await browser.test.assertRejects(
+ browser.identity.launchWebAuthFlow({ interactive: true, url }),
+ "redirect_uri is invalid",
+ "invalid redirect url"
+ );
+ url = `${base_uri}?redirect_uri=https://somesite.com`;
+ await browser.test.assertRejects(
+ browser.identity.launchWebAuthFlow({ interactive: true, url }),
+ "redirect_uri not allowed",
+ "invalid redirect url"
+ );
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function background_launchWebAuthFlow_requires_interaction() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["identity", "https://example.com/"],
+ },
+ async background() {
+ let base_uri =
+ "https://example.com/tests/toolkit/components/extensions/test/mochitest/";
+ let url = `${base_uri}?redirect_uri=${browser.identity.getRedirectURL(
+ "redirect"
+ )}`;
+ await browser.test.assertRejects(
+ browser.identity.launchWebAuthFlow({ interactive: false, url }),
+ "Requires user interaction",
+ "Rejects on required user interaction"
+ );
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+function background_launchWebAuthFlow({
+ interactive = false,
+ path = "redirect_auto.sjs",
+ params = {},
+ redirect = true,
+ useRedirectUri = true,
+} = {}) {
+ let uri_path = useRedirectUri ? "identity_cb" : "";
+ let expected_redirect = `https://35b64b676900f491c00e7f618d43f7040e88422e.example.com/${uri_path}`;
+ let base_uri =
+ "https://example.com/tests/toolkit/components/extensions/test/mochitest/";
+ let redirect_uri = browser.identity.getRedirectURL(
+ useRedirectUri ? uri_path : undefined
+ );
+ browser.test.assertEq(
+ expected_redirect,
+ redirect_uri,
+ "expected redirect uri matches hash"
+ );
+ let url = `${base_uri}${path}`;
+ if (useRedirectUri) {
+ params.redirect_uri = redirect_uri;
+ } else {
+ // We kind of fake it with the redirect url that would normally be configured
+ // in the oauth service. This does still test that the identity service falls back
+ // to the extensions redirect url.
+ params.default_redirect = expected_redirect;
+ }
+ if (!redirect) {
+ params.no_redirect = 1;
+ }
+ let query = [];
+ for (let [param, value] of Object.entries(params)) {
+ query.push(`${param}=${encodeURIComponent(value)}`);
+ }
+ url = `${url}?${query.join("&")}`;
+
+ // Ensure we do not start the actual request for the redirect url. In the case
+ // of a 303 POST redirect we are getting a request started.
+ let watchRedirectRequest = () => {};
+ if (params.post !== 303) {
+ watchRedirectRequest = details => {
+ if (details.url.startsWith(expected_redirect)) {
+ browser.test.fail(`onBeforeRequest called for redirect url: ${JSON.stringify(details)}`);
+ }
+ };
+
+ browser.webRequest.onBeforeRequest.addListener(
+ watchRedirectRequest,
+ {
+ urls: [
+ "https://35b64b676900f491c00e7f618d43f7040e88422e.example.com/*",
+ ],
+ }
+ );
+ }
+
+ browser.identity
+ .launchWebAuthFlow({ interactive, url })
+ .then(redirectURL => {
+ browser.test.assertTrue(
+ redirectURL.startsWith(redirect_uri),
+ `correct redirect url ${redirectURL}`
+ );
+ if (redirect) {
+ let url = new URL(redirectURL);
+ browser.test.assertEq(
+ "here ya go",
+ url.searchParams.get("access_token"),
+ "Handled auto redirection"
+ );
+ }
+ })
+ .catch(error => {
+ if (redirect) {
+ browser.test.fail(error.message);
+ } else {
+ browser.test.assertEq(
+ "Requires user interaction",
+ error.message,
+ "Auth page loaded, interaction required."
+ );
+ }
+ }).then(() => {
+ browser.webRequest.onBeforeRequest.removeListener(watchRedirectRequest);
+ browser.test.sendMessage("done");
+ });
+}
+
+// Tests the situation where the oauth provider has already granted access and
+// simply redirects the oauth client to provide the access key or code.
+add_task(async function test_autoRedirect() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["webRequest", "identity", "https://*.example.com/*"],
+ },
+ background: `(${background_launchWebAuthFlow})()`,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function test_autoRedirect_noRedirectURI() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["webRequest", "identity", "https://*.example.com/*"],
+ },
+ background: `(${background_launchWebAuthFlow})({useRedirectUri: false})`,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+// Tests the situation where the oauth provider has not granted access and interactive=false
+add_task(async function test_noRedirect() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["webRequest", "identity", "https://*.example.com/*"],
+ },
+ background: `(${background_launchWebAuthFlow})({redirect: false})`,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+// Tests the situation where the oauth provider must show a window where
+// presumably the user interacts, then the redirect occurs and access key or
+// code is provided. We bypass any real interaction, but want the window to
+// open and result in a redirect.
+add_task(async function test_interaction() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["webRequest", "identity", "https://*.example.com/*"],
+ },
+ background: `(${background_launchWebAuthFlow})({interactive: true, path: "oauth.html"})`,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+// Tests the situation where the oauth provider redirects with a 303.
+add_task(async function test_auto303Redirect() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["webRequest", "identity", "https://*.example.com/*"],
+ },
+ background: `(${background_launchWebAuthFlow})({interactive: true, path: "oauth.html", params: {post: 303, server_uri: "redirect_auto.sjs"}})`,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+
+add_task(async function test_loopbackRedirectURI() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: {
+ gecko: {
+ id: "identity@mozilla.org",
+ },
+ },
+ permissions: ["identity"],
+ },
+ async background() {
+ let redirectURL = "http://127.0.0.1/mozoauth2/35b64b676900f491c00e7f618d43f7040e88422e";
+ let actualRedirect = await browser.identity.launchWebAuthFlow({
+ interactive: true,
+ url: `https://example.com/tests/toolkit/components/extensions/test/mochitest/oauth.html?redirect_uri=${encodeURIComponent(redirectURL)}`
+ }).catch(error => {
+ browser.test.fail(error.message)
+ });
+ browser.test.assertTrue(
+ actualRedirect.startsWith(redirectURL),
+ "Expected redirect url to be loopback address"
+ )
+ browser.test.sendMessage("done");
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("done");
+ await extension.unload();
+});
+</script>
+
+</body>
+</html>