Skip to content
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
4 changes: 4 additions & 0 deletions lib/mongo/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,10 @@ def hash
# (this part of the API is subject to change).
# - :encrypted_fields_map => Hash | nil, maps a collection namespace to
# a hash describing encrypted fields for queryable encryption.
# - Note: Supplying an encrypted_fields_map provides more security
# than relying on an encryptedFields obtained from the server. It
# protects against a malicious server advertising a false
# encryptedFields.
# - Note: If a collection is present on both the encryptedFieldsMap
# and schemaMap, an error will be raised.
Comment on lines +516 to 521
# - :bypass_query_analysis => Boolean | nil, when true disables automatic
Expand Down
13 changes: 7 additions & 6 deletions lib/mongo/collection/queryable_encryption.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def maybe_create_qe_collections(encrypted_fields, client, session)
def maybe_drop_emm_collections(encrypted_fields, client, session)
encrypted_fields = if encrypted_fields
encrypted_fields
elsif encrypted_fields_map
encrypted_fields_for_drop_from_map
elsif client.options[:auto_encryption_options]
encrypted_fields_for_drop
else
{}
end
Expand Down Expand Up @@ -127,12 +127,13 @@ def encrypted_fields_from(fields)
{}
end

# Tries to return the encrypted fields from the {{encrypted_fields_map}}
# value, for the current namespace.
# Tries to return the encrypted fields for the current namespace from
# the {{encrypted_fields_map}} value, falling back to the encrypted
# fields advertised by the server for the collection.
#
# @return [ Hash | nil ] the encrypted fields, if found
def encrypted_fields_for_drop_from_map
encrypted_fields_map[namespace] ||
def encrypted_fields_for_drop
(encrypted_fields_map && encrypted_fields_map[namespace]) ||
database.list_collections(filter: { name: name })
.first
&.fetch(:options, {})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'Queryable encryption drop collection' do
require_libmongocrypt
min_server_version '7.0.0-rc0'
require_topology :replica_set, :sharded, :load_balanced

include_context 'define shared FLE helpers'

let(:encrypted_coll) { 'qe_drop_lookup' }

# The shared fixture hardcodes metadata collection names for a collection
# named "default"; remove them so the default enxcol_.<name>.esc/.ecoc
# names for the collection under test apply.
let(:encrypted_fields) do
BSON::ExtJSON.parse(
File.read('spec/support/crypt/encrypted_fields/encryptedFields.json')
).tap do |fields|
fields.delete('escCollection')
fields.delete('ecocCollection')
end
end

let(:auto_encryption_options) do
{
key_vault_namespace: key_vault_namespace,
kms_providers: local_kms_providers,
bypass_query_analysis: true
}
end

let(:encrypted_client) do
ClientRegistry.instance.new_local_client(
SpecConfig.instance.addresses,
auto_encryption_options: auto_encryption_options,
database: SpecConfig.instance.test_db
)
end

before do
authorized_client[encrypted_coll].drop(encrypted_fields: encrypted_fields)
authorized_client[encrypted_coll].create(encrypted_fields: encrypted_fields)
end

after do
authorized_client[encrypted_coll].drop(encrypted_fields: encrypted_fields)
end

shared_examples 'drops the metadata collections' do
it 'looks up encryptedFields on the server and drops the metadata collections' do
expect(authorized_client.database.collection_names)
.to include("enxcol_.#{encrypted_coll}.esc", "enxcol_.#{encrypted_coll}.ecoc")

encrypted_client[encrypted_coll].drop

collection_names = authorized_client.database.collection_names
expect(collection_names).not_to include("enxcol_.#{encrypted_coll}.esc")
expect(collection_names).not_to include("enxcol_.#{encrypted_coll}.ecoc")
expect(collection_names).not_to include(encrypted_coll)
end
end

context 'when auto encryption is configured without encrypted_fields_map' do
include_examples 'drops the metadata collections'
end

context 'when encrypted_fields_map has no entry for the collection' do
let(:auto_encryption_options) do
super().merge(encrypted_fields_map: {})
end

include_examples 'drops the metadata collections'
end
end
Loading