Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connection-form): support for multiple kms options from same provider COMPASS-8082 #6166

Merged
merged 34 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1b917fb
ux changes
mabaasit Aug 28, 2024
46f4bb6
fix tests
mabaasit Aug 28, 2024
efd8b77
Merge branch 'main' of https://github.com/mongodb-js/compass into COM…
mabaasit Aug 28, 2024
508c7d1
fix after merge
mabaasit Aug 28, 2024
009876b
tests
mabaasit Aug 28, 2024
adf979b
ts issues
mabaasit Aug 28, 2024
aa2cf7c
remove todo
mabaasit Aug 28, 2024
4635ecc
store connection data
mabaasit Aug 29, 2024
cc21a64
use icon button
mabaasit Aug 29, 2024
8fcf8a5
fix types
mabaasit Aug 29, 2024
83c0fe9
fix test
mabaasit Aug 29, 2024
3b90fb1
another ts
mabaasit Aug 29, 2024
4c6f296
fix connection storage test
mabaasit Aug 29, 2024
f22cc6e
show delete button on hover
mabaasit Aug 29, 2024
e70ed58
Merge remote-tracking branch 'origin' into COMPASS-8082-multiple-kms-…
mabaasit Sep 1, 2024
392d7b3
show configured providers when creating collection
mabaasit Sep 4, 2024
23a068b
multiple local keys in tests
mabaasit Sep 4, 2024
2254bd4
multiple local keys in tests
mabaasit Sep 4, 2024
d69e60c
Merge branch 'main' of https://github.com/mongodb-js/compass into COM…
mabaasit Sep 4, 2024
d4a2fac
allow rename of kms
mabaasit Sep 5, 2024
e8572fa
tests
mabaasit Sep 6, 2024
8525f23
don't clear state when modal is closed
mabaasit Sep 6, 2024
5798bb0
check
mabaasit Sep 6, 2024
188bfaf
Merge branch 'main' of https://github.com/mongodb-js/compass into COM…
mabaasit Sep 6, 2024
31d9e6f
pr feedback
mabaasit Sep 6, 2024
711e0ef
cleaner path names
mabaasit Sep 8, 2024
4acde92
e2e-test
mabaasit Sep 8, 2024
10abea3
remove tls
mabaasit Sep 8, 2024
6050c56
fix id
mabaasit Sep 8, 2024
63e1306
use regex to get next name
mabaasit Sep 9, 2024
b2e0a99
reformat doesn't take care of ts-comments
mabaasit Sep 9, 2024
328a7c1
Merge branch 'main' of https://github.com/mongodb-js/compass into COM…
mabaasit Sep 9, 2024
3f954e6
cr fix
mabaasit Sep 9, 2024
1b179f6
revert unnecessary changes
mabaasit Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
addaleax marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1549,12 +1549,15 @@ export const connect = (
dispatch(disconnect(connectionInfo.id));
});

const { connectionOptions, ...restOfTheConnectionInfo } =
connectionInfo;

const adjustedConnectionInfoForConnection: ConnectionInfo = merge(
cloneDeep(connectionInfo),
cloneDeep(restOfTheConnectionInfo),
{
connectionOptions: adjustConnectionOptionsBeforeConnect({
connectionOptions: merge(
cloneDeep(connectionInfo.connectionOptions),
cloneDeep(connectionOptions),
SecretsForConnection.get(connectionInfo.id) ?? {}
),
defaultAppName: appName,
Expand Down
23 changes: 17 additions & 6 deletions packages/compass-e2e-tests/helpers/commands/connect-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ export async function setConnectFormState(
// FLE2
if (
state.fleKeyVaultNamespace ||
state.fleKey ||
state.kmsProviders ||
state.fleEncryptedFieldsMap
) {
await browser.navigateToConnectTab('In-Use Encryption');
Expand All @@ -665,12 +665,23 @@ export async function setConnectFormState(
state.fleKeyVaultNamespace
);
}
if (state.fleKey) {
if ((state.kmsProviders?.local?.length ?? 0) > 0) {
await browser.expandAccordion(Selectors.ConnectionFormInputFLELocalKMS);
await browser.setValueVisible(
Selectors.ConnectionFormInputFLELocalKey,
state.fleKey
);
for (const [index, item] of (state.kmsProviders?.local ?? []).entries()) {
if (item.name) {
await browser.setValueVisible(
Selectors.connectionFormInputFLELocalName(index),
item.name
);
}
await browser.setValueVisible(
Selectors.connectionFormInputFLELocalKey(index),
item.key
);
await browser.clickVisible(
Selectors.ConnectionFormAddNewKMSProviderButton
);
}
}
if (state.fleEncryptedFieldsMap) {
// set the text in the editor
Expand Down
8 changes: 7 additions & 1 deletion packages/compass-e2e-tests/helpers/connect-form-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,14 @@ export interface ConnectFormState {
// FLE2
fleKeyVaultNamespace?: string;
fleStoreCredentials?: boolean;
fleKey?: string;
fleEncryptedFieldsMap?: string;
kmsProviders?: {
// For now adding support for local only
local?: {
name?: string;
key: string;
}[];
};

// - SSH with Password
sshPasswordHost?: string;
Expand Down
8 changes: 6 additions & 2 deletions packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ export const ConnectionFormInputFLEStoreCredentialsCheckbox =
'[data-testid="csfle-store-credentials-input"]';
export const ConnectionFormInputFLELocalKMS =
'[data-testid="csfle-kms-provider-local"]';
export const ConnectionFormInputFLELocalKey =
'[data-testid="csfle-kms-local-key"]';
export const connectionFormInputFLELocalName = (index = 0) =>
`[data-card-index="${index}"] [data-testid="csfle-kms-card-name"]`;
export const connectionFormInputFLELocalKey = (index = 0) =>
`[data-card-index="${index}"] [data-testid="csfle-kms-local-key"]`;
export const ConnectionFormAddNewKMSProviderButton =
'[data-testid="csfle-add-new-kms-provider-button"]';
export const ConnectionFormInputFLEEncryptedFieldsMap =
'[data-testid="connection-csfle-encrypted-fields-map"]';
export const ConnectionFormInputFLEEncryptedFieldsMapEditor =
Expand Down
8 changes: 7 additions & 1 deletion packages/compass-e2e-tests/tests/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,13 @@ describe('FLE2', function () {
await browser.connectWithConnectionForm({
hosts: ['127.0.0.1:27091'],
fleKeyVaultNamespace: 'alena.keyvault',
fleKey: 'A'.repeat(128),
kmsProviders: {
local: [
{
key: 'A'.repeat(128),
},
],
},
fleEncryptedFieldsMap: `{
'alena.coll': {
fields: [
Expand Down
188 changes: 183 additions & 5 deletions packages/compass-e2e-tests/tests/in-use-encryption.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,13 @@ describe('CSFLE / QE', function () {
const options: ConnectFormState = {
hosts: [CONNECTION_HOSTS],
fleKeyVaultNamespace: `${databaseName}.keyvault`,
fleKey: 'A'.repeat(128),
kmsProviders: {
local: [
{
key: 'A'.repeat(128),
},
],
},
fleEncryptedFieldsMap: `{
'${databaseName}.${collectionName}': {
fields: [
Expand Down Expand Up @@ -226,7 +232,14 @@ describe('CSFLE / QE', function () {
await browser.connectWithConnectionForm({
hosts: [CONNECTION_HOSTS],
fleKeyVaultNamespace: `${databaseName}.keyvault`,
fleKey: 'A'.repeat(128),
kmsProviders: {
local: [
{
name: 'local',
key: 'A'.repeat(128),
},
],
},
connectionName,
});

Expand Down Expand Up @@ -324,7 +337,14 @@ describe('CSFLE / QE', function () {
await browser.connectWithConnectionForm({
hosts: [CONNECTION_HOSTS],
fleKeyVaultNamespace: `${databaseName}.keyvault`,
fleKey: 'A'.repeat(128),
kmsProviders: {
local: [
{
name: 'local',
key: 'A'.repeat(128),
},
],
},
fleEncryptedFieldsMap: `{
'${databaseName}.${collectionName}': {
fields: [
Expand Down Expand Up @@ -372,7 +392,7 @@ describe('CSFLE / QE', function () {
'"creationDate": ISODate("2022-05-27T18:28:33.925Z"),' +
'"updateDate": ISODate("2022-05-27T18:28:33.925Z"),' +
'"status": 0,' +
'"masterKey": { "provider" : "local" }' +
'"masterKey": { "provider" : "local:local" }' +
'})',
// make sure there is a collection so we can navigate to the database
`db.getMongo().getDB('${databaseName}').createCollection('default')`,
Expand Down Expand Up @@ -947,6 +967,158 @@ describe('CSFLE / QE', function () {
});
});
});

describe('multiple kms providers of the same type', function () {
const databaseName = 'fle-test';
const collection1 = 'collection-1';
const collection2 = 'collection-2';
const phoneNumber1 = '1234567890';
const phoneNumber2 = '0987654321';
let compass: Compass;
let browser: CompassBrowser;
let plainMongo: MongoClient;

before(async function () {
compass = await init(this.test?.fullTitle());
browser = compass.browser;
});

beforeEach(async function () {
await browser.disconnectAll();
await browser.connectWithConnectionForm({
hosts: [CONNECTION_HOSTS],
fleKeyVaultNamespace: `${databaseName}.keyvault`,
fleEncryptedFieldsMap: `{
'${databaseName}.${collection1}': {
fields: [
{
path: 'phoneNumber',
keyId: UUID("28bbc608-524e-4717-9246-33633361788e"),
bsonType: 'string',
queries: { queryType: 'equality' }
}
]
},
'${databaseName}.${collection2}': {
fields: [
{
path: 'phoneNumber',
keyId: UUID("9c932ef9-f43c-489a-98f3-31012a83bc46"),
bsonType: 'string',
queries: { queryType: 'equality' }
}
]
},
}`,
kmsProviders: {
local: [
{
name: 'localA',
key: 'A'.repeat(128),
},
{
name: 'localB',
key: 'B'.repeat(128),
},
],
},
connectionName,
});
await browser.shellEval(connectionName, [
`use ${databaseName}`,
'db.keyvault.insertOne({' +
'"_id": UUID("28bbc608-524e-4717-9246-33633361788e"),' +
'"keyMaterial": Binary.createFromBase64("fqZuVyi6ThsSNbgUWtn9MCFDxOQtL3dibMa2P456l+1xJUvAkqzZB2SZBr5Zd2xLDua45IgYAagWFeLhX+hpi0KkdVgdIZu2zlZ+mJSbtwZrFxcuyQ3oPCPnp7l0YH1fSfxeoEIQNVMFpnHzfbu2CgZ/nC8jp6IaB9t+tcszTDdJRLeHnzPuHIKzblFGP8CfuQHJ81B5OA0PrBJr+HbjJg==", 0),' +
'"creationDate": ISODate("2022-05-27T18:28:33.925Z"),' +
'"updateDate": ISODate("2022-05-27T18:28:33.925Z"),' +
'"status": 0,' +
'"masterKey": { "provider" : "local:localA" }' +
'})',
'db.keyvault.insertOne({' +
'"_id": UUID("9c932ef9-f43c-489a-98f3-31012a83bc46"),' +
'"keyMaterial": Binary.createFromBase64("TymoH++xeTsaiIl498fviLaklY4xTM/baQydmVUABphJzvBsitjWfkoiKlGod/J45Vwoou1VfDRsFaiVHNth7aiFBvEsqvto5ETDFC9hSzP17c1ZrQI1nqrOfI0VGJm+WBALB7IMVFuyd9LV2i6KDIslxBfchOGR4q05Gm1Vgb/cTTUPJpvYLxmduyNSjxqH6lBAJ2ut9TgmUxCC+dMQRQ==", 0),' +
'"creationDate": ISODate("2022-05-27T18:28:34.925Z"),' +
'"updateDate": ISODate("2022-05-27T18:28:34.925Z"),' +
'"status": 0,' +
'"masterKey": { "provider" : "local:localB" }' +
'})',
// make sure there is a collection so we can navigate to the database
`db.getMongo().getDB('${databaseName}').createCollection('default')`,
]);
await refresh(browser, connectionName);

plainMongo = await MongoClient.connect(CONNECTION_STRING);
});

after(async function () {
if (compass) {
await cleanup(compass);
}
});

afterEach(async function () {
if (compass) {
await screenshotIfFailed(compass, this.currentTest);
}
await plainMongo.db(databaseName).dropDatabase();
await plainMongo.close();
});

it('allows setting multiple kms providers of the same type', async function () {
async function verifyCollectionHasValue(
collection: string,
value: string
) {
await browser.navigateToCollectionTab(
connectionName,
databaseName,
collection,
'Documents'
);
const result = await getFirstListDocument(browser);
console.log(result);
expect(result.phoneNumber).to.be.equal(JSON.stringify(value));
}

await browser.shellEval(connectionName, [
`use ${databaseName}`,
`db.createCollection("${collection1}")`,
`db.createCollection("${collection2}")`,
`db["${collection1}"].insertOne({ "phoneNumber": "${phoneNumber1}", "name": "LocalA" })`,
`db["${collection2}"].insertOne({ "phoneNumber": "${phoneNumber2}", "name": "LocalB" })`,
]);
await refresh(browser, connectionName);

await verifyCollectionHasValue(collection1, phoneNumber1);
await verifyCollectionHasValue(collection2, phoneNumber2);

// create a new encrypted collection using keyId for local:localB
await browser.navigateToDatabaseCollectionsTab(
connectionName,
databaseName
);
const collection3 = 'collection-3';
const phoneNumber3 = '1111111111';
await browser.clickVisible(Selectors.DatabaseCreateCollectionButton);
await browser.addCollection(collection3, {
encryptedFields: `{
fields: [{
path: 'phoneNumber',
keyId: UUID("9c932ef9-f43c-489a-98f3-31012a83bc46"),
bsonType: 'string',
queries: { queryType: 'equality' }
}]
}`,
});

await browser.shellEval(connectionName, [
`use ${databaseName}`,
`db["${collection3}"].insertOne({ "phoneNumber": "${phoneNumber3}", "name": "LocalB" })`,
]);

await verifyCollectionHasValue(collection3, phoneNumber3);
});
});
});

describe('server version gte 6.0 and lt 7.0', function () {
Expand Down Expand Up @@ -1070,7 +1242,13 @@ describe('CSFLE / QE', function () {
await browser.connectWithConnectionForm({
hosts: [CONNECTION_HOSTS],
fleKeyVaultNamespace: `${databaseName}.keyvault`,
fleKey: 'A'.repeat(128),
kmsProviders: {
local: [
{
key: 'A'.repeat(128),
},
],
},
connectionName,
});

Expand Down
Loading
Loading