Skip to content

Commit

Permalink
GODRIVER-3123 QE Range Protocol V2 (#1723)
Browse files Browse the repository at this point in the history
  • Loading branch information
qingyang-hu authored Aug 19, 2024
1 parent 758291c commit a766876
Show file tree
Hide file tree
Showing 105 changed files with 2,009 additions and 1,417 deletions.
8 changes: 4 additions & 4 deletions etc/install-libmongocrypt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This script installs libmongocrypt into an "install" directory.
set -eux

LIBMONGOCRYPT_TAG="1.8.2"
LIBMONGOCRYPT_TAG="1.11.0"

# Install libmongocrypt based on OS.
if [ "Windows_NT" = "${OS:-}" ]; then
Expand All @@ -13,11 +13,11 @@ if [ "Windows_NT" = "${OS:-}" ]; then
mkdir libmongocrypt-all
cd libmongocrypt-all
# The following URL is published from the upload-all task in the libmongocrypt Evergreen project.
curl https://mciuploads.s3.amazonaws.com/libmongocrypt/all/$LIBMONGOCRYPT_TAG/libmongocrypt-all.tar.gz -o libmongocrypt-all.tar.gz
curl -L https://github.com/mongodb/libmongocrypt/releases/download/$LIBMONGOCRYPT_TAG/libmongocrypt-windows-x86_64-$LIBMONGOCRYPT_TAG.tar.gz -o libmongocrypt-all.tar.gz
tar -xf libmongocrypt-all.tar.gz
cd ..
cp libmongocrypt-all/windows-test/bin/mongocrypt.dll c:/libmongocrypt/bin
cp libmongocrypt-all/windows-test/include/mongocrypt/*.h c:/libmongocrypt/include
cp libmongocrypt-all/bin/mongocrypt.dll c:/libmongocrypt/bin
cp libmongocrypt-all/include/mongocrypt/*.h c:/libmongocrypt/include

rm -rf libmongocrypt-all
echo "fetching build for Windows ... end"
Expand Down
10 changes: 7 additions & 3 deletions mongo/client_encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ func transformExplicitEncryptionOptions(opts ...*options.EncryptOptions) *mcopts
if eo.RangeOptions.Precision != nil {
transformedRange.Precision = eo.RangeOptions.Precision
}
transformedRange.Sparsity = eo.RangeOptions.Sparsity
if eo.RangeOptions.Sparsity != nil {
transformedRange.Sparsity = eo.RangeOptions.Sparsity
}
if eo.RangeOptions.TrimFactor != nil {
transformedRange.TrimFactor = eo.RangeOptions.TrimFactor
}
transformed.SetRangeOptions(transformedRange)
}
return transformed
Expand All @@ -230,8 +235,7 @@ func (ce *ClientEncryption) Encrypt(ctx context.Context, val bson.RawValue,
// 2. An Aggregate Expression of this form:
// {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
// $gt may also be $gte. $lt may also be $lte.
// Only supported for queryType "rangePreview"
// Beta: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
// Only supported for queryType "range"
func (ce *ClientEncryption) EncryptExpression(ctx context.Context, expr interface{}, result interface{}, opts ...*options.EncryptOptions) error {
transformed := transformExplicitEncryptionOptions(opts...)

Expand Down
141 changes: 107 additions & 34 deletions mongo/integration/client_side_encryption_prose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2465,8 +2465,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
}
})

// GODRIVER-3123. When we implement this feature, lower the min server version to 8.0.1
qeRunOpts22 := qeRunOpts.MaxServerVersion("7.99.99")
qeRunOpts22 := qeRunOpts.MinServerVersion("8.0")
mt.RunOpts("22. range explicit encryption", qeRunOpts22, func(mt *mtest.T) {
type testcase struct {
typeStr string
Expand All @@ -2480,6 +2479,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
twoHundredOne bson.RawValue
}

trimFactor := int32(1)
sparsity := int64(1)
precision := int32(2)

d128_0, err := primitive.ParseDecimal128("0")
Expand All @@ -2499,7 +2500,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedDecimalNoPrecision",
typeBson: bson.TypeDecimal128,
rangeOpts: options.RangeOptions{
Sparsity: 1,
TrimFactor: &trimFactor,
Sparsity: &sparsity,
},
zero: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
six: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_6)},
Expand All @@ -2512,10 +2514,11 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedDecimalPrecision",
typeBson: bson.TypeDecimal128,
rangeOpts: options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
Max: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_200)},
Sparsity: 1,
Precision: &precision,
Min: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
Max: &bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_200)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
Precision: &precision,
},
zero: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_0)},
six: bson.RawValue{Type: bson.TypeDecimal128, Value: bsoncore.AppendDecimal128(nil, d128_6)},
Expand All @@ -2528,7 +2531,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedDoubleNoPrecision",
typeBson: bson.TypeDouble,
rangeOpts: options.RangeOptions{
Sparsity: 1,
TrimFactor: &trimFactor,
Sparsity: &sparsity,
},
zero: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
six: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 6)},
Expand All @@ -2541,10 +2545,11 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedDoublePrecision",
typeBson: bson.TypeDouble,
rangeOpts: options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 200)},
Sparsity: 1,
Precision: &precision,
Min: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 200)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
Precision: &precision,
},
zero: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 0)},
six: bson.RawValue{Type: bson.TypeDouble, Value: bsoncore.AppendDouble(nil, 6)},
Expand All @@ -2557,9 +2562,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedDate",
typeBson: bson.TypeDateTime,
rangeOpts: options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 200)},
Sparsity: 1,
Min: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 200)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
},
zero: bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 0)},
six: bson.RawValue{Type: bson.TypeDateTime, Value: bsoncore.AppendDateTime(nil, 6)},
Expand All @@ -2572,9 +2578,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedInt",
typeBson: bson.TypeInt32,
rangeOpts: options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 200)},
Sparsity: 1,
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 200)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
},
zero: bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
six: bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 6)},
Expand All @@ -2587,9 +2594,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
field: "encryptedLong",
typeBson: bson.TypeInt64,
rangeOpts: options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 200)},
Sparsity: 1,
Min: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 200)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
},
zero: bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 0)},
six: bson.RawValue{Type: bson.TypeInt64, Value: bsoncore.AppendInt64(nil, 6)},
Expand Down Expand Up @@ -2645,7 +2653,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
// Insert 0, 6, 30, and 200.
coll := encryptedClient.Database("db").Collection("explicit_encryption")
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetRangeOptions(test.rangeOpts)
Expand Down Expand Up @@ -2692,7 +2700,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetRangeOptions(test.rangeOpts)
Expand All @@ -2708,10 +2716,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetQueryType("rangePreview").
SetQueryType("range").
SetRangeOptions(test.rangeOpts)

expr := bson.M{
Expand Down Expand Up @@ -2750,10 +2758,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetQueryType("rangePreview").
SetQueryType("range").
SetRangeOptions(test.rangeOpts)

expr := bson.M{
Expand Down Expand Up @@ -2792,10 +2800,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetQueryType("rangePreview").
SetQueryType("range").
SetRangeOptions(test.rangeOpts)

expr := bson.M{
Expand Down Expand Up @@ -2829,10 +2837,10 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetQueryType("rangePreview").
SetQueryType("range").
SetRangeOptions(test.rangeOpts)

expr := bson.M{
Expand Down Expand Up @@ -2868,7 +2876,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetRangeOptions(test.rangeOpts)
Expand All @@ -2882,7 +2890,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
defer clientEncryption.Close(context.Background())
defer encryptedClient.Disconnect(context.Background())
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetRangeOptions(test.rangeOpts)
Expand All @@ -2909,7 +2917,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
ro := test.rangeOpts
ro.SetPrecision(2)
eo := options.Encrypt().
SetAlgorithm("RangePreview").
SetAlgorithm("Range").
SetKeyID(key1ID).
SetContentionFactor(0).
SetRangeOptions(ro)
Expand All @@ -2921,6 +2929,71 @@ func TestClientSideEncryptionProse(t *testing.T) {
})
}
})

mt.RunOpts("22. range explicit encryption applies defaults", qeRunOpts22, func(mt *mtest.T) {
err := mt.Client.Database("keyvault").Collection("datakeys").Drop(context.Background())
assert.Nil(mt, err, "error on Drop: %v", err)

testVal := bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 123)}

keyVaultClient, err := mongo.Connect(context.Background(), options.Client().ApplyURI(mtest.ClusterURI()))
assert.Nil(mt, err, "error on Connect: %v", err)

ceo := options.ClientEncryption().
SetKeyVaultNamespace("keyvault.datakeys").
SetKmsProviders(fullKmsProvidersMap)
clientEncryption, err := mongo.NewClientEncryption(keyVaultClient, ceo)
assert.Nil(mt, err, "error on NewClientEncryption: %v", err)

dkOpts := options.DataKey()
keyID, err := clientEncryption.CreateDataKey(context.Background(), "local", dkOpts)
assert.Nil(mt, err, "error in CreateDataKey: %v", err)

eo := options.Encrypt().
SetAlgorithm("Range").
SetKeyID(keyID).
SetContentionFactor(0).
SetRangeOptions(options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
})
payloadDefaults, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
assert.Nil(mt, err, "error in Encrypt: %v", err)

mt.Run("Case 1: uses libmongocrypt defaults", func(mt *mtest.T) {
trimFactor := int32(6)
sparsity := int64(2)
eo := options.Encrypt().
SetAlgorithm("Range").
SetKeyID(keyID).
SetContentionFactor(0).
SetRangeOptions(options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
TrimFactor: &trimFactor,
Sparsity: &sparsity,
})
payload, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
assert.Nil(mt, err, "error in Encrypt: %v", err)
assert.Equalf(mt, len(payload.Data), len(payloadDefaults.Data), "the returned payload size is expected to be %d", len(payloadDefaults.Data))
})

mt.Run("Case 2: accepts trimFactor 0", func(mt *mtest.T) {
trimFactor := int32(0)
eo := options.Encrypt().
SetAlgorithm("Range").
SetKeyID(keyID).
SetContentionFactor(0).
SetRangeOptions(options.RangeOptions{
Min: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 0)},
Max: &bson.RawValue{Type: bson.TypeInt32, Value: bsoncore.AppendInt32(nil, 1000)},
TrimFactor: &trimFactor,
})
payload, err := clientEncryption.Encrypt(context.Background(), testVal, eo)
assert.Nil(mt, err, "error in Encrypt: %v", err)
assert.Greater(t, len(payload.Data), len(payloadDefaults.Data), "the returned payload size is expected to be greater than %d", len(payloadDefaults.Data))
})
})
}

func getWatcher(mt *mtest.T, streamType mongo.StreamType, cpt *cseProseTest) watcher {
Expand Down
Loading

0 comments on commit a766876

Please sign in to comment.