Commit ecb522dd authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Worklet: Fix credentials tests for worklets

Before this CL, credentials tests for worklets are completely broken as follows:

- In credentials.py, |credentials_mode| is compared by "is" that conducts the
  object equality check. As a result, all conditions unexpectedly pass through
  and the script always returns a valid response.
- In credentials.py, |is_cross_origin| value is always |False| because requests
  don't have the GET param.
- fetch() needs { credentials: 'include' } option for configuring the document's
  cookie with the Set-Cookie header, but it's not specified.
- Response headers are not specified for a 404 response. This results in test
  timeout instead of a network error.

This CL fixes these bugs and cleans up tests.

Bug: 738769
Change-Id: I9aeb11fca23dec3fd3057a765fa60eb6e59d8258
Reviewed-on: https://chromium-review.googlesource.com/799730
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523713}
parent 17ef14e2
function createCookieValue(settings) {
return settings.credentials + '-' + settings.origin;
}
function createSetCookieURL(settings) {
const params = new URLSearchParams;
params.append('name', 'cookieName');
params.append('value', createCookieValue(settings));
if (settings.origin == 'same') {
return get_host_info().HTTPS_ORIGIN +
'/worklets/resources/set-cookie.py?' + params;
}
if (settings.origin == 'remote') {
return get_host_info().HTTPS_REMOTE_ORIGIN +
'/worklets/resources/set-cookie.py?' + params;
}
assert_unreached('settings.origin has an invalid value.');
}
function createScriptURL(settings) {
const params = new URLSearchParams;
if (settings.expectCredentialsSent)
params.append('value', createCookieValue(settings));
if (settings.origin == 'same') {
return get_host_info().HTTPS_ORIGIN +
'/worklets/resources/credentials.py?' + params;
}
if (settings.origin == 'remote') {
return get_host_info().HTTPS_REMOTE_ORIGIN +
'/worklets/resources/credentials.py?' + params;
}
assert_unreached('settings.origin has an invalid value.');
}
function createWorkletOptions(settings) {
if (settings.credentials == '')
return {};
return { credentials: settings.credentials };
}
// Run a credentials test with the given settings.
//
// Example:
// settings = {
// workletType: 'paint',
// credentials: 'include',
// origin: 'same', // 'same' or 'remote'
// expectCredentialsSent: true
// };
function runCredentialsTest(settings) {
const worklet = get_worklet(settings.workletType);
const setCookieURL = createSetCookieURL(settings);
const scriptURL = createScriptURL(settings);
const options = createWorkletOptions(settings);
// { credentials: 'include' } is necessary for configuring document's cookies
// with the Set-Cookie: header of the response.
return fetch(setCookieURL, { mode: 'cors', credentials: 'include' })
.then(response => worklet.addModule(scriptURL, options));
}
// Runs a series of tests related to credentials on a worklet. // Runs a series of tests related to credentials on a worklet.
// //
// Usage: // Usage:
// runCredentialsTests("paint"); // runCredentialsTests("paint");
function runCredentialsTests(worklet_type) { function runCredentialsTests(worklet_type) {
const worklet = get_worklet(worklet_type);
promise_test(() => { promise_test(() => {
document.cookie = 'cookieName=default'; return runCredentialsTest({ workletType: worklet_type,
const kScriptURL = 'resources/credentials.py?mode=default'; credentials: '',
return worklet.addModule(kScriptURL).then(undefined_arg => { origin: 'same',
assert_equals(undefined_arg, undefined); expectCredentialsSent: false });
});
}, 'Importing a same-origin script with the default WorkletOptions should ' + }, 'Importing a same-origin script with the default WorkletOptions should ' +
'omit the credentials'); 'not send the credentials');
promise_test(() => { promise_test(() => {
const kSetCookieURL = return runCredentialsTest({ workletType: worklet_type,
get_host_info().HTTPS_REMOTE_ORIGIN + credentials: '',
'/worklets/resources/set-cookie.py?name=cookieName'; origin: 'remote',
const kScriptURL = get_host_info().HTTPS_REMOTE_ORIGIN + expectCredentialsSent: false });
'/worklets/resources/credentials.py?mode=default';
const kOptions = { credentials: 'same-origin' };
// Set a cookie in the remote origin and then start a worklet.
return fetch(kSetCookieURL, { mode: 'cors' })
.then(() => worklet.addModule(kScriptURL, kOptions))
.then(undefined_arg => assert_equals(undefined_arg, undefined));
}, 'Importing a remote-origin script with the default WorkletOptions ' + }, 'Importing a remote-origin script with the default WorkletOptions ' +
'should not include the credentials'); 'should not send the credentials');
promise_test(() => { promise_test(() => {
document.cookie = 'cookieName=omit'; return runCredentialsTest({ workletType: worklet_type,
const kScriptURL = 'resources/credentials.py?mode=omit'; credentials: 'omit',
const kOptions = { credentials: 'omit' }; origin: 'same',
return worklet.addModule(kScriptURL, kOptions).then(undefined_arg => { expectCredentialsSent: false });
assert_equals(undefined_arg, undefined); }, 'Importing a same-origin script with credentials=omit should not send ' +
}); 'the credentials');
}, 'Importing a same-origin script with credentials=omit should omit the ' +
'credentials');
promise_test(() => { promise_test(() => {
const kSetCookieURL = return runCredentialsTest({ workletType: worklet_type,
get_host_info().HTTPS_REMOTE_ORIGIN + credentials: 'omit',
'/worklets/resources/set-cookie.py?name=cookieName'; origin: 'remote',
const kScriptURL = get_host_info().HTTPS_REMOTE_ORIGIN + expectCredentialsSent: false });
'/worklets/resources/credentials.py?mode=omit'; }, 'Importing a remote-origin script with credentials=omit should not send ' +
const kOptions = { credentials: 'omit' }; 'the credentials');
// Set a cookie in the remote origin and then start a worklet.
return fetch(kSetCookieURL, { mode: 'cors' })
.then(() => worklet.addModule(kScriptURL, kOptions))
.then(undefined_arg => assert_equals(undefined_arg, undefined));
}, 'Importing a remote-origin script with credentials=omit should omit the ' +
'credentials');
promise_test(() => { promise_test(() => {
document.cookie = 'cookieName=same-origin'; return runCredentialsTest({ workletType: worklet_type,
const kScriptURL = 'resources/credentials.py?mode=same-origin'; credentials: 'same-origin',
const kOptions = { credentials: 'same-origin' }; origin: 'same',
return worklet.addModule(kScriptURL, kOptions).then(undefined_arg => { expectCredentialsSent: true });
assert_equals(undefined_arg, undefined);
});
}, 'Importing a same-origin script with credentials=same-origin should ' + }, 'Importing a same-origin script with credentials=same-origin should ' +
'include the credentials'); 'send the credentials');
promise_test(() => { promise_test(() => {
const kSetCookieURL = return runCredentialsTest({ workletType: worklet_type,
get_host_info().HTTPS_REMOTE_ORIGIN + credentials: 'same-origin',
'/worklets/resources/set-cookie.py?name=cookieName'; origin: 'remote',
const kScriptURL = get_host_info().HTTPS_REMOTE_ORIGIN + expectCredentialsSent: false });
'/worklets/resources/credentials.py?mode=same-origin';
const kOptions = { credentials: 'same-origin' };
// Set a cookie in the remote origin and then start a worklet.
return fetch(kSetCookieURL, { mode: 'cors' })
.then(() => worklet.addModule(kScriptURL, kOptions))
.then(undefined_arg => assert_equals(undefined_arg, undefined));
}, 'Importing a remote-origin script with credentials=same-origin should ' + }, 'Importing a remote-origin script with credentials=same-origin should ' +
'not include the credentials'); 'not send the credentials');
promise_test(() => { promise_test(() => {
document.cookie = 'cookieName=include'; return runCredentialsTest({ workletType: worklet_type,
const kScriptURL = 'resources/credentials.py?mode=include'; credentials: 'include',
const kOptions = { credentials: 'include' }; origin: 'same',
return worklet.addModule(kScriptURL, kOptions).then(undefined_arg => { expectCredentialsSent: true });
assert_equals(undefined_arg, undefined); }, 'Importing a same-origin script with credentials=include should send ' +
});
}, 'Importing a same-origin script with credentials=include should include ' +
'the credentials'); 'the credentials');
promise_test(() => { promise_test(() => {
const kSetCookieURL = return runCredentialsTest({ workletType: worklet_type,
get_host_info().HTTPS_REMOTE_ORIGIN + credentials: 'include',
'/worklets/resources/set-cookie.py?name=cookieName'; origin: 'remote',
const kScriptURL = get_host_info().HTTPS_REMOTE_ORIGIN + expectCredentialsSent: true });
'/worklets/resources/credentials.py?mode=include';
const kOptions = { credentials: 'include' };
// Set a cookie in the remote origin and then start a worklet.
return fetch(kSetCookieURL, { mode: 'cors' })
.then(() => worklet.addModule(kScriptURL, kOptions))
.then(undefined_arg => assert_equals(undefined_arg, undefined));
}, 'Importing a remote-origin script with credentials=include should ' + }, 'Importing a remote-origin script with credentials=include should ' +
'include the credentials'); 'send the credentials');
} }
# Returns a valid response when a request has appropriate credentials. # Returns a valid response when a request has appropriate credentials.
def main(request, response): def main(request, response):
credentials_mode = request.GET.first("mode")
cookie = request.cookies.first("cookieName", None) cookie = request.cookies.first("cookieName", None)
source_origin = request.headers.get("origin", None); expected_value = request.GET.first("value", None)
is_cross_origin = request.GET.first("is_cross_origin", False) source_origin = request.headers.get("origin", None)
# The request with the default WorkletOptions should not include the cookie. response_headers = [("Content-Type", "text/javascript"),
if credentials_mode is "default" and cookie is not None: ("Access-Control-Allow-Origin", source_origin),
return (404) ("Access-Control-Allow-Credentials", "true")]
# The request with "credentials=omit" should not include the cookie.
if credentials_mode is "omit" and cookie is not None:
return (404)
if credentials_mode is "same-origin":
# The cross-origin request with "credentials=same-origin" should not
# include the cookie.
if is_cross_origin and cookie is not None:
return (404)
# The same-origin request with "credentials=same-origin" should include
# the cookie.
if not is_cross_origin and cookie is None:
return (404)
# The request with "credentials=include" should include the cookie. if cookie == expected_value:
if credentials_mode is "include" and cookie is None: return (200, response_headers, "")
return (404)
return (200, [("Content-Type", "text/javascript"), return (404, response_headers)
("Access-Control-Allow-Origin", source_origin),
("Access-Control-Allow-Credentials", "true")], "")
def main(request, response): def main(request, response):
name = request.GET.first("name") name = request.GET.first("name")
source_origin = request.headers.get("origin", None); value = request.GET.first("value")
response.headers.set("Set-Cookie", name + "=value") source_origin = request.headers.get("origin", None)
response.headers.set("Access-Control-Allow-Origin", source_origin)
response.headers.set("Access-Control-Allow-Credentials", "true") response_headers = [("Set-Cookie", name + "=" + value),
("Access-Control-Allow-Origin", source_origin),
("Access-Control-Allow-Credentials", "true")]
return (200, response_headers, "")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment