Bug 1826196 - [bidi] Add network.continueWithAuth command r=webdriver-reviewers,whimboo

Depends on D195673

Differential Revision: https://phabricator.services.mozilla.com/D195675
This commit is contained in:
Julian Descottes 2023-12-15 15:45:06 +00:00
Родитель bb6e197ba9
Коммит c2061a27ed
2 изменённых файлов: 124 добавлений и 120 удалений

Просмотреть файл

@ -31,6 +31,13 @@ ChromeUtils.defineESModuleGetters(lazy, {
* @property {string} realm
*/
/**
* @typedef {object} AuthCredentials
* @property {'password'} type
* @property {string} username
* @property {string} password
*/
/**
* @typedef {object} BaseParameters
* @property {string=} context
@ -65,6 +72,18 @@ const BytesValueType = {
* @property {string} value
*/
/**
* Enum of possible continueWithAuth actions.
*
* @readonly
* @enum {ContinueWithAuthAction}
*/
const ContinueWithAuthAction = {
Cancel: "cancel",
Default: "default",
ProvideCredentials: "provideCredentials",
};
/**
* @typedef {object} Cookie
* @property {string} domain
@ -346,6 +365,101 @@ class NetworkModule extends Module {
};
}
/**
* Continues a response that is blocked by a network intercept at the
* authRequired phase.
*
* @param {object=} options
* @param {string} options.request
* The id of the blocked request that should be continued.
* @param {string} options.action
* The continueWithAuth action, one of ContinueWithAuthAction.
* @param {AuthCredentials=} options.credentials
* The credentials to use for the ContinueWithAuthAction.ProvideCredentials
* action.
*
* @throws {InvalidArgumentError}
* Raised if an argument is of an invalid type or value.
* @throws {NoSuchRequestError}
* Raised if the request id does not match any request in the blocked
* requests map.
*/
async continueWithAuth(options = {}) {
this.assertExperimentalCommandsEnabled("network.continueWithAuth");
const { action, credentials, request: requestId } = options;
lazy.assert.string(
requestId,
`Expected "request" to be a string, got ${requestId}`
);
if (!Object.values(ContinueWithAuthAction).includes(action)) {
throw new lazy.error.InvalidArgumentError(
`Expected "action" to be one of ${Object.values(
ContinueWithAuthAction
)} got ${action}`
);
}
if (action == ContinueWithAuthAction.ProvideCredentials) {
lazy.assert.object(
credentials,
`Expected "credentials" to be an object, got ${credentials}`
);
if (credentials.type !== "password") {
throw new lazy.error.InvalidArgumentError(
`Expected credentials "type" to be "password" got ${credentials.type}`
);
}
lazy.assert.string(
credentials.username,
`Expected credentials "username" to be a string, got ${credentials.username}`
);
lazy.assert.string(
credentials.password,
`Expected credentials "password" to be a string, got ${credentials.password}`
);
}
if (!this.#blockedRequests.has(requestId)) {
throw new lazy.error.NoSuchRequestError(
`Blocked request with id ${requestId} not found`
);
}
const { authCallbacks, phase, resolveBlockedEvent } =
this.#blockedRequests.get(requestId);
if (phase !== InterceptPhase.AuthRequired) {
throw new lazy.error.InvalidArgumentError(
`Expected blocked request to be in "authRequired" phase, got ${phase}`
);
}
switch (action) {
case ContinueWithAuthAction.Cancel: {
authCallbacks.cancelAuthPrompt();
break;
}
case ContinueWithAuthAction.Default: {
authCallbacks.forwardAuthPrompt();
break;
}
case ContinueWithAuthAction.ProvideCredentials: {
await authCallbacks.provideAuthCredentials(
credentials.username,
credentials.password
);
break;
}
}
resolveBlockedEvent();
}
/**
* Removes an existing network intercept.
*
@ -492,6 +606,7 @@ class NetworkModule extends Module {
redirectCount,
requestChannel,
requestData,
responseChannel,
responseData,
timestamp,
} = data;
@ -553,17 +668,23 @@ class NetworkModule extends Module {
if (authRequiredEvent.isBlocked) {
isBlocked = true;
const { promise: blockedEventPromise, resolve: resolveBlockedEvent } =
Promise.withResolvers();
// requestChannel.suspend() is not needed here because the request is
// already blocked on the authentication prompt notification until
// one of the authCallbacks is called.
this.#blockedRequests.set(authRequiredEvent.request.request, {
authCallbacks,
request: requestChannel,
response: responseChannel,
resolveBlockedEvent,
phase: InterceptPhase.AuthRequired,
});
// TODO: Once we implement network.continueWithAuth, we should create a
// promise here which will wait until the request is resumed and removes
// the request from the blockedRequests. See Bug 1826196.
blockedEventPromise.finally(() => {
this.#blockedRequests.delete(authRequiredEvent.request.request);
});
}
} finally {
if (!isBlocked) {

Просмотреть файл

@ -1,117 +0,0 @@
[invalid.py]
[test_params_request_invalid_phase[beforeRequestSent\]]
expected: FAIL
[test_params_request_invalid_phase[responseStarted\]]
expected: FAIL
[test_params_request_invalid_type[None\]]
expected: FAIL
[test_params_request_invalid_type[False\]]
expected: FAIL
[test_params_request_invalid_type[42\]]
expected: FAIL
[test_params_request_invalid_type[value3\]]
expected: FAIL
[test_params_request_invalid_type[value4\]]
expected: FAIL
[test_params_request_invalid_value[\]]
expected: FAIL
[test_params_request_invalid_value[foo\]]
expected: FAIL
[test_params_request_no_such_request]
expected: FAIL
[test_params_action_invalid_type[None\]]
expected: FAIL
[test_params_action_invalid_type[False\]]
expected: FAIL
[test_params_action_invalid_type[42\]]
expected: FAIL
[test_params_action_invalid_type[value3\]]
expected: FAIL
[test_params_action_invalid_type[value4\]]
expected: FAIL
[test_params_action_invalid_value[\]]
expected: FAIL
[test_params_action_invalid_value[foo\]]
expected: FAIL
[test_params_action_provideCredentials_invalid_credentials[missing username\]]
expected: FAIL
[test_params_action_provideCredentials_invalid_credentials[missing password\]]
expected: FAIL
[test_params_action_provideCredentials_invalid_credentials[missing username and password\]]
expected: FAIL
[test_params_action_provideCredentials_invalid_credentials[missing type\]]
expected: FAIL
[test_params_action_provideCredentials_invalid_credentials[missing credentials\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_type[None\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_type[False\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_type[42\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_type[value3\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_type[value4\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_value[\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_type_invalid_value[foo\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_username_invalid_type[None\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_username_invalid_type[False\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_username_invalid_type[42\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_username_invalid_type[value3\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_username_invalid_type[value4\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_password_invalid_type[None\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_password_invalid_type[False\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_password_invalid_type[42\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_password_invalid_type[value3\]]
expected: FAIL
[test_params_action_provideCredentials_credentials_password_invalid_type[value4\]]
expected: FAIL