Skip to content

Commit

Permalink
Change default classic script fetch options credentials mode
Browse files Browse the repository at this point in the history
This CL changes the default classic script fetch options credentials mode
from "omit" to "same-origin", as per the recent spec change [1], and adds
descendant worker credentials tests as a follow-up to said spec change and
[2].

[1]: whatwg/html#3656
[2]: #13426

R=domenic@chromium.org, kouhei@chromium.org, nhiroki@chromium.org

Bug: 849101
Change-Id: I958f552f0ee91beb8aab98269f79a1eb219fb40a
Reviewed-on: https://chromium-review.googlesource.com/c/1301964
Commit-Queue: Dominic Farolino <domfarolino@gmail.com>
Reviewed-by: Kouhei Ueno <kouhei@chromium.org>
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604862}
  • Loading branch information
domfarolino authored and chromium-wpt-export-bot committed Nov 2, 2018
1 parent 69a2952 commit 21cd6f0
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 26 deletions.
268 changes: 243 additions & 25 deletions workers/modules/dedicated-worker-options-credentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,302 @@
<title>DedicatedWorker: WorkerOptions 'credentials'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script>
host_info = get_host_info();

// Determines the expected cookie value to be reported by a dedicated worker
// based on the given option. The worker reports an empty string as the actual
// cookie value if the cookie wasn't sent to the server. Otherwise, it's the
// value set by the headers file:
// "dedicated-worker-options-credentials.html.headers"
function DetermineExpectedCookieValue(options) {
// Classic script loading should always send credentials regardless of the
// 'credentials' option because the spec says the option takes effect only
// for module script loading.
if (options.type == 'classic')
return 'COOKIE_VALUE';
assert_equals(options.type, 'module');

if (!options.credentials ||
options.credentials == 'same-origin' ||
options.credentials == 'include') {
return 'COOKIE_VALUE';
function DetermineExpectedCookieValue(options, config) {
// Valid WorkerOptions and test config checking.
if (config.origin !== 'same' && config.origin !== 'remote')
assert_unreached('Invalid config.origin was specified: ' + config.origin);
if (options.credentials && options.credentials !== 'omit' &&
options.credentials !== 'same-origin' &&
options.credentials !== 'include') {
assert_unreached('Invalid credentials option was specified: ' +
options.credentials);
}
if (options.credentials == 'omit')
if (options.type !== 'classic' && options.type !== 'module')
assert_unreached('Invalid type option was specified: ' + options.type);

if (options.type === 'classic')
return (config.origin === 'same') ? '1' : '';

if (options.credentials === 'omit')
return '';
assert_unreached('Invalid credentials option was specified: ' +
options.credentials);
else if (options.credentials === 'include')
return '1';
else
return (config.origin === 'same') ? '1' : '';
}

// Runs a credentials test with the given WorkerOptions.
function credentials_test(options, description) {
//
// |options| is a WorkerOptions dict.
// |config| has options as follows:
//
// config = {
// fetchType: 'top-level' or 'descendant-static' or 'descendant-dynamic'
// origin: 'remote' or 'same'
// };
//
// - |config.fetchType| indicates the type of script to load for the test.
// - |config.origin| indicates same-origin-ness of the script to load.
function credentials_test(options, config, description) {
promise_test(async () => {
const worker = new Worker('resources/credentials.py', options);
let workerURL, origin = config.origin;
if (config.fetchType === 'top-level') {
workerURL = 'resources/credentials.py';
} else if (config.fetchType === 'descendant-static') {
workerURL =
`resources/static-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
} else if (config.fetchType === 'descendant-dynamic') {
workerURL =
`resources/dynamic-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
} else {
assert_unreached('Invalid config.fetchType: ' + config.fetchType);
}

const worker = new Worker(workerURL, options);

// Wait until the worker sends the actual cookie value.
const msg_event = await new Promise(resolve => worker.onmessage = resolve);

const expectedCookieValue = DetermineExpectedCookieValue(options);
const expectedCookieValue = DetermineExpectedCookieValue(options, config);
assert_equals(msg_event.data, expectedCookieValue);
}, description);
}

// Tests for module scripts.
function init() {
// Same-origin cookie is set up in the .headers file in this directory.
promise_test(async () => {
return fetch(
`${host_info.HTTP_REMOTE_ORIGIN}/cookies/resources/set-cookie.py?name=COOKIE_NAME&path=/workers/modules/`,
{
mode: 'no-cors',
credentials: 'include'
});
}, 'Test initialization: setting up cross-origin cookie');
}

init();

// Tests for module workers.

credentials_test(
{ type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials');

credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials');

credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials');

credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials');

// Tests for module worker static imports.

credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials for ' +
'same-origin static imports');

credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials for same-origin static imports');

credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials for same-origin static imports');

credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for same-origin static imports');

credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and not send the credentials for ' +
'cross-origin static imports');

credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type-module credentials=omit should not send the ' +
'credentials for cross-origin static imports');

credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and credentials=same-origin should not ' +
'send the credentials for cross-origin static imports');

credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for cross-origin static imports');

// Tests for module worker dynamic imports.

credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials for ' +
'same-origin dynamic imports');

credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials for same-origin dynamic imports');

credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials for same-origin dynamic imports');

credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for same-origin dynamic imports');

credentials_test(
{ type: 'module'},
'new Worker() with the default credentials option should behave as ' +
'credentials=same-origin and send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and not send the credentials for ' +
'cross-origin dynamic imports');

credentials_test(
{ credentials: 'omit', type: 'module' },
'new Worker() with credentials=omit should not send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type-module credentials=omit should not send the ' +
'credentials for cross-origin dynamic imports');

credentials_test(
{ credentials: 'same-origin', type: 'module' },
'new Worker() with credentials=same-origin should send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and credentials=same-origin should not ' +
'send the credentials for cross-origin dynamic imports');

credentials_test(
{ credentials: 'include', type: 'module' },
'new Worker() with credentials=include should send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for cross-origin dynamic imports');

// Tests for classic scripts.
// Tests for classic workers.
// TODO(domfarolino): Maybe move classic worker tests up a directory?

credentials_test(
{ type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (default).');

credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (omit).');

credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (same-origin).');

credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (include).');

// Tests for classic worker dynamic imports.

credentials_test(
{ type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(default).');

credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option (omit).');

credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(same-origin).');

credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(include).');

credentials_test(
{ type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(default).');

credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(omit).');

credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(same-origin).');

credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(include).');

</script>
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Set-Cookie: COOKIE_NAME=COOKIE_VALUE
Set-Cookie: COOKIE_NAME=1
Access-Control-Allow-Credentials: true
1 change: 1 addition & 0 deletions workers/modules/resources/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ def main(request, response):
cookie = request.cookies.first("COOKIE_NAME", None)

response_headers = [("Content-Type", "text/javascript"),
("Access-Control-Allow-Origin", request.headers.get("Origin")),
("Access-Control-Allow-Credentials", "true")]

cookie_value = '';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Import a remote origin script.
import('http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py');
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import('./credentials.py');
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Import a remote origin script.
import 'http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './credentials.py';

0 comments on commit 21cd6f0

Please sign in to comment.