diff --git a/CMakeLists.txt b/CMakeLists.txt index fe09b8857..e70cfd204 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,11 +25,6 @@ option (ENABLE_PIC ) option (ENABLE_BUILD_FOR_PPA "Maintainer-only option for preparing PPA build" OFF) option (ENABLE_ONLINE_TESTS "Enable online tests and the csfle utility. Requires libmongoc." ON) -# TODO MONGOCRYPT-661 When range V2 is default, remove this option. -option (ENABLE_USE_RANGE_V2 "Enable the use_range_v2 flag by default for queryable encryption" OFF) -if (ENABLE_USE_RANGE_V2) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DQE_USE_RANGE_V2") -endif () if (ENABLE_WINDOWS_STATIC_RUNTIME) if (POLICY CMP0091) diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java index 75c8e7c9f..999190b43 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java @@ -583,9 +583,8 @@ public interface mongocrypt_random_fn extends Callback { mongocrypt_ctx_setopt_query_type (mongocrypt_ctx_t ctx, cstring query_type, int len); /** - * Set options for explicit encryption with the "rangePreview" algorithm. - * NOTE: The RangePreview algorithm is experimental only. It is not intended for - * public use. + * Set options for explicit encryption with the "range" algorithm. + * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * opts is a BSON document of the form: * { @@ -887,9 +886,8 @@ public interface mongocrypt_random_fn extends Callback { /** * Explicit helper method to encrypt a Match Expression or Aggregate Expression. * Contexts created for explicit encryption will not go through mongocryptd. - * Requires query_type to be "rangePreview". - * NOTE: The RangePreview algorithm is experimental only. It is not intended for - * public use. + * Requires query_type to be "range". + * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * This method expects the passed-in BSON to be of the form: * { "v" : FLE2RangeFindDriverSpec } diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java index 7dbe236c4..e96808e84 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java @@ -114,7 +114,7 @@ public Builder queryType(final String queryType) { /** * The Range Options. * - *
It is an error to set rangeOptions when the algorithm is not "rangePreview".
+ *It is an error to set rangeOptions when the algorithm is not "range".
* * @param rangeOptions the range options * @return this @@ -202,11 +202,13 @@ private MongoExplicitEncryptOptions(Builder builder) { this.contentionFactor = builder.contentionFactor; this.queryType = builder.queryType; this.rangeOptions = builder.rangeOptions; - if (!(Objects.equals(algorithm, "Indexed") || Objects.equals(algorithm, "RangePreview"))) { + if (!(Objects.equals(algorithm, "Indexed") || Objects.equals(algorithm, "Range"))) { if (contentionFactor != null) { - throw new IllegalStateException("Invalid configuration, contentionFactor can only be set if algorithm is 'Indexed' or 'RangePreview'"); + throw new IllegalStateException( + "Invalid configuration, contentionFactor can only be set if algorithm is 'Indexed' or 'Range'"); } else if (queryType != null) { - throw new IllegalStateException("Invalid configuration, queryType can only be set if algorithm is 'Indexed' or 'RangePreview'"); + throw new IllegalStateException( + "Invalid configuration, queryType can only be set if algorithm is 'Indexed' or 'Range'"); } } } diff --git a/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java b/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java index 969a60a77..b9424cda4 100644 --- a/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +++ b/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java @@ -44,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertIterableEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; @SuppressWarnings("SameParameterValue") @@ -210,8 +211,8 @@ public void testExplicitExpressionEncryption() { MongoExplicitEncryptOptions options = MongoExplicitEncryptOptions.builder() .keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("q83vqxI0mHYSNBI0VniQEg=="))) - .algorithm("RangePreview") - .queryType("rangePreview") + .algorithm("Range") + .queryType("range") .contentionFactor(4L) .rangeOptions(rangeOptions) .build(); @@ -230,6 +231,47 @@ public void testExplicitExpressionEncryption() { mongoCrypt.close(); } + @Test + public void testRangePreviewQueryTypeIsNotSupported() { + MongoCrypt mongoCrypt = createMongoCrypt(); + assertNotNull(mongoCrypt); + + BsonDocument valueToEncrypt = getResourceAsDocument("fle2-find-range-explicit-v2/int32/value-to-encrypt.json"); + BsonDocument rangeOptions = getResourceAsDocument("fle2-find-range-explicit-v2/int32/rangeopts.json"); + + MongoExplicitEncryptOptions options = MongoExplicitEncryptOptions.builder() + .keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("q83vqxI0mHYSNBI0VniQEg=="))) + .algorithm("Range") + .queryType("rangePreview") + .contentionFactor(4L) + .rangeOptions(rangeOptions) + .build(); + + MongoCryptException exp = assertThrows(MongoCryptException.class, () -> mongoCrypt.createEncryptExpressionContext(valueToEncrypt, options)); + assertEquals("Query type 'rangePreview' is deprecated, please use 'range'", exp.getMessage()); + mongoCrypt.close(); + } + + @Test + public void testRangePreviewAlgorithmIsNotSupported() { + MongoCrypt mongoCrypt = createMongoCrypt(); + assertNotNull(mongoCrypt); + + BsonDocument rangeOptions = getResourceAsDocument("fle2-find-range-explicit-v2/int32/rangeopts.json"); + + IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> MongoExplicitEncryptOptions.builder() + .keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("q83vqxI0mHYSNBI0VniQEg=="))) + .algorithm("RangePreview") + .queryType("range") + .contentionFactor(4L) + .rangeOptions(rangeOptions) + .build()); + + assertEquals("Invalid configuration, contentionFactor can only be set if algorithm is 'Indexed' or 'Range'", + illegalStateException.getMessage()); + mongoCrypt.close(); + } + @Test public void testExplicitEncryptionDecryptionKeyAltName() throws IOException, URISyntaxException { MongoCrypt mongoCrypt = createMongoCrypt(); diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json index 5ef3da478..2e1407fe4 100644 --- a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json +++ b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json @@ -7,5 +7,8 @@ }, "sparsity": { "$numberLong": "1" + }, + "trimFactor": { + "$numberInt": "1" } } diff --git a/bindings/python/pymongocrypt/binding.py b/bindings/python/pymongocrypt/binding.py index 6d4234e8e..5394e2a5e 100644 --- a/bindings/python/pymongocrypt/binding.py +++ b/bindings/python/pymongocrypt/binding.py @@ -664,9 +664,7 @@ def _parse_version(version): /// String constant for setopt_algorithm "Random" encryption /// String constant for setopt_algorithm "Indexed" explicit encryption /// String constant for setopt_algorithm "Unindexed" explicit encryption -/// String constant for setopt_algorithm "rangePreview" explicit encryption (deprecated in favor of "range") -/// NOTE: "rangePreview" is experimental only and is not intended for public use. -/// API for "rangePreview" may be removed in a future release. +// DEPRECATED: support "RangePreview" has been removed in favor of "range". // NOTE: "Range" is currently unstable API and subject to backwards breaking changes. /** @@ -849,10 +847,8 @@ def _parse_version(version): /** * Explicit helper method to encrypt a Match Expression or Aggregate Expression. * Contexts created for explicit encryption will not go through mongocryptd. - * Requires query_type to be "range" or "rangePreview". + * Requires query_type to be "range". * - * NOTE: "rangePreview" is experimental only and is not intended for public use. - * API for "rangePreview" may be removed in a future release. * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * This method expects the passed-in BSON to be of the form: @@ -1363,7 +1359,7 @@ def _parse_version(version): void mongocrypt_setopt_bypass_query_analysis(mongocrypt_t *crypt); /** - * @brief Opt-into use of Queryable Encryption Range V2 protocol. + * DEPRECATED: Use of `mongocrypt_setopt_use_range_v2` is deprecated. Range V2 is always enabled. * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * @param[in] crypt The @ref mongocrypt_t object. @@ -1436,11 +1432,8 @@ def _parse_version(version): bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts); /// String constants for setopt_query_type -// 'rangePreview' is deprecated in favor of range. -/// NOTE: "rangePreview" is experimental only and is not intended for public use. -/// API for "rangePreview" may be removed in a future release. +// DEPRECATED: Support "rangePreview" has been removed in favor of "range". /// NOTE: "range" is currently unstable API and subject to backwards breaking changes. - """ ) diff --git a/bindings/python/pymongocrypt/mongocrypt.py b/bindings/python/pymongocrypt/mongocrypt.py index a48a3f2fe..88dd19c91 100644 --- a/bindings/python/pymongocrypt/mongocrypt.py +++ b/bindings/python/pymongocrypt/mongocrypt.py @@ -60,9 +60,6 @@ def __init__(self, options, callback): self.__crypt = lib.mongocrypt_new() if self.__crypt == ffi.NULL: raise MongoCryptError("unable to create new mongocrypt object") - if options.enable_range_v2: - if not lib.mongocrypt_setopt_use_range_v2(self.__crypt): - raise MongoCryptError("unable to enable QE Range Protocol V2") try: self.__init() diff --git a/bindings/python/pymongocrypt/options.py b/bindings/python/pymongocrypt/options.py index c932ee29e..6b905d492 100644 --- a/bindings/python/pymongocrypt/options.py +++ b/bindings/python/pymongocrypt/options.py @@ -11,7 +11,6 @@ def __init__( crypt_shared_lib_path=None, crypt_shared_lib_required=False, bypass_encryption=False, - enable_range_v2=False, ): """Options for :class:`MongoCrypt`. @@ -54,7 +53,9 @@ def __init__( - `crypt_shared_lib_required`: Whether to require a crypt_shared library. - `bypass_encryption`: Whether to bypass encryption. - - `enable_range_v2`: Whether to enable range V2. + + .. versionremoved:: 1.11 + Removed the ``enable_range_v2`` parameter. .. versionadded:: 1.10 Added the ``enable_range_v2`` parameter. @@ -143,7 +144,6 @@ def __init__( self.crypt_shared_lib_path = crypt_shared_lib_path self.crypt_shared_lib_required = crypt_shared_lib_required self.bypass_encryption = bypass_encryption - self.enable_range_v2 = enable_range_v2 class ExplicitEncryptOpts: diff --git a/bindings/python/test/performance/perf_test.py b/bindings/python/test/performance/perf_test.py index 211b2f5f6..2d66063d7 100644 --- a/bindings/python/test/performance/perf_test.py +++ b/bindings/python/test/performance/perf_test.py @@ -79,9 +79,7 @@ def tearDownModule(): class TestBulkDecryption(unittest.TestCase): def setUp(self): - opts = MongoCryptOptions( - {"local": {"key": LOCAL_MASTER_KEY}}, enable_range_v2=True - ) + opts = MongoCryptOptions({"local": {"key": LOCAL_MASTER_KEY}}) callback = MockCallback(key_docs=[bson_data("keyDocument.json")]) self.mongocrypt = MongoCrypt(opts, callback) self.encrypter = ExplicitEncrypter(callback, opts) diff --git a/bindings/python/test/test_mongocrypt.py b/bindings/python/test/test_mongocrypt.py index eb6a52f27..d492442c4 100644 --- a/bindings/python/test/test_mongocrypt.py +++ b/bindings/python/test/test_mongocrypt.py @@ -193,14 +193,6 @@ def test_mongocrypt_options_validation(self): ): MongoCryptOptions(valid_kms, encrypted_fields_map={}) - def test_mongocrypt_options_range(self): - opts = MongoCryptOptions({"local": {"key": b"\x00" * 96}}) - self.assertFalse(opts.enable_range_v2) - opts.enable_range_v2 = True - self.assertTrue(opts.enable_range_v2) - opts = MongoCryptOptions({"local": {"key": b"\x00" * 96}}, enable_range_v2=True) - self.assertTrue(opts.enable_range_v2) - class TestMongoCrypt(unittest.TestCase): maxDiff = None @@ -381,9 +373,7 @@ def test_encrypt_encrypted_fields_map(self): encrypted_fields_map = bson_data( "compact/success/encrypted-field-config-map.json" ) - mc = self.create_mongocrypt( - encrypted_fields_map=encrypted_fields_map, enable_range_v2=True - ) + mc = self.create_mongocrypt(encrypted_fields_map=encrypted_fields_map) self.addCleanup(mc.close) with mc.encryption_context("db", bson_data("compact/success/cmd.json")) as ctx: self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS) @@ -782,8 +772,7 @@ def mongo_crypt_opts(): { "aws": {"accessKeyId": "example", "secretAccessKey": "example"}, "local": {"key": b"\x00" * 96}, - }, - enable_range_v2=True, + } ) async def _test_encrypt_decrypt(self, key_id=None, key_alt_name=None): @@ -1212,13 +1201,12 @@ class TestExplicitEncryption(unittest.TestCase): maxDiff = None @staticmethod - def mongo_crypt_opts(enable_range_v2=True): + def mongo_crypt_opts(): return MongoCryptOptions( { "aws": {"accessKeyId": "example", "secretAccessKey": "example"}, "local": {"key": b"\x00" * 96}, - }, - enable_range_v2=enable_range_v2, + } ) def _test_encrypt_decrypt(self, key_id=None, key_alt_name=None): @@ -1424,30 +1412,36 @@ def test_range_query_int32(self): self.assertEqual(encrypted_val, adjust_range_counter(encrypted_val, expected)) def test_rangePreview_query_int32(self): - key_path = "keys/ABCDEFAB123498761234123456789012-local-document.json" - key_id = json_data(key_path)["_id"] - encrypter = ExplicitEncrypter( - MockCallback( - key_docs=[bson_data(key_path)], kms_reply=http_data("kms-reply.txt") - ), - self.mongo_crypt_opts(enable_range_v2=False), - ) - self.addCleanup(encrypter.close) + # Expect error attempting to use 'rangePreview' + with self.assertRaisesRegex( + MongoCryptError, + "Algorithm 'rangePreview' is deprecated, please use 'range'", + ): + key_path = "keys/ABCDEFAB123498761234123456789012-local-document.json" + key_id = json_data(key_path)["_id"] + encrypter = ExplicitEncrypter( + MockCallback( + key_docs=[bson_data(key_path)], kms_reply=http_data("kms-reply.txt") + ), + self.mongo_crypt_opts(), + ) + self.addCleanup(encrypter.close) - range_opts = bson_data("fle2-find-rangePreview-explicit/int32/rangeopts.json") - value = bson_data("fle2-find-rangePreview-explicit/int32/value-to-encrypt.json") - expected = json_data("fle2-find-range-explicit-v2/int32/encrypted-payload.json") - encrypted = encrypter.encrypt( - value, - "rangePreview", - key_id=key_id, - query_type="rangePreview", - contention_factor=4, - range_opts=range_opts, - is_expression=True, - ) - encrypted_val = bson.decode(encrypted, OPTS) - self.assertEqual(encrypted_val, adjust_range_counter(encrypted_val, expected)) + range_opts = bson_data( + "fle2-find-rangePreview-explicit/int32/rangeopts.json" + ) + value = bson_data( + "fle2-find-rangePreview-explicit/int32/value-to-encrypt.json" + ) + encrypter.encrypt( + value, + "rangePreview", + key_id=key_id, + query_type="rangePreview", + contention_factor=4, + range_opts=range_opts, + is_expression=True, + ) def read(filename, **kwargs): diff --git a/src/mongocrypt-opts.c b/src/mongocrypt-opts.c index ff6637116..dc6680aa0 100644 --- a/src/mongocrypt-opts.c +++ b/src/mongocrypt-opts.c @@ -35,9 +35,7 @@ void _mongocrypt_opts_kms_providers_init(_mongocrypt_opts_kms_providers_t *kms_p void _mongocrypt_opts_init(_mongocrypt_opts_t *opts) { BSON_ASSERT_PARAM(opts); memset(opts, 0, sizeof(*opts)); -#ifdef QE_USE_RANGE_V2 opts->use_range_v2 = true; -#endif _mongocrypt_opts_kms_providers_init(&opts->kms_providers); } diff --git a/src/mongocrypt.c b/src/mongocrypt.c index e746f1e9b..be73f5be3 100644 --- a/src/mongocrypt.c +++ b/src/mongocrypt.c @@ -156,7 +156,7 @@ bool mongocrypt_setopt_fle2v2(mongocrypt_t *crypt, bool enable) { bool mongocrypt_setopt_use_range_v2(mongocrypt_t *crypt) { ASSERT_MONGOCRYPT_PARAM_UNINIT(crypt); - crypt->opts.use_range_v2 = true; + // Nothing to do. As of MONGOCRYPT-661, rangeV2 is the default. return true; } diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 605277647..ab21a2997 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -686,9 +686,7 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith #define MONGOCRYPT_ALGORITHM_INDEXED_STR "Indexed" /// String constant for setopt_algorithm "Unindexed" explicit encryption #define MONGOCRYPT_ALGORITHM_UNINDEXED_STR "Unindexed" -/// String constant for setopt_algorithm "rangePreview" explicit encryption (deprecated in favor of "range") -/// NOTE: "rangePreview" is experimental only and is not intended for public use. -/// API for "rangePreview" may be removed in a future release. +// DEPRECATED: support "RangePreview" has been removed in favor of "range". #define MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR "RangePreview" // NOTE: "Range" is currently unstable API and subject to backwards breaking changes. #define MONGOCRYPT_ALGORITHM_RANGE_STR "Range" @@ -880,10 +878,8 @@ bool mongocrypt_ctx_explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_bina /** * Explicit helper method to encrypt a Match Expression or Aggregate Expression. * Contexts created for explicit encryption will not go through mongocryptd. - * Requires query_type to be "range" or "rangePreview". + * Requires query_type to be "range". * - * NOTE: "rangePreview" is experimental only and is not intended for public use. - * API for "rangePreview" may be removed in a future release. * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * This method expects the passed-in BSON to be of the form: @@ -1419,7 +1415,7 @@ MONGOCRYPT_EXPORT void mongocrypt_setopt_bypass_query_analysis(mongocrypt_t *crypt); /** - * @brief Opt-into use of Queryable Encryption Range V2 protocol. + * DEPRECATED: Use of `mongocrypt_setopt_use_range_v2` is deprecated. Range V2 is always enabled. * NOTE: "range" is currently unstable API and subject to backwards breaking changes. * * @param[in] crypt The @ref mongocrypt_t object. @@ -1498,9 +1494,7 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin /// String constants for setopt_query_type #define MONGOCRYPT_QUERY_TYPE_EQUALITY_STR "equality" -// 'rangePreview' is deprecated in favor of range. -/// NOTE: "rangePreview" is experimental only and is not intended for public use. -/// API for "rangePreview" may be removed in a future release. +// DEPRECATED: Support "rangePreview" has been removed in favor of "range". #define MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR "rangePreview" /// NOTE: "range" is currently unstable API and subject to backwards breaking changes. #define MONGOCRYPT_QUERY_TYPE_RANGE_STR "range"