Skip to content

Commit 9660ea8

Browse files
authored
RUST-1843 Support for QE range protocol V2 (#1132)
1 parent ac7fc24 commit 9660ea8

File tree

99 files changed

+4046
-4336
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+4046
-4336
lines changed

src/action/csfle/encrypt.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ impl ClientEncryption {
3333
}
3434
}
3535

36-
/// NOTE: This method is experimental only. It is not intended for public use.
36+
/// Encrypts a Match Expression or Aggregate Expression to query a range index.
37+
/// `expression` is expected to be a BSON document of one of the following forms:
38+
/// 1. A Match Expression of this form:
39+
/// {$and: [{<field>: {$gt: <value1>}}, {<field>: {$lt: <value2> }}]}
40+
/// 2. An Aggregate Expression of this form:
41+
/// {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
42+
/// $gt may also be $gte. $lt may also be $lte.
3743
///
38-
/// Encrypts a match or aggregate expression with the given key.
39-
///
40-
/// The expression will be encrypted using the [`Algorithm::RangePreview`] algorithm and the
41-
/// "rangePreview" query type.
44+
/// The expression will be encrypted using the [`Algorithm::Range`] algorithm and the
45+
/// "range" query type.
4246
///
4347
/// `await` will return a d[`Result<Document>`] containing the encrypted expression.
4448
#[deeplink]
@@ -51,10 +55,9 @@ impl ClientEncryption {
5155
client_enc: self,
5256
mode: Expression { value: expression },
5357
key: key.into(),
54-
#[allow(deprecated)]
55-
algorithm: Algorithm::RangePreview,
58+
algorithm: Algorithm::Range,
5659
options: Some(EncryptOptions {
57-
query_type: Some("rangePreview".into()),
60+
query_type: Some("range".into()),
5861
..Default::default()
5962
}),
6063
}
@@ -109,19 +112,16 @@ pub struct EncryptOptions {
109112
pub contention_factor: Option<i64>,
110113
/// The query type.
111114
pub query_type: Option<String>,
112-
/// NOTE: This method is experimental and not intended for public use.
113-
///
114-
/// Set the range options. This method should only be called when the algorithm is
115-
/// [`Algorithm::RangePreview`].
115+
/// Set the range options. This should only be set when the algorithm is
116+
/// [`Algorithm::Range`].
116117
pub range_options: Option<RangeOptions>,
117118
}
118119

119-
/// NOTE: These options are experimental and not intended for public use.
120-
///
121-
/// The index options for a Queryable Encryption field supporting "rangePreview" queries.
120+
/// The index options for a Queryable Encryption field supporting "range" queries.
122121
/// The options set must match the values set in the encryptedFields of the destination collection.
123122
#[skip_serializing_none]
124123
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
124+
#[serde(rename_all = "camelCase")]
125125
#[builder(field_defaults(default, setter(into)))]
126126
#[non_exhaustive]
127127
pub struct RangeOptions {
@@ -131,6 +131,9 @@ pub struct RangeOptions {
131131
/// The maximum value. This option must be set if `precision` is set.
132132
pub max: Option<Bson>,
133133

134+
/// The trim factor.
135+
pub trim_factor: i32,
136+
134137
/// The sparsity.
135138
pub sparsity: i64,
136139

src/client/csfle.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ impl ClientState {
9999
fn make_crypt(opts: &AutoEncryptionOptions) -> Result<Crypt> {
100100
let mut builder = Crypt::builder()
101101
.kms_providers(&opts.kms_providers.credentials_doc()?)?
102-
.use_need_kms_credentials_state();
102+
.use_need_kms_credentials_state()
103+
.use_range_v2()?;
103104
if let Some(m) = &opts.schema_map {
104105
builder = builder.schema_map(&bson::to_document(m)?)?;
105106
}

src/client/csfle/client_encryption.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl ClientEncryption {
6363
let crypt = Crypt::builder()
6464
.kms_providers(&kms_providers.credentials_doc()?)?
6565
.use_need_kms_credentials_state()
66+
.use_range_v2()?
6667
.build()?;
6768
let exec = CryptExecutor::new_explicit(
6869
key_vault_client.weak(),

src/test/csfle.rs

+13-25
Original file line numberDiff line numberDiff line change
@@ -2977,19 +2977,20 @@ async fn range_explicit_encryption() -> Result<()> {
29772977
return Ok(());
29782978
}
29792979
let client = TestClient::new().await;
2980-
if client.server_version_lt(6, 2) || client.server_version_gte(8, 0) || client.is_standalone() {
2980+
if client.server_version_lt(8, 0) || client.is_standalone() {
29812981
log_uncaptured("Skipping range_explicit_encryption due to unsupported topology");
29822982
return Ok(());
29832983
}
29842984

29852985
range_explicit_encryption_test(
29862986
"DecimalNoPrecision",
2987-
RangeOptions::builder().sparsity(1).build(),
2987+
RangeOptions::builder().sparsity(1).trim_factor(1).build(),
29882988
)
29892989
.await?;
29902990
range_explicit_encryption_test(
29912991
"DecimalPrecision",
29922992
RangeOptions::builder()
2993+
.trim_factor(1)
29932994
.sparsity(1)
29942995
.min(Bson::Decimal128("0".parse()?))
29952996
.max(Bson::Decimal128("200".parse()?))
@@ -2999,12 +3000,13 @@ async fn range_explicit_encryption() -> Result<()> {
29993000
.await?;
30003001
range_explicit_encryption_test(
30013002
"DoubleNoPrecision",
3002-
RangeOptions::builder().sparsity(1).build(),
3003+
RangeOptions::builder().trim_factor(1).sparsity(1).build(),
30033004
)
30043005
.await?;
30053006
range_explicit_encryption_test(
30063007
"DoublePrecision",
30073008
RangeOptions::builder()
3009+
.trim_factor(1)
30083010
.sparsity(1)
30093011
.min(Bson::Double(0.0))
30103012
.max(Bson::Double(200.0))
@@ -3015,6 +3017,7 @@ async fn range_explicit_encryption() -> Result<()> {
30153017
range_explicit_encryption_test(
30163018
"Date",
30173019
RangeOptions::builder()
3020+
.trim_factor(1)
30183021
.sparsity(1)
30193022
.min(Bson::DateTime(DateTime::from_millis(0)))
30203023
.max(Bson::DateTime(DateTime::from_millis(200)))
@@ -3024,6 +3027,7 @@ async fn range_explicit_encryption() -> Result<()> {
30243027
range_explicit_encryption_test(
30253028
"Int",
30263029
RangeOptions::builder()
3030+
.trim_factor(1)
30273031
.sparsity(1)
30283032
.min(Bson::Int32(0))
30293033
.max(Bson::Int32(200))
@@ -3033,6 +3037,7 @@ async fn range_explicit_encryption() -> Result<()> {
30333037
range_explicit_encryption_test(
30343038
"Long",
30353039
RangeOptions::builder()
3040+
.trim_factor(1)
30363041
.sparsity(1)
30373042
.min(Bson::Int64(0))
30383043
.max(Bson::Int64(200))
@@ -3114,12 +3119,7 @@ async fn range_explicit_encryption_test(
31143119

31153120
for (id, num) in bson_numbers.keys().enumerate() {
31163121
let encrypted_value = client_encryption
3117-
.encrypt(
3118-
bson_numbers[num].clone(),
3119-
key1_id.clone(),
3120-
#[allow(deprecated)]
3121-
Algorithm::RangePreview,
3122-
)
3122+
.encrypt(bson_numbers[num].clone(), key1_id.clone(), Algorithm::Range)
31233123
.contention_factor(0)
31243124
.range_options(range_options.clone())
31253125
.await?;
@@ -3134,12 +3134,7 @@ async fn range_explicit_encryption_test(
31343134

31353135
// Case 1: Decrypt a payload
31363136
let insert_payload = client_encryption
3137-
.encrypt(
3138-
bson_numbers[&6].clone(),
3139-
key1_id.clone(),
3140-
#[allow(deprecated)]
3141-
Algorithm::RangePreview,
3142-
)
3137+
.encrypt(bson_numbers[&6].clone(), key1_id.clone(), Algorithm::Range)
31433138
.contention_factor(0)
31443139
.range_options(range_options.clone())
31453140
.await?;
@@ -3250,9 +3245,8 @@ async fn range_explicit_encryption_test(
32503245
// Case 6: Encrypting a document greater than the maximum errors
32513246
if bson_type != "DoubleNoPrecision" && bson_type != "DecimalNoPrecision" {
32523247
let num = get_raw_bson_from_num(bson_type, 201);
3253-
#[allow(deprecated)]
32543248
let error = client_encryption
3255-
.encrypt(num, key1_id.clone(), Algorithm::RangePreview)
3249+
.encrypt(num, key1_id.clone(), Algorithm::Range)
32563250
.contention_factor(0)
32573251
.range_options(range_options.clone())
32583252
.await
@@ -3267,9 +3261,8 @@ async fn range_explicit_encryption_test(
32673261
} else {
32683262
rawdoc! { &key: { "$numberInt": "6" } }
32693263
};
3270-
#[allow(deprecated)]
32713264
let error = client_encryption
3272-
.encrypt(value, key1_id.clone(), Algorithm::RangePreview)
3265+
.encrypt(value, key1_id.clone(), Algorithm::Range)
32733266
.contention_factor(0)
32743267
.range_options(range_options.clone())
32753268
.await
@@ -3286,12 +3279,7 @@ async fn range_explicit_encryption_test(
32863279
.precision(2)
32873280
.build();
32883281
let error = client_encryption
3289-
.encrypt(
3290-
bson_numbers[&6].clone(),
3291-
key1_id.clone(),
3292-
#[allow(deprecated)]
3293-
Algorithm::RangePreview,
3294-
)
3282+
.encrypt(bson_numbers[&6].clone(), key1_id.clone(), Algorithm::Range)
32953283
.contention_factor(0)
32963284
.range_options(range_options)
32973285
.await

0 commit comments

Comments
 (0)