Commit cd63e9e0 authored by Kim Paulhamus's avatar Kim Paulhamus Committed by Commit Bot

[WebAuthn] Refactor layout tests to reduce code.

Instead of custom building each set of options per test,
deep copy the options and remove select properties. Both reduces
code and makes it more clear what is being tested.

Also adds a helper to set up a successful response from the
mock authenticator.

Bug: 664630
Change-Id: If5986e21b56e1093835866283f0e69134f265390
Reviewed-on: https://chromium-review.googlesource.com/957831Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542753}
parent aa7d638b
......@@ -25,121 +25,61 @@ promise_test(t => {
navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}));
}, "Verify that invalid domain error returned by mock is properly handled.");
promise_test(t => {
var customMakeCredOptions = {
// No challenge.
rp: PUBLIC_KEY_RP,
user: PUBLIC_KEY_USER,
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey : customMakeCredOptions}));
promise_test(t => {
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.challenge;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey : customMakeCredOptions}));
}, "navigator.credentials.create() with missing challenge");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
user: PUBLIC_KEY_USER,
// No parameters.
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey : customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.pubKeyCredParams;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey : customMakeCredOptions}));
}, "navigator.credentials.create() with missing parameters");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
// No rp.
user: PUBLIC_KEY_USER,
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.rp;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing rp");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
// No user.
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.user;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: { id: "google.com" },
user: PUBLIC_KEY_USER,
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.rp.name;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing rp.name");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
user: {
name: "avery.a.jones@example.com",
displayName: "Avery A. Jones",
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
},
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.user.id;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.id");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
user: {
id: new TextEncoder().encode("1098237235409872"),
displayName: "Avery A. Jones",
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
},
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
timeout: 60000, // 1 minute
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
excludeCredentials: [], // No already-registered credentials.
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.user.name;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.name");
promise_test(t => {
var customMakeCredOptions = {
challenge: CHALLENGE,
rp: PUBLIC_KEY_RP,
user: {
id: new TextEncoder().encode("1098237235409872"),
name: "avery.a.jones@example.com",
icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
},
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
authenticatorSelection: AUTHENTICATOR_SELECTION_CRITERIA,
};
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.user.displayName;
return promise_rejects(t, new TypeError(),
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with missing user.displayName");
promise_test(_ => {
......@@ -150,9 +90,9 @@ promise_test(_ => {
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
return navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}).then(r => {
assertValidMakeCredentialResponse(r);
});
return navigator.credentials.create({publicKey : MAKE_CREDENTIAL_OPTIONS}).then(r => {
assertValidMakeCredentialResponse(r);
});
}, "Verify that the mock returns the values we give it.");
promise_test(t => {
......@@ -185,29 +125,18 @@ promise_test(t => {
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setId(ID);
mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
mockAuthenticator.setAttestationObject(ATTESTATION_OBJECT);
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
var customPublicKey = {
challenge: CHALLENGE,
rp: { name: "Acme" },
user: PUBLIC_KEY_USER,
pubKeyCredParams: PUBLIC_KEY_PARAMETERS,
};
return navigator.credentials.create({publicKey: customPublicKey}).then(r => {
assertValidMakeCredentialResponse(r);
});
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
customMakeCredOptions.rp = { name: "Acme" };
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
});
}, "navigator.credentials.create() with missing rp.id");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.authenticatorSelection;
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
......@@ -217,7 +146,7 @@ promise_test(_ => {
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.authenticatorSelection.requireResidentKey;
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
......@@ -227,7 +156,7 @@ promise_test(_ => {
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customMakeCredOptions.authenticatorSelection.userVerification;
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
......@@ -238,25 +167,25 @@ promise_test(t => {
mockAuthenticator.reset();
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.NOT_SUPPORTED_ERROR);
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
return promise_rejects(t, "NotSupportedError",
navigator.credentials.create({publicKey: customMakeCredOptions}));
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with requireResidentKey true");
promise_test(t => {
mockAuthenticator.reset();
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.NOT_SUPPORTED_ERROR);
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
customMakeCredOptions.authenticatorSelection.userVerification = 'required';
return promise_rejects(t, "NotSupportedError",
navigator.credentials.create({publicKey: customMakeCredOptions}));
navigator.credentials.create({publicKey: customMakeCredOptions}));
}, "navigator.credentials.create() with userVerification required");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
customMakeCredOptions.authenticatorSelection.userVerification = 'discouraged';
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
......@@ -266,7 +195,7 @@ promise_test(_ => {
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
customMakeCredOptions.authenticatorSelection.authenticatorAttachment = 'platform';
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
......@@ -276,10 +205,11 @@ promise_test(_ => {
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setDefaultsForSuccessfulMakeCredential();
var customMakeCredOptions = Object.assign({}, MAKE_CREDENTIAL_OPTIONS);
var customMakeCredOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
customMakeCredOptions.authenticatorSelection.authenticatorAttachment = 'cross-platform';
return navigator.credentials.create({publicKey: customMakeCredOptions}).then(r => {
assertValidMakeCredentialResponse(r);
});
}, "navigator.credentials.create() with cross-platform authenticatorAttachment");
</script>
......@@ -115,16 +115,10 @@ promise_test(_ => {
promise_test(_ => {
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setId(ID);
mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
mockAuthenticator.setSignature(SIGNATURE);
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
return navigator.credentials.get({publicKey : GET_CREDENTIAL_OPTIONS}).then(r => {
assertValidGetCredentialResponse(r);
});
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
return navigator.credentials.get({publicKey : GET_CREDENTIAL_OPTIONS}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "Verify that mockAuthenticator returns the values we give it.");
promise_test(t => {
......@@ -156,54 +150,28 @@ promise_test(t => {
}, "Verify that not supported error returned by mock is properly handled.");
promise_test(function(t) {
var customGetCredentialOptions = {
// No challenge.
rpId: "google.com",
allowCredentials: [ACCEPTABLE_CREDENTIAL],
userVerification: "preferred",
};
return promise_rejects(t, new TypeError(),
navigator.credentials.get({publicKey: customGetCredentialOptions}));
var customGetCredentialOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.challenge;
return promise_rejects(t, new TypeError(),
navigator.credentials.get({publicKey: customGetCredentialOptions}));
}, "navigator.credentials.get() with missing challenge");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setId(ID);
mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
mockAuthenticator.setSignature(SIGNATURE);
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
var customPublicKey = {
challenge: CHALLENGE,
allowCredentials: [ACCEPTABLE_CREDENTIAL],
userVerification: "preferred",
};
return navigator.credentials.get({publicKey: customPublicKey}).then(r => {
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.rpId;
return navigator.credentials.get({publicKey: customGetCredentialOptions}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "navigator.credentials.get() with missing rpId");
promise_test(_ => {
mockAuthenticator.reset();
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setId(ID);
mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
mockAuthenticator.setSignature(SIGNATURE);
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
var customPublicKey = {
challenge: CHALLENGE,
allowCredentials: [ACCEPTABLE_CREDENTIAL]
};
return navigator.credentials.get({publicKey: customPublicKey}).then(r => {
mockAuthenticator.setDefaultsForSuccessfulGetAssertion();
var customGetCredentialOptions = deepCopy(MAKE_CREDENTIAL_OPTIONS);
delete customGetCredentialOptions.userVerification;
return navigator.credentials.get({publicKey: customGetCredentialOptions}).then(r => {
assertValidGetCredentialResponse(r);
});
}, "navigator.credentials.get() with missing user verification requirement");
......
......@@ -138,6 +138,17 @@ class MockAuthenticator {
webauth.mojom.AuthenticatorStatus.SUCCESS);
}
// Sets everything needed for a GetAssertion success response.
setDefaultsForSuccessfulGetAssertion() {
mockAuthenticator.setRawId(RAW_ID);
mockAuthenticator.setId(ID);
mockAuthenticator.setClientDataJson(CLIENT_DATA_JSON);
mockAuthenticator.setAuthenticatorData(AUTHENTICATOR_DATA);
mockAuthenticator.setSignature(SIGNATURE);
mockAuthenticator.setAuthenticatorStatus(
webauth.mojom.AuthenticatorStatus.SUCCESS);
}
setAuthenticatorStatus(status) {
this.status_ = status;
}
......@@ -267,6 +278,16 @@ function EncloseInScriptTag(code) {
return "<script>" + code + "</scr" + "ipt>";
}
function deepCopy(value) {
if ([Number, String, Uint8Array].includes(value.constructor))
return value;
let copy = (value.constructor == Array) ? [] : {};
for (let key of Object.keys(value))
copy[key] = deepCopy(value[key]);
return copy;
}
// Verifies if |r| is the valid response to credentials.create(publicKey).
function assertValidMakeCredentialResponse(r) {
assert_equals(r.id, ID, 'id');
......
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