Bug 1642579 [wpt PR 23909] - [COOP access reporting] Preliminary WPT tests., a=testonly

Automatic update from web-platform-tests
[COOP access reporting] Preliminary WPT tests.

Add some basic WPT tests about the COOP access reporting feature.
No web browsers actually implement this. As a result, chrome do not
pass them yet.
The tests aren't complete yet, they will evolve along the specification
and the implementations.

Bug: 922191
Change-Id: I9aa03e727252086eb64c0110afc9b5885b66802d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2225757
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Auto-Submit: Arthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: Pâris Meuleman <pmeuleman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774599}

--

wpt-commits: cbb4b64833f40c8089ba67d4fe807ffba603e6b5
wpt-pr: 23909
This commit is contained in:
arthursonzogni 2020-06-10 11:24:52 +00:00 committed by moz-wptsync-bot
parent f0a2dcd688
commit b1b35f55bb
8 changed files with 429 additions and 0 deletions

View File

@ -0,0 +1,6 @@
suggested_reviewers:
- ArthurSonzogni
- ParisMeuleman
- camillelamy
- hemeryar
- mikewest

View File

@ -0,0 +1,84 @@
<title>
COOP reports are sent when the openee used COOP-RO+COEP and then its opener
tries to access it.
</title>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src="/common/utils.js"></script>
<script src="./resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/access-reporting";
const executor_path = directory + "/resources/executor.html?pipe=";
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
let operation = [
//[test name , operation ] ,
["Call blur" , w => w.blur() ] ,
["Call foo" , w => w.foo() ] ,
["Call location" , w => w.location() ] ,
["Call opener" , w => w.opener() ] ,
["Call postMessage" , w => w.postMessage() ] ,
["Call window" , w => w.window() ] ,
["Read blur" , w => w.blur ] ,
["Read foo" , w => w.foo ] ,
["Read location" , w => w.location ] ,
["Read opener" , w => w.opener ] ,
["Read postMessage" , w => w.postMessage ] ,
["Read window" , w => w.window ] ,
["Write blur" , w => w.blur = "test" ] ,
["Write foo" , w => w.foo = "test" ] ,
["Write location" , w => w.location = "test" ] ,
["Write opener" , w => w.opener = "test" ] ,
["Write postMessage" , w => w.postMessage = "test" ] ,
["Write window" , w => w.window = "test" ] ,
];
operation.forEach(([test, op]) => {
promise_test(async t => {
const report_token = token();
const executor_token = token();
const callback_token = token();
const reportTo = reportToHeaders(report_token);
const openee_url = cross_origin + executor_path +
reportTo.header + reportTo.coopReportOnlySameOrigin + coep_header +
`&uuid=${executor_token}`;
const openee = window.open(openee_url);
t.add_cleanup(() => send(executor_token, "window.close()"))
// 1. Make sure the new document to be loaded.
send(executor_token, `
send("${callback_token}", "Ready");
`);
let reply = await receive(callback_token);
assert_equals(reply, "Ready");
// 2. Skip the first report about the opener breakage.
let report_1 = await receive(report_token);
assert_not_equals(report_1, "timeout");
report_1 = JSON.parse(report_1);
assert_equals(report_1.length, 1);
assert_equals(report_1[0].type, "coop");
assert_equals(report_1[0].body["violation-type"], "navigation-to-document");
assert_equals(report_1[0].body["disposition"], "reporting");
// 3. Try to access the openee. A report is sent, because of COOP-RO+COEP.
try {op(openee)} catch(e) {}
// 4. A COOP access reports must be sent as a result of (3).
let report_2 = await receive(report_token);
assert_not_equals(report_1, "timeout");
report_2 = JSON.parse(report_2);
assert_equals(report_2.length, 1);
assert_equals(report_2[0].type, "coop");
assert_equals(report_2[0].body["violation-type"], "access");
assert_equals(report_2[0].body["disposition"], "reporting");
assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep");
}, `${test}`);
});
</script>

View File

@ -0,0 +1,84 @@
<title>
COOP reports are sent when the openee used COOP+COEP and then its opener
tries to access it.
</title>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src="/common/utils.js"></script>
<script src="./resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/access-reporting";
const executor_path = directory + "/resources/executor.html?pipe=";
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
let operation = [
//[test name , operation ] ,
["Call blur" , w => w.blur() ] ,
["Call foo" , w => w.foo() ] ,
["Call location" , w => w.location() ] ,
["Call opener" , w => w.opener() ] ,
["Call postMessage" , w => w.postMessage() ] ,
["Call window" , w => w.window() ] ,
["Read blur" , w => w.blur ] ,
["Read foo" , w => w.foo ] ,
["Read location" , w => w.location ] ,
["Read opener" , w => w.opener ] ,
["Read postMessage" , w => w.postMessage ] ,
["Read window" , w => w.window ] ,
["Write blur" , w => w.blur = "test" ] ,
["Write foo" , w => w.foo = "test" ] ,
["Write location" , w => w.location = "test" ] ,
["Write opener" , w => w.opener = "test" ] ,
["Write postMessage" , w => w.postMessage = "test" ] ,
["Write window" , w => w.window = "test" ] ,
];
operation.forEach(([test, op]) => {
promise_test(async t => {
const report_token = token();
const executor_token = token();
const callback_token = token();
const reportTo = reportToHeaders(report_token);
const openee_url = cross_origin + executor_path +
reportTo.header + reportTo.coopSameOrigin + coep_header +
`&uuid=${executor_token}`;
const openee = window.open(openee_url);
t.add_cleanup(() => send(executor_token, "window.close()"))
// 1. Make sure the new document to be loaded.
send(executor_token, `
send("${callback_token}", "Ready");
`);
let reply = await receive(callback_token);
assert_equals(reply, "Ready");
// 2. Skip the first report about the opener breakage.
let report_1 = await receive(report_token);
assert_not_equals(report_1, "timeout");
report_1 = JSON.parse(report_1);
assert_equals(report_1.length, 1);
assert_equals(report_1[0].type, "coop");
assert_equals(report_1[0].body["violation-type"], "navigation-to-document");
assert_equals(report_1[0].body["disposition"], "enforce");
// 3. Try to access the openee. This shouldn't work because of COOP+COEP.
try {op(openee)} catch(e) {}
// 4. A COOP access reports must be sent as a result of (3).
let report_2 = await receive(report_token);
assert_not_equals(report_2, "timeout");
report_2 = JSON.parse(report_2);
assert_equals(report_2.length, 1);
assert_equals(report_2[0].type, "coop");
assert_equals(report_2[0].body["violation-type"], "access");
assert_equals(report_2[0].body["disposition"], "enforce");
assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep");
}, `${test}`);
});
</script>

View File

@ -0,0 +1,83 @@
<title>
COOP reports are sent when the openee used COOP-RO+COEP and then tries to
access its opener.
</title>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src="/common/utils.js"></script>
<script src="./resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/access-reporting";
const executor_path = directory + "/resources/executor.html?pipe=";
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
let operation = [
//[test name , operation ] ,
["Call blur" , "opener.blur()" ] ,
["Call foo" , "opener.foo()" ] ,
["Call location" , "opener.location()" ] ,
["Call opener" , "opener.opener()" ] ,
["Call postMessage" , "opener.postMessage()" ] ,
["Call window" , "opener.window()" ] ,
["Read blur" , "opener.blur" ] ,
["Read foo" , "opener.foo" ] ,
["Read location" , "opener.location" ] ,
["Read opener" , "opener.opener" ] ,
["Read postMessage" , "opener.postMessage" ] ,
["Read window" , "opener.window" ] ,
["Write blur" , "opener.blur = 'test'" ] ,
["Write foo" , "opener.foo = 'test'" ] ,
["Write location" , "opener.location = 'test'" ] ,
["Write opener" , "opener.opener = 'test'" ] ,
["Write postMessage" , "opener.postMessage = 'test'" ] ,
["Write window" , "opener.window = 'test'" ] ,
];
operation.forEach(([test, op]) => {
promise_test(async t => {
const report_token = token();
const executor_token = token();
const callback_token = token();
const reportTo = reportToHeaders(report_token);
const openee_url = cross_origin + executor_path +
reportTo.header + reportTo.coopReportOnlySameOrigin + coep_header +
`&uuid=${executor_token}`;
const openee = window.open(openee_url);
t.add_cleanup(() => send(executor_token, "window.close()"))
// 1. Skip the first report about the opener breakage.
let report_1 = await receive(report_token);
assert_not_equals(report_1, "timeout");
report_1 = JSON.parse(report_1);
assert_equals(report_1.length, 1);
assert_equals(report_1[0].type, "coop");
assert_equals(report_1[0].body["violation-type"], "navigation-to-document");
assert_equals(report_1[0].body["disposition"], "reporting");
// 3. Try to access the opener. A report is sent, because of COOP-RO+COEP.
send(executor_token, `
try {${op}} catch(e) {}
send("${callback_token}", "Done");
`);
let reply = await receive(callback_token);
assert_equals(reply, "Done");
// 4. A COOP access reports must be sent as a result of (3).
let report_2 = await receive(report_token);
assert_not_equals(report_2, "timeout");
report_2 = JSON.parse(report_2);
assert_equals(report_2.length, 1);
assert_equals(report_2[0].type, "coop");
assert_equals(report_2[0].body["violation-type"], "access");
assert_equals(report_2[0].body["disposition"], "reporting");
assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep");
}, `${test}`);
});
</script>

View File

@ -0,0 +1,83 @@
<title>
COOP reports are sent when the openee used COOP+COEP and then tries to
access its opener.
</title>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src="/common/utils.js"></script>
<script src="./resources/dispatcher.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/access-reporting";
const executor_path = directory + "/resources/executor.html?pipe=";
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
let operation = [
//[test name , operation ] ,
["Call blur" , "opener.blur()" ] ,
["Call foo" , "opener.foo()" ] ,
["Call location" , "opener.location()" ] ,
["Call opener" , "opener.opener()" ] ,
["Call postMessage" , "opener.postMessage()" ] ,
["Call window" , "opener.window()" ] ,
["Read blur" , "opener.blur" ] ,
["Read foo" , "opener.foo" ] ,
["Read location" , "opener.location" ] ,
["Read opener" , "opener.opener" ] ,
["Read postMessage" , "opener.postMessage" ] ,
["Read window" , "opener.window" ] ,
["Write blur" , "opener.blur = 'test'" ] ,
["Write foo" , "opener.foo = 'test'" ] ,
["Write location" , "opener.location = 'test'" ] ,
["Write opener" , "opener.opener = 'test'" ] ,
["Write postMessage" , "opener.postMessage = 'test'" ] ,
["Write window" , "opener.window = 'test'" ] ,
];
operation.forEach(([test, op]) => {
promise_test(async t => {
const report_token = token();
const executor_token = token();
const callback_token = token();
const reportTo = reportToHeaders(report_token);
const openee_url = cross_origin + executor_path +
reportTo.header + reportTo.coopSameOrigin + coep_header +
`&uuid=${executor_token}`;
const openee = window.open(openee_url);
t.add_cleanup(() => send(executor_token, "window.close()"));
// 1. Skip the first report about the opener breakage.
let report_1 = await receive(report_token);
assert_not_equals(report_1, "timeout");
report_1 = JSON.parse(report_1);
assert_equals(report_1.length, 1);
assert_equals(report_1[0].type, "coop");
assert_equals(report_1[0].body["violation-type"], "navigation-to-document");
assert_equals(report_1[0].body["disposition"], "enforce");
// 3. Try to access the opener. A report is sent, because of COOP-RO+COEP.
send(executor_token, `
try {${op}} catch(e) {}
send("${callback_token}", "Done");
`);
let reply = await receive(callback_token);
assert_equals(reply, "Done");
// 4. A COOP access reports must be sent as a result of (3).
let report_2 = await receive(report_token);
assert_not_equals(report_2, "timeout");
report_2 = JSON.parse(report_2);
assert_equals(report_2.length, 1);
assert_equals(report_2[0].type, "coop");
assert_equals(report_2[0].body["violation-type"], "access");
assert_equals(report_2[0].body["disposition"], "enforce");
assert_equals(report_2[0].body["effective-policy"], "same-origin-plus-coep");
}, `${test}`);
});
</script>

View File

@ -0,0 +1,55 @@
// Define an universal message passing API.
//
// In particular, this works:
// - cross-origin and
// - cross-browsing-context-group.
//
// It can also be used to receive reports.
const dispatcher_path =
'/html/cross-origin-opener-policy/access-reporting/resources/dispatcher.py';
const dispatcher_url = new URL(dispatcher_path, location.href).href;
const send = function(uuid, message) {
fetch(dispatcher_url + `?uuid=${uuid}`, {
method: 'POST',
body: message
});
}
const receive = async function(uuid) {
const timeout = 2500;
const retry_delay = 100;
for(let i = 0; i * retry_delay < timeout; ++i) {
let response = await fetch(dispatcher_url + `?uuid=${uuid}`);
let data = await response.text();
if (data != 'not ready')
return data;
await new Promise(r => step_timeout(r, retry_delay));
}
return "timeout";
}
// Build a set of headers to tests the reporting API. This defines a set of
// matching 'Report-To', 'Cross-Origin-Opener-Policy' and
// 'Cross-Origin-Opener-Policy-Report-Only' headers.
const reportToHeaders = function(uuid) {
const report_endpoint_url = dispatcher_path + `?uuid=${uuid}`;
let reportToJSON = {
'group': `${uuid}`,
'max_age': 3600,
'endpoints': [
{'url': report_endpoint_url.toString()},
]
};
reportToJSON = JSON.stringify(reportToJSON)
.replace(/,/g, '\\,')
.replace(/\(/g, '\\\(')
.replace(/\)/g, '\\\)=');
return {
header: `|header(report-to,${reportToJSON})`,
coopSameOrigin: `|header(Cross-Origin-Opener-Policy, same-origin%3Breport-to="${uuid}")`,
coopReportOnlySameOrigin: `|header(Cross-Origin-Opener-Policy-Report-Only, same-origin%3Breport-to="${uuid}")`,
};
};

View File

@ -0,0 +1,22 @@
# A server used to store and retrieve arbitrary data.
# This is used by: ./dispatcher.js
import json
def main(request, response):
response.headers.set('Access-Control-Allow-Origin', '*')
response.headers.set('Access-Control-Allow-Methods', 'OPTIONS, GET, POST')
response.headers.set('Access-Control-Allow-Headers', 'Content-Type')
response.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
if request.method == 'OPTIONS': # CORS preflight
return ''
uuid = request.GET['uuid']
if request.method == 'POST':
return request.server.stash.put(uuid, request.body)
else:
body = request.server.stash.take(uuid)
if body is None:
return 'not ready'
else:
return body

View File

@ -0,0 +1,12 @@
<script src=/resources/testharness.js></script>
<script src="./dispatcher.js"></script>
<script>
const params = new URLSearchParams(window.location.search);
const uuid = params.get('uuid');
let executeOrders = async function() {
while(true)
eval(await receive(uuid));
};
executeOrders();
</script>