Skip to content

Commit

Permalink
Digital Credentials: implement digital-credentials-get permission policy
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=275783
rdar://130821690

Reviewed by NOBODY (OOPS!).

Implements the digital-credentials-get permission policy directive.
This directive allows a site to control whether the .get() method
can be used in the Digital Credential API.

Related spec change:
WICG/digital-credentials#132

* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/allow-attribute.https-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/allow-attribute.https.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/override-permissions-policy.https.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/override-permissions-policy.https.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/override-permissions-policy.https.sub.html.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/digital-credentials/support/iframe.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/permissions-policy.js:
(test_feature_availability):
* Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp:
(WebCore::IdentityCredentialsContainer::get):
* Source/WebCore/html/PermissionsPolicy.cpp:
(WebCore::toFeatureNameForLogging):
(WebCore::readFeatureIdentifier):
(WebCore::defaultAllowlistValue):
* Source/WebCore/html/PermissionsPolicy.h:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
  • Loading branch information
marcoscaceres committed Jul 17, 2024
1 parent aadfa72 commit 00126ee
Show file tree
Hide file tree
Showing 20 changed files with 460 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

PASS Policy to use: null, is cross-origin: false, is allowed by policy: true
PASS Policy to use: null, is cross-origin: true, is allowed by policy: false
PASS Policy to use: digital-credentials-get, is cross-origin: false, is allowed by policy: true
PASS Policy to use: digital-credentials-get, is cross-origin: true, is allowed by policy: true
PASS Policy to use: digital-credentials-get *, is cross-origin: true, is allowed by policy: true
PASS Policy to use: digital-credentials-get *, is cross-origin: false, is allowed by policy: true
PASS Policy to use: digital-credentials-get 'none', is cross-origin: true, is allowed by policy: false
PASS Policy to use: digital-credentials-get 'none', is cross-origin: false, is allowed by policy: false
PASS Policy to use: digital-credentials-get 'self', is cross-origin: true, is allowed by policy: false
PASS Policy to use: digital-credentials-get 'self', is cross-origin: false, is allowed by policy: true
PASS Policy to use: digital-credentials-get https://127.0.0.1:9443, is cross-origin: true, is allowed by policy: true
PASS Policy to use: digital-credentials-get https://127.0.0.1:9443, is cross-origin: false, is allowed by policy: false

Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test allow attribute with "digital-credentials-get" and
CredentialsContainer's .get() method
</title>
<script src="/common/get-host-info.sub.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const hostInfo = get_host_info();
const iframeDetails = [
{
policy: null,
crossOrigin: false,
isAllowed: true,
},
{
policy: null,
crossOrigin: true,
isAllowed: false,
},
{
policy: "digital-credentials-get",
crossOrigin: false,
isAllowed: true,
},
{
policy: "digital-credentials-get",
crossOrigin: true,
isAllowed: true,
},
{
policy: "digital-credentials-get *",
crossOrigin: true,
isAllowed: true,
},
{
policy: "digital-credentials-get *",
crossOrigin: false,
isAllowed: true,
},
{
policy: "digital-credentials-get 'none'",
crossOrigin: true,
isAllowed: false,
},
{
policy: "digital-credentials-get 'none'",
crossOrigin: false,
isAllowed: false,
},
{
policy: "digital-credentials-get 'self'",
crossOrigin: true,
isAllowed: false,
},
{
policy: "digital-credentials-get 'self'",
crossOrigin: false,
isAllowed: true,
},
{
policy: `digital-credentials-get ${hostInfo.HTTPS_REMOTE_ORIGIN}`,
crossOrigin: true,
isAllowed: true,
},
{
policy: `digital-credentials-get ${hostInfo.HTTPS_REMOTE_ORIGIN}`,
crossOrigin: false,
isAllowed: false,
},
];

async function loadIframe({ policy, crossOrigin, isAllowed }) {
const iframe = document.createElement("iframe");
if (policy !== null) {
iframe.allow = policy;
}

iframe.src = new URL(
"/digital-credentials/support/iframe.html",
crossOrigin ? hostInfo.HTTPS_REMOTE_ORIGIN : location.origin
).href;
iframe.dataset.isAllowed = isAllowed;

await new Promise((resolve) => {
iframe.onload = resolve;
document.body.appendChild(iframe);
});
iframe.focus();
return iframe;
}

function runTests() {
for (const details of iframeDetails) {
promise_test(async (test) => {
const iframe = await loadIframe(details);
const { isAllowed } = details;
const action = "get";
const options = {
digital: { providers: [] },
};
const { data } = await new Promise((resolve) => {
window.addEventListener("message", resolve, {
once: true,
});
iframe.contentWindow.postMessage({ action, options }, "*");
});
const { name, messsage } = data;
assert_equals(
name,
isAllowed ? "TypeError" : "NotAllowedError",
`${iframe.outerHTML} - ${messsage}`
);
iframe.remove();
}, `Policy to use: ${details.policy}, is cross-origin: ${details.crossOrigin}, is allowed by policy: ${details.isAllowed}`);
}
}
</script>
</head>
<body onload="runTests()"></body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

PASS Permissions-Policy is by default 'self'.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/permissions-policy/resources/permissions-policy.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body></body>
<script>
"use strict";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
const same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;

promise_test(async (test) => {
await test_driver.bless("use activation");
await promise_rejects_js(
test,
TypeError,
navigator.identity.get({ digital: { providers: [] } })
);

await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: same_origin_src,
expect_feature_available: expect_feature_available_default,
is_promise_test: true,
});

await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: cross_origin_src,
expect_feature_available: expect_feature_unavailable_default,
feature_name: "digital-credentials-get",
is_promise_test: true,
});
}, "Permissions-Policy is by default 'self'.");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


FAIL Permissions-Policy header digital-credentials-get=() disallows the top-level document. promise_rejects_dom: function "function() { throw e }" threw object "TypeError: At least one provider must be specified." that is not a DOMException NotAllowedError: property "code" is equal to undefined, expected 0
FAIL Permissions-Policy header digital-credentials-get=() disallows same-origin iframes. assert_false: Digital Credential API expected false got true

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/permissions-policy/resources/permissions-policy.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body></body>
<script>
"use strict";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
const same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;

promise_test(async (test) => {
await test_driver.bless("user activation");
await promise_rejects_dom(
test,
"NotAllowedError",
navigator.identity.get({ digital: { providers: [] } })
);
}, "Permissions-Policy header digital-credentials-get=() disallows the top-level document.");

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: same_origin_src,
expect_feature_available: expect_feature_unavailable_default,
is_promise_test: true,
needs_focus: true,
});
}, "Permissions-Policy header digital-credentials-get=() disallows same-origin iframes.");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Permissions-Policy: digital-credentials-get=()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

PASS Permissions-Policy header digital-credentials-get=(self) allows the top-level document.
PASS Permissions-Policy header digital-credentials-get=(self) allows same-origin iframes.
PASS Permissions-Policy header digital-credentials-get=(self) disallows cross-origin iframes.
PASS Permissions-Policy header digital-credentials-get=(self) gets overridden by allow attribute.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/permissions-policy/resources/permissions-policy.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body></body>
<script>
"use strict";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
const same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;

promise_test(async (test) => {
await test_driver.bless("use activation");
await promise_rejects_js(
test,
TypeError,
navigator.identity.get({ digital: { providers: [] } })
);
}, "Permissions-Policy header digital-credentials-get=(self) allows the top-level document.");

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: same_origin_src,
expect_feature_available: expect_feature_available_default,
is_promise_test: true,
needs_focus: true,
});
}, "Permissions-Policy header digital-credentials-get=(self) allows same-origin iframes.");

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: cross_origin_src,
expect_feature_available: expect_feature_unavailable_default,
is_promise_test: true,
needs_focus: true,
});
}, "Permissions-Policy header digital-credentials-get=(self) disallows cross-origin iframes.");

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: cross_origin_src,
expect_feature_available: expect_feature_available_default,
feature_name: "digital-credentials-get",
is_promise_test: true,
needs_focus: true,
});
}, "Permissions-Policy header digital-credentials-get=(self) gets overridden by allow attribute.");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Permissions-Policy: digital-credentials-get=(self)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


PASS Header-set policy is overridden in cross-origin iframe using allow attribute.
FAIL Setting digital-credentials-get=(self) disallows the API in same-origin iframes. assert_false: Digital Credential API expected false got true

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/permissions-policy/resources/permissions-policy.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body></body>
<script>
"use strict";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
const same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: cross_origin_src,
expect_feature_available: expect_feature_available_default,
feature_name: "digital-credentials-get",
is_promise_test: true,
needs_focus: true,
});
}, "Header-set policy is overridden in cross-origin iframe using allow attribute.");

promise_test(async (test) => {
await test_feature_availability({
feature_description: "Digital Credential API",
test,
src: same_origin_src,
expect_feature_available: expect_feature_unavailable_default,
is_promise_test: true,
needs_focus: true,
});
}, "Setting digital-credentials-get=(self) disallows the API in same-origin iframes.");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Permissions-Policy: digital-credentials-get=()
Loading

0 comments on commit 00126ee

Please sign in to comment.