diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/credential-management/support/fedcm | |
parent | Initial commit. (diff) | |
download | firefox-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')
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"] + }] +} +""" |