Skip to content

Stop creating the ECC collection in v2 of queryable encryption #1110

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

Merged
merged 5 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions driver-core/src/main/com/mongodb/AutoEncryptionSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ public Builder bypassAutoEncryption(final boolean bypassAutoEncryption) {
* @param encryptedFieldsMap the mapping of the collection namespace to the encryptedFields
* @return this
* @since 4.7
* @mongodb.server.release 7.0
*/
@Beta(Beta.Reason.SERVER)
public Builder encryptedFieldsMap(final Map<String, BsonDocument> encryptedFieldsMap) {
Expand Down Expand Up @@ -462,6 +463,7 @@ public boolean isBypassAutoEncryption() {
*
* @return the mapping of the collection namespaces to encryptedFields
* @since 4.7
* @mongodb.server.release 7.0
*/
@Beta(Beta.Reason.SERVER)
@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.mongodb.client.model;

import com.mongodb.AutoEncryptionSettings;
import com.mongodb.annotations.Beta;
import com.mongodb.lang.Nullable;
import org.bson.conversions.Bson;

Expand Down Expand Up @@ -350,8 +351,9 @@ public CreateCollectionOptions changeStreamPreAndPostImagesOptions(
* <p>Note: If not set the driver will lookup the namespace in {@link AutoEncryptionSettings#getEncryptedFieldsMap()}</p>
* @return the encrypted fields document
* @since 4.7
* @mongodb.server.release 6.0
* @mongodb.server.release 7.0
*/
@Beta(Beta.Reason.SERVER)
@Nullable
public Bson getEncryptedFields() {
return encryptedFields;
Expand All @@ -366,8 +368,9 @@ public Bson getEncryptedFields() {
* @return this
* @since 4.7
* @mongodb.driver.manual core/security-client-side-encryption/ In-use encryption
* @mongodb.server.release 6.0
* @mongodb.server.release 7.0
*/
@Beta(Beta.Reason.SERVER)
public CreateCollectionOptions encryptedFields(@Nullable final Bson encryptedFields) {
this.encryptedFields = encryptedFields;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.mongodb.client.model;

import com.mongodb.AutoEncryptionSettings;
import com.mongodb.annotations.Beta;
import com.mongodb.lang.Nullable;
import org.bson.conversions.Bson;

Expand All @@ -36,7 +37,9 @@ public class DropCollectionOptions {
* <p>Note: If not set the driver will lookup the namespace in {@link AutoEncryptionSettings#getEncryptedFieldsMap()}</p>
* @return the encrypted fields document
* @since 4.7
* @mongodb.server.release 7.0
*/
@Beta(Beta.Reason.SERVER)
@Nullable
public Bson getEncryptedFields() {
return encryptedFields;
Expand All @@ -50,8 +53,10 @@ public Bson getEncryptedFields() {
* @param encryptedFields the encrypted fields document
* @return this
* @since 4.7
* @mongodb.server.release 7.0
* @mongodb.driver.manual core/security-client-side-encryption/ In-use encryption
*/
@Beta(Beta.Reason.SERVER)
public DropCollectionOptions encryptedFields(@Nullable final Bson encryptedFields) {
this.encryptedFields = encryptedFields;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

package com.mongodb.internal.operation;

import com.mongodb.MongoClientException;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.client.model.ChangeStreamPreAndPostImagesOptions;
import com.mongodb.client.model.Collation;
import com.mongodb.client.model.TimeSeriesGranularity;
import com.mongodb.client.model.TimeSeriesOptions;
import com.mongodb.client.model.ValidationAction;
import com.mongodb.client.model.ValidationLevel;
import com.mongodb.connection.ConnectionDescription;
import com.mongodb.internal.async.SingleResultCallback;
import com.mongodb.internal.binding.AsyncWriteBinding;
import com.mongodb.internal.binding.WriteBinding;
Expand Down Expand Up @@ -51,6 +54,7 @@
import static com.mongodb.internal.operation.OperationHelper.releasingCallback;
import static com.mongodb.internal.operation.OperationHelper.withAsyncConnection;
import static com.mongodb.internal.operation.OperationHelper.withConnection;
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionSevenDotZero;
import static com.mongodb.internal.operation.WriteConcernHelper.appendWriteConcernToCommand;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
Expand Down Expand Up @@ -232,6 +236,7 @@ public CreateCollectionOperation encryptedFields(@Nullable final BsonDocument en
@Override
public Void execute(final WriteBinding binding) {
return withConnection(binding, connection -> {
checkEncryptedFieldsSupported(connection.getDescription());
getCommandFunctions().forEach(commandCreator ->
executeCommand(binding, databaseName, commandCreator.get(), connection,
writeConcernErrorTransformer())
Expand All @@ -247,7 +252,11 @@ public void executeAsync(final AsyncWriteBinding binding, final SingleResultCall
if (t != null) {
errHandlingCallback.onResult(null, t);
} else {
new ProcessCommandsCallback(binding, connection, releasingCallback(errHandlingCallback, connection))
SingleResultCallback<Void> releasingCallback = releasingCallback(errHandlingCallback, connection);
if (!checkEncryptedFieldsSupported(connection.getDescription(), releasingCallback)) {
return;
}
new ProcessCommandsCallback(binding, connection, releasingCallback)
.onResult(null, null);
}
});
Expand Down Expand Up @@ -276,14 +285,11 @@ private String getGranularityAsString(final TimeSeriesGranularity granularity) {
* <li>Create the collection with name encryptedFields["escCollection"] using default options.
* If encryptedFields["escCollection"] is not set, use the collection name enxcol_.<collectionName>.esc.
* Creating this collection MUST NOT check if the collection namespace is in the AutoEncryptionOpts.encryptedFieldsMap.
* <li>Create the collection with name encryptedFields["eccCollection"] using default options.
* If encryptedFields["eccCollection"] is not set, use the collection name enxcol_.<collectionName>.ecc.
* Creating this collection MUST NOT check if the collection namespace is in the AutoEncryptionOpts.encryptedFieldsMap.
* <li>Create the collection with name encryptedFields["ecocCollection"] using default options.
* If encryptedFields["ecocCollection"] is not set, use the collection name enxcol_.<collectionName>.ecoc.
* Creating this collection MUST NOT check if the collection namespace is in the AutoEncryptionOpts.encryptedFieldsMap.
* <li>Create the collection collectionName with collectionOptions and the option encryptedFields set to the encryptedFields.
* <li>Create the the index {"__safeContent__": 1} on collection collectionName.
* <li>Create the index {"__safeContent__": 1} on collection collectionName.
* </ol>
* </p>
* @return the list of commands to run to create the collection
Expand All @@ -294,7 +300,6 @@ private List<Supplier<BsonDocument>> getCommandFunctions() {
}
return asList(
() -> getCreateEncryptedFieldsCollectionCommand("esc"),
() -> getCreateEncryptedFieldsCollectionCommand("ecc"),
() -> getCreateEncryptedFieldsCollectionCommand("ecoc"),
this::getCreateCollectionCommand,
() -> new BsonDocument("createIndexes", new BsonString(collectionName))
Expand Down Expand Up @@ -361,6 +366,27 @@ private BsonDocument getCreateCollectionCommand() {
return document;
}

private void checkEncryptedFieldsSupported(final ConnectionDescription connectionDescription) throws MongoException {
if (encryptedFields != null && serverIsLessThanVersionSevenDotZero(connectionDescription)) {
throw new MongoClientException("Driver support of Queryable Encryption is incompatible with server."
+ " Upgrade server to use Queryable Encryption.");
}
}

/**
* @return {@code true} iff the {@linkplain #checkEncryptedFieldsSupported(ConnectionDescription) check} was successful.
* The {@code callback} is completed (with a failed result) iff the check was not successful.
*/
private boolean checkEncryptedFieldsSupported(final ConnectionDescription connectionDescription, final SingleResultCallback<Void> callback) {
try {
checkEncryptedFieldsSupported(connectionDescription);
return true;
} catch (Exception e) {
callback.onResult(null, e);
return false;
}
}

/**
* A SingleResultCallback that can be repeatedly called via onResult until all commands have been run.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ public void executeAsync(final AsyncWriteBinding binding, final SingleResultCall
* <li>Drop the collection collectionName.
* <li>Drop the collection with name encryptedFields["escCollection"].
* If encryptedFields["escCollection"] is not set, use the collection name enxcol_.<collectionName>.esc.</li>
* <li>Drop the collection with name encryptedFields["eccCollection"].
* If encryptedFields["eccCollection"] is not set, use the collection name enxcol_.<collectionName>.ecc.</li>
* <li>Drop the collection with name encryptedFields["ecocCollection"].
* If encryptedFields["ecocCollection"] is not set, use the collection name enxcol_.<collectionName>.ecoc.</li>
* </ol>
Expand All @@ -160,7 +158,6 @@ private List<Supplier<BsonDocument>> getCommands(final BsonDocument encryptedFie
} else {
return asList(
() -> getDropEncryptedFieldsCollectionCommand(encryptedFields, "esc"),
() -> getDropEncryptedFieldsCollectionCommand(encryptedFields, "ecc"),
() -> getDropEncryptedFieldsCollectionCommand(encryptedFields, "ecoc"),
this::dropCollectionCommand
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public final class ServerVersionHelper {
public static final int FOUR_DOT_FOUR_WIRE_VERSION = 9;
public static final int FIVE_DOT_ZERO_WIRE_VERSION = 12;
public static final int SIX_DOT_ZERO_WIRE_VERSION = 17;
private static final int SEVEN_DOT_ZERO_WIRE_VERSION = 21;

public static boolean serverIsAtLeastVersionFourDotZero(final ConnectionDescription description) {
return description.getMaxWireVersion() >= FOUR_DOT_ZERO_WIRE_VERSION;
Expand Down Expand Up @@ -60,6 +61,10 @@ public static boolean serverIsLessThanVersionFourDotFour(final ConnectionDescrip
return description.getMaxWireVersion() < FOUR_DOT_FOUR_WIRE_VERSION;
}

public static boolean serverIsLessThanVersionSevenDotZero(final ConnectionDescription description) {
return description.getMaxWireVersion() < SEVEN_DOT_ZERO_WIRE_VERSION;
}

private ServerVersionHelper() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -291,37 +291,25 @@ private static CommandStartedEvent massageExpectedCommandStartedEvent(final Comm
BsonDocument command = getWritableCloneOfCommand(event.getCommand());

massageCommand(event, command);

// The null-treatment below stems from
// https://github.com/mongodb/specifications/blob/master/source/transactions/tests/README.rst#null-values
if (lsidMap == null) {
command.remove("lsid");
} else if (command.containsKey("lsid")) {
command.put("lsid", lsidMap.get(command.getString("lsid").getValue()));
}

if (command.containsKey("txnNumber") && command.isNull("txnNumber")) {
command.remove("txnNumber");
}
if (command.containsKey("stmtId") && command.isNull("stmtId")) {
command.remove("stmtId");
}
if (command.containsKey("startTransaction") && command.isNull("startTransaction")) {
command.remove("startTransaction");
}
if (command.containsKey("autocommit") && command.isNull("autocommit")) {
command.remove("autocommit");
}
if (command.containsKey("maxTimeMS") && command.isNull("maxTimeMS")) {
command.remove("maxTimeMS");
}
if (command.containsKey("writeConcern") && command.isNull("writeConcern")) {
command.remove("writeConcern");
}
if (command.containsKey("allowDiskUse") && command.isNull("allowDiskUse")) {
command.remove("allowDiskUse");
for (String nullableFieldName : new String[] {"txnNumber", "stmtId", "startTransaction", "autocommit", "maxTimeMS", "writeConcern",
"allowDiskUse", "readConcern", "encryptedFields"}) {
if (command.isNull(nullableFieldName)) {
command.remove(nullableFieldName);
}
}
if (command.containsKey("readConcern")) {
if (command.isNull("readConcern")) {
command.remove("readConcern");
if (command.containsKey("encryptedFields")) {
BsonDocument encryptedFields = command.getDocument("encryptedFields");
for (String nullableFieldName : new String[] {"escCollection", "ecocCollection", "eccCollection"}) {
if (encryptedFields.isNull(nullableFieldName)) {
encryptedFields.remove(nullableFieldName);
}
}
}
command.remove("recoveryToken");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -33,4 +30,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand All @@ -23,4 +20,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -32,4 +29,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand All @@ -23,4 +20,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -32,4 +29,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -29,4 +26,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -29,4 +26,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"escCollection": "enxcol_.default.esc",
"eccCollection": "enxcol_.default.ecc",
"ecocCollection": "enxcol_.default.ecoc",
"fields": [
{
"keyId": {
Expand Down Expand Up @@ -30,4 +27,4 @@
"bsonType": "string"
}
]
}
}
Loading