summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/credential-management/support/fedcm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/credential-management/support/fedcm
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/credential-management/support/fedcm')
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/accounts.py24
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py25
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py.headers1
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/client_metadata_clear_count.py15
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/continue_on.py12
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/disconnect-iframe.html61
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/disconnect.py14
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/disconnect_failure.py8
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/error_with_code_and_url.py12
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/intercept_service_worker.js10
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/keys.py2
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/login.html9
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest-not-in-list.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest.py19
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_no_login_url.json5
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_accounts.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_token.json7
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_token_with_http_error.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_auto_selected_flag.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_continue_on.json8
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_cross_origin_disconnect.sub.json7
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_disconnect_failure.json7
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_no_accounts.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_single_account.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_two_accounts.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/manifest_with_variable_accounts.json6
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/no_accounts.py17
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/pending-userinfo-iframe.html22
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/request-params-check.py101
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/resolve.html8
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/select_manifest_in_root_manifest.py17
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/simple.html3
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/single_account.py24
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/token.py11
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/token_with_account_id.py12
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/token_with_auto_selected_flag.py12
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/token_with_http_error.py12
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/two_accounts.py34
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/userinfo-iframe.html37
-rw-r--r--testing/web-platform/tests/credential-management/support/fedcm/variable_accounts.py33
41 files changed, 643 insertions, 0 deletions
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/accounts.py b/testing/web-platform/tests/credential-management/support/fedcm/accounts.py
new file mode 100644
index 0000000000..126f911a58
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/accounts.py
@@ -0,0 +1,24 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.accountsCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{
+ "accounts": [{
+ "id": "1234",
+ "given_name": "John",
+ "name": "John Doe",
+ "email": "john_doe@idp.example",
+ "picture": "https://idp.example/profile/123",
+ "approved_clients": ["123", "456", "789"],
+ "login_hints": ["john_doe"],
+ "domain_hints": ["idp.example", "example"]
+ }]
+}
+"""
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py
new file mode 100644
index 0000000000..72ddcc5cd6
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py
@@ -0,0 +1,25 @@
+# 'import credential-management.support.fedcm.keys' does not work.
+import importlib
+keys = importlib.import_module("credential-management.support.fedcm.keys")
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.clientMetadataCheck(request)
+ if (request_error):
+ return request_error
+
+ counter = request.server.stash.take(keys.CLIENT_METADATA_COUNTER_KEY)
+ try:
+ counter = int(counter) + 1
+ except (TypeError, ValueError):
+ counter = 1
+
+ request.server.stash.put(keys.CLIENT_METADATA_COUNTER_KEY, str(counter).encode())
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{{
+ "privacy_policy_url": "https://privacypolicy{0}.com"
+}}
+""".format(str(counter))
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py.headers b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py.headers
new file mode 100644
index 0000000000..7164e5f818
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata.py.headers
@@ -0,0 +1 @@
+Cache-Control: public, max-age=86400
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/client_metadata_clear_count.py b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata_clear_count.py
new file mode 100644
index 0000000000..3c31bf5077
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/client_metadata_clear_count.py
@@ -0,0 +1,15 @@
+# 'import credential-management.support.fedcm.keys' does not work.
+import importlib
+keys = importlib.import_module("credential-management.support.fedcm.keys")
+
+def main(request, response):
+ client_metadata_url = "/credential-management/support/fedcm/client_metadata.py"
+ counter = request.server.stash.take(keys.CLIENT_METADATA_COUNTER_KEY,
+ client_metadata_url)
+
+ try:
+ counter = counter.decode()
+ except (UnicodeDecodeError, AttributeError):
+ pass
+
+ return counter
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/continue_on.py b/testing/web-platform/tests/credential-management/support/fedcm/continue_on.py
new file mode 100644
index 0000000000..42b4f3f8fd
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/continue_on.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return "{\"continue_on\": \"resolve.html\"}"
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/disconnect-iframe.html b/testing/web-platform/tests/credential-management/support/fedcm/disconnect-iframe.html
new file mode 100644
index 0000000000..f65763932b
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/disconnect-iframe.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script type="module">
+ import {disconnect_options,
+ request_options_with_mediation_required,
+ set_fedcm_cookie, manifest_origin} from './../fedcm-helper.sub.js';
+
+// Loading this iframe in the test will make a FedCM call on load, and
+// trigger a postMessage upon completion.
+//
+// message {
+// string result: "Pass" | "Failed get" | "Failed disconnect"
+// string errorType: error.name
+// }
+async function attemptDisconnect() {
+ try {
+ await IdentityCredential.disconnect(disconnect_options("1234"));
+ window.top.postMessage({result: "Pass"}, "*");
+ } catch (error) {
+ window.top.postMessage({result: "Failed disconnect", errorType: error.name},
+ "*");
+ }
+}
+
+window.onload = async () => {
+ const params = new URLSearchParams(document.location.search);
+ if (params.has("skip_get")) {
+ attemptDisconnect();
+ return;
+ }
+
+ // Use this variable to stop trying to select an account once the get()
+ // promise is resolved.
+ let cancelHelper = false;
+ try {
+ const credentialPromise = navigator.credentials.get(request_options_with_mediation_required());
+ async function helper() {
+ try {
+ if (cancelHelper)
+ return;
+
+ await window.test_driver.select_fedcm_account(0);
+ } catch (ex) {
+ setTimeout(helper, 100);
+ }
+ }
+ helper();
+ const cred = await credentialPromise;
+ await set_fedcm_cookie(manifest_origin);
+ // Now that we have a get(), attempt to disconnect permission.
+ attemptDisconnect();
+ } catch (error) {
+ window.top.postMessage({result: "Failed get", errorType: error.name}, '*');
+ }
+ // In case the get() call fails and no accounts may be selected, force the
+ // helper function to stop calling itself.
+ cancelHelper = true;
+};
+</script>
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/disconnect.py b/testing/web-platform/tests/credential-management/support/fedcm/disconnect.py
new file mode 100644
index 0000000000..cf62ceda22
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/disconnect.py
@@ -0,0 +1,14 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ response.headers.set(b"Content-Type", b"application/json")
+ response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"origin"))
+ response.headers.set(b"Access-Control-Allow-Credentials", b"true")
+ request_error = error_checker.revokeCheck(request)
+ if request_error:
+ return request_error
+
+ # Pass the account_hint as the accountId.
+ account_hint = request.POST.get(b"account_hint")
+ return f"{{\"account_id\": \"{account_hint}\"}}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/disconnect_failure.py b/testing/web-platform/tests/credential-management/support/fedcm/disconnect_failure.py
new file mode 100644
index 0000000000..f880218b2f
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/disconnect_failure.py
@@ -0,0 +1,8 @@
+import importlib
+
+def main(request, response):
+ response.headers.set(b"Content-Type", b"application/json")
+ response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"origin"))
+ response.headers.set(b"Access-Control-Allow-Credentials", b"true")
+
+ return (599, [], "Server failure")
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/error_with_code_and_url.py b/testing/web-platform/tests/credential-management/support/fedcm/error_with_code_and_url.py
new file mode 100644
index 0000000000..71bfea00f4
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/error_with_code_and_url.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+ response.status = (401, b"Unauthorized")
+
+ return "{\"error\": {\"code\": \"unauthorized_client\", \"url\": \"error.html\"}}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/intercept_service_worker.js b/testing/web-platform/tests/credential-management/support/fedcm/intercept_service_worker.js
new file mode 100644
index 0000000000..773e38fd21
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/intercept_service_worker.js
@@ -0,0 +1,10 @@
+var num_overridden = 0;
+
+self.addEventListener('fetch', event => {
+ const url = event.request.url;
+ if (url.indexOf('query_service_worker_intercepts.html') != -1) {
+ event.respondWith(new Response(num_overridden));
+ } else if (url.indexOf('credential-management/support') != -1) {
+ ++num_overridden;
+ }
+});
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/keys.py b/testing/web-platform/tests/credential-management/support/fedcm/keys.py
new file mode 100644
index 0000000000..6b7d67e21e
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/keys.py
@@ -0,0 +1,2 @@
+CLIENT_METADATA_COUNTER_KEY = b"bdc14e3e-b8bc-44a1-8eec-78da5fdacbc3"
+MANIFEST_URL_IN_MANIFEST_LIST_KEY = b"7f3f7478-b7f0-41c5-b357-f3ac16f5f25a"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/login.html b/testing/web-platform/tests/credential-management/support/fedcm/login.html
new file mode 100644
index 0000000000..78d241cda9
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/login.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<script>
+async function doLogin() {
+ document.cookie = "accounts=1";
+ navigator.login.setStatus("logged-in");
+ IdentityProvider.close();
+}
+window.onload = doLogin;
+</script>
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest-not-in-list.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest-not-in-list.json
new file mode 100644
index 0000000000..0070066667
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest-not-in-list.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest.py b/testing/web-platform/tests/credential-management/support/fedcm/manifest.py
new file mode 100644
index 0000000000..a40fc100ee
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest.py
@@ -0,0 +1,19 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.manifestCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token.py",
+ "disconnect_endpoint": "disconnect.py",
+ "login_url": "login.html"
+}
+"""
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json
new file mode 100644
index 0000000000..e098cc4511
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "error_with_code_and_url.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_no_login_url.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_no_login_url.json
new file mode 100644
index 0000000000..15a657c679
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_no_login_url.json
@@ -0,0 +1,5 @@
+{
+ "accounts_endpoint": "single_account.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_account_id.py"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_accounts.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_accounts.json
new file mode 100644
index 0000000000..6a8972feeb
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_accounts.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "/common/redirect.py?location=/credential-management/support/fedcm/accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_token.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_token.json
new file mode 100644
index 0000000000..867b4dffb7
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_redirect_token.json
@@ -0,0 +1,7 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "/common/redirect.py?location=/credential-management/support/fedcm/token.py&status=308",
+ "disconnect_endpoint": "disconnect.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_token_with_http_error.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_token_with_http_error.json
new file mode 100644
index 0000000000..691a1e8d3a
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_token_with_http_error.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_http_error.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_auto_selected_flag.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_auto_selected_flag.json
new file mode 100644
index 0000000000..591c927153
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_auto_selected_flag.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "two_accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_auto_selected_flag.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_continue_on.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_continue_on.json
new file mode 100644
index 0000000000..3f5a954b87
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_continue_on.json
@@ -0,0 +1,8 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "continue_on.py",
+ "disconnect_endpoint": "disconnect.py",
+ "login_url": "login.html"
+}
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_cross_origin_disconnect.sub.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_cross_origin_disconnect.sub.json
new file mode 100644
index 0000000000..a1ad5c71ac
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_cross_origin_disconnect.sub.json
@@ -0,0 +1,7 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token.py",
+ "disconnect_endpoint": "https://{{hosts[alt][]}}:{{ports[https][0]}}/credential-management/support/fedcm/disconnect.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_disconnect_failure.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_disconnect_failure.json
new file mode 100644
index 0000000000..96035e7e8b
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_disconnect_failure.json
@@ -0,0 +1,7 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token.py",
+ "disconnect_endpoint": "disconnect_failure.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_no_accounts.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_no_accounts.json
new file mode 100644
index 0000000000..0d38f26d35
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_no_accounts.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "no_accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_account_id.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_single_account.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_single_account.json
new file mode 100644
index 0000000000..5f9b7a81b9
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_single_account.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "single_account.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_account_id.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_two_accounts.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_two_accounts.json
new file mode 100644
index 0000000000..6310fb0a0b
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_two_accounts.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "two_accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_account_id.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_variable_accounts.json b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_variable_accounts.json
new file mode 100644
index 0000000000..10c2ddd55d
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/manifest_with_variable_accounts.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "variable_accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_account_id.py",
+ "login_url": "login.html"
+}
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/no_accounts.py b/testing/web-platform/tests/credential-management/support/fedcm/no_accounts.py
new file mode 100644
index 0000000000..8767c50afb
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/no_accounts.py
@@ -0,0 +1,17 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.accountsCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{
+ "accounts": [
+ ]
+}
+"""
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/pending-userinfo-iframe.html b/testing/web-platform/tests/credential-management/support/fedcm/pending-userinfo-iframe.html
new file mode 100644
index 0000000000..0afe279bcc
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/pending-userinfo-iframe.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script type="module">
+import {alt_manifest_origin} from './../fedcm-helper.sub.js';
+
+// Invokes getUserInfo and immediately sends a message to the parent frame.
+window.onload = async () => {
+ try {
+ const manifest_path = `${alt_manifest_origin}/\
+credential-management/support/fedcm/manifest.py`;
+ IdentityProvider.getUserInfo({
+ configURL: manifest_path,
+ // Approved client
+ clientId: '123',
+ });
+ window.top.postMessage("Pass", '*');
+ } catch (error) {
+ window.top.postMessage("Fail", '*');
+ }
+};
+
+</script>
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/request-params-check.py b/testing/web-platform/tests/credential-management/support/fedcm/request-params-check.py
new file mode 100644
index 0000000000..daf91aad8f
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/request-params-check.py
@@ -0,0 +1,101 @@
+def commonCheck(request, mode=b"no-cors"):
+ if request.headers.get(b"Accept") != b"application/json":
+ return (531, [], "Wrong Accept")
+ if request.headers.get(b"Sec-Fetch-Dest") != b"webidentity":
+ return (532, [], "Wrong Sec-Fetch-Dest header")
+ if request.headers.get(b"Referer"):
+ return (533, [], "Should not have Referer")
+ if request.headers.get(b"Sec-Fetch-Mode") != mode:
+ return (534, [], "Wrong Sec-Fetch-Mode header")
+
+def commonUncredentialedRequestCheck(request):
+ if len(request.cookies) > 0:
+ return (535, [], "Cookie should not be sent to this endpoint")
+ if request.headers.get(b"Sec-Fetch-Site") != b"cross-site":
+ return (536, [], "Wrong Sec-Fetch-Site header")
+
+def commonCredentialedRequestCheck(request):
+ if request.cookies.get(b"cookie") != b"1":
+ return (537, [], "Missing cookie")
+ if request.headers.get(b"Sec-Fetch-Site") != b"none":
+ return (538, [], "Wrong Sec-Fetch-Site header")
+
+def commonPostCheck(request):
+ if not request.headers.get(b"Origin"):
+ return (540, [], "Missing Origin")
+ if request.method != "POST":
+ return (541, [], "Method is not POST")
+ if request.headers.get(b"Content-Type") != b"application/x-www-form-urlencoded":
+ return (542, [], "Wrong Content-Type")
+ if not request.POST.get(b"client_id"):
+ return (543, [], "Missing 'client_id' POST parameter")
+
+def manifestCheck(request):
+ common_error = commonCheck(request)
+ if (common_error):
+ return common_error
+ common_uncredentialed_error = commonUncredentialedRequestCheck(request)
+ if (common_uncredentialed_error):
+ return common_uncredentialed_error
+
+ if request.headers.get(b"Origin"):
+ return (539, [], "Should not have Origin")
+
+def clientMetadataCheck(request):
+ if (request.GET.get(b'skip_checks', b'0') != b'1'):
+ common_error = commonCheck(request)
+ if (common_error):
+ return common_error
+ common_uncredentialed_error = commonUncredentialedRequestCheck(request)
+ if (common_uncredentialed_error):
+ return common_uncredentialed_error
+
+ if not request.headers.get(b"Origin"):
+ return (540, [], "Missing Origin")
+
+def accountsCheck(request):
+ common_error = commonCheck(request)
+ if (common_error):
+ return common_error
+ common_credentialed_error = commonCredentialedRequestCheck(request)
+ if (common_credentialed_error):
+ return common_credentialed_error
+
+ if request.headers.get(b"Origin"):
+ return (539, [], "Should not have Origin")
+
+def tokenCheck(request):
+ common_error = commonCheck(request)
+ if (common_error):
+ return common_error
+ common_credentialed_error = commonCredentialedRequestCheck(request)
+ if (common_credentialed_error):
+ return common_credentialed_error
+
+ post_error = commonPostCheck(request)
+ if (post_error):
+ return post_error
+
+ if not request.POST.get(b"account_id"):
+ return (544, [], "Missing 'account_id' POST parameter")
+ if not request.POST.get(b"disclosure_text_shown"):
+ return (545, [], "Missing 'disclosure_text_shown' POST parameter")
+
+def revokeCheck(request):
+ common_error = commonCheck(request, b"cors")
+ if (common_error):
+ return common_error
+
+ if request.cookies.get(b"cookie") != b"1":
+ return (537, [], "Missing cookie")
+ # The value of the Sec-Fetch-Site header can vary depending on the IdP origin
+ # but it should not be 'none'.
+ if request.headers.get(b"Sec-Fetch-Site") == b"none":
+ return (538, [], "Wrong Sec-Fetch-Site header")
+
+ post_error = commonPostCheck(request)
+ if (post_error):
+ return post_error
+
+ if not request.POST.get(b"account_hint"):
+ return (544, [], "Missing 'account_hint' POST parameter")
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/resolve.html b/testing/web-platform/tests/credential-management/support/fedcm/resolve.html
new file mode 100644
index 0000000000..87f5112cfd
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/resolve.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+async function doResolve() {
+ IdentityProvider.resolve("resolved token");
+}
+window.onload = doResolve;
+</script>
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/select_manifest_in_root_manifest.py b/testing/web-platform/tests/credential-management/support/fedcm/select_manifest_in_root_manifest.py
new file mode 100644
index 0000000000..d4f1efff6a
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/select_manifest_in_root_manifest.py
@@ -0,0 +1,17 @@
+import importlib
+from urllib.parse import urlsplit
+
+# 'import credential-management.support.fedcm.keys' does not work.
+keys = importlib.import_module("credential-management.support.fedcm.keys")
+
+def main(request, response):
+ root_manifest_url = "/.well-known/web-identity"
+
+ # Clear stash so that a new value can be written.
+ request.server.stash.take(keys.MANIFEST_URL_IN_MANIFEST_LIST_KEY, root_manifest_url)
+
+ request.server.stash.put(keys.MANIFEST_URL_IN_MANIFEST_LIST_KEY,
+ request.GET.first(b"manifest_url", b""),
+ root_manifest_url)
+
+ return root_manifest_url
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/simple.html b/testing/web-platform/tests/credential-management/support/fedcm/simple.html
new file mode 100644
index 0000000000..d62419ce8a
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/simple.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<html><body>
+Simple
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/single_account.py b/testing/web-platform/tests/credential-management/support/fedcm/single_account.py
new file mode 100644
index 0000000000..7c8906ae7b
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/single_account.py
@@ -0,0 +1,24 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.accountsCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{
+ "accounts": [
+ {
+ "id": "john_doe",
+ "given_name": "John",
+ "name": "John Doe",
+ "email": "john_doe@idp.example",
+ "picture": "https://idp.example/profile/123",
+ "approved_clients": ["123", "456", "789"]
+ }
+ ]
+}
+"""
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/token.py b/testing/web-platform/tests/credential-management/support/fedcm/token.py
new file mode 100644
index 0000000000..b914eb2d96
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/token.py
@@ -0,0 +1,11 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return "{\"token\": \"token\"}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/token_with_account_id.py b/testing/web-platform/tests/credential-management/support/fedcm/token_with_account_id.py
new file mode 100644
index 0000000000..52fb20184b
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/token_with_account_id.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ account_id = request.POST.get(b"account_id")
+ return "{\"token\": \"account_id=" + account_id.decode("utf-8") + "\"}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/token_with_auto_selected_flag.py b/testing/web-platform/tests/credential-management/support/fedcm/token_with_auto_selected_flag.py
new file mode 100644
index 0000000000..93ccf3ee7e
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/token_with_auto_selected_flag.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ is_auto_selected = request.POST.get(b"is_auto_selected")
+ return "{\"token\": \"is_auto_selected=" + is_auto_selected.decode("utf-8") + "\"}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/token_with_http_error.py b/testing/web-platform/tests/credential-management/support/fedcm/token_with_http_error.py
new file mode 100644
index 0000000000..c8d95ab63d
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/token_with_http_error.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+ response.status = (403, b"Forbidden")
+
+ return "{\"token\": \"token\"}"
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/two_accounts.py b/testing/web-platform/tests/credential-management/support/fedcm/two_accounts.py
new file mode 100644
index 0000000000..4022561ff7
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/two_accounts.py
@@ -0,0 +1,34 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.accountsCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ return """
+{
+ "accounts": [
+ {
+ "id": "jane_doe",
+ "given_name": "Jane",
+ "name": "Jane Doe",
+ "email": "jane_doe@idp.example",
+ "picture": "https://idp.example/profile/5678",
+ "approved_clients": ["123", "abc"]
+ },
+ {
+ "id": "john_doe",
+ "given_name": "John",
+ "name": "John Doe",
+ "email": "john_doe@idp.example",
+ "picture": "https://idp.example/profile/123",
+ "approved_clients": ["123", "456", "789"],
+ "login_hints": ["john_doe"],
+ "domain_hints": ["idp.example", "example"]
+ }
+ ]
+}
+"""
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/userinfo-iframe.html b/testing/web-platform/tests/credential-management/support/fedcm/userinfo-iframe.html
new file mode 100644
index 0000000000..45a1a34ce9
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/userinfo-iframe.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<script type="module">
+import {alt_manifest_origin} from './../fedcm-helper.sub.js';
+
+// Loading fedcm-iframe.html in the test will make a FedCM call on load, and
+// trigger a postMessage upon completion.
+//
+// message {
+// string result: "Pass" | "Fail"
+// string token: token.token
+// string errorType: error.name
+// }
+window.onload = async () => {
+ try {
+ const manifest_path = `${alt_manifest_origin}/\
+credential-management/support/fedcm/manifest.py`;
+ const user_info = await IdentityProvider.getUserInfo({
+ configURL: manifest_path,
+ // Approved client
+ clientId: '123',
+ });
+ let results = {
+ result: "Pass",
+ numAccounts: user_info.length,
+ firstAccountEmail: user_info[0].email,
+ firstAccountName: user_info[0].name,
+ firstAccountGivenName: user_info[0].givenName,
+ firstAccountPicture: user_info[0].picture
+ };
+ window.top.postMessage(results, '*');
+ } catch (error) {
+ window.top.postMessage({result: "Fail", errorType: error.name}, '*');
+ }
+};
+
+</script>
+
diff --git a/testing/web-platform/tests/credential-management/support/fedcm/variable_accounts.py b/testing/web-platform/tests/credential-management/support/fedcm/variable_accounts.py
new file mode 100644
index 0000000000..c9db2c4528
--- /dev/null
+++ b/testing/web-platform/tests/credential-management/support/fedcm/variable_accounts.py
@@ -0,0 +1,33 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.accountsCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+
+ if request.cookies.get(b"accounts") != b"1":
+ return """
+{
+ "accounts": [
+ ]
+}
+"""
+
+
+ return """
+{
+ "accounts": [{
+ "id": "1234",
+ "given_name": "John",
+ "name": "John Doe",
+ "email": "john_doe@idp.example",
+ "picture": "https://idp.example/profile/123",
+ "approved_clients": ["123", "456", "789"],
+ "login_hints": ["john_doe"],
+ "hosted_domains": ["idp.example", "example"]
+ }]
+}
+"""