mongo 2.11.6 → 2.12.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/mongo.rb +3 -0
- data/lib/mongo/address.rb +13 -2
- data/lib/mongo/auth.rb +1 -0
- data/lib/mongo/auth/credential_cache.rb +51 -0
- data/lib/mongo/auth/scram/conversation.rb +20 -16
- data/lib/mongo/auth/user.rb +0 -8
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/background_thread.rb +1 -1
- data/lib/mongo/bulk_write.rb +5 -5
- data/lib/mongo/client.rb +126 -11
- data/lib/mongo/client_encryption.rb +103 -0
- data/lib/mongo/cluster.rb +2 -2
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
- data/lib/mongo/cluster/sdam_flow.rb +54 -58
- data/lib/mongo/cluster/srv_monitor.rb +1 -1
- data/lib/mongo/collection.rb +3 -3
- data/lib/mongo/collection/view.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +12 -3
- data/lib/mongo/collection/view/iterable.rb +14 -5
- data/lib/mongo/collection/view/map_reduce.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +7 -9
- data/lib/mongo/collection/view/writable.rb +7 -7
- data/lib/mongo/crypt.rb +33 -0
- data/lib/mongo/crypt/auto_decryption_context.rb +42 -0
- data/lib/mongo/crypt/auto_encrypter.rb +169 -0
- data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
- data/lib/mongo/crypt/binary.rb +155 -0
- data/lib/mongo/crypt/binding.rb +1162 -0
- data/lib/mongo/crypt/context.rb +135 -0
- data/lib/mongo/crypt/data_key_context.rb +162 -0
- data/lib/mongo/crypt/encryption_io.rb +283 -0
- data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
- data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
- data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
- data/lib/mongo/crypt/handle.rb +293 -0
- data/lib/mongo/crypt/hooks.rb +90 -0
- data/lib/mongo/crypt/kms_context.rb +67 -0
- data/lib/mongo/crypt/status.rb +131 -0
- data/lib/mongo/cursor.rb +64 -32
- data/lib/mongo/database.rb +13 -6
- data/lib/mongo/database/view.rb +13 -4
- data/lib/mongo/dbref.rb +9 -2
- data/lib/mongo/error.rb +5 -1
- data/lib/mongo/error/crypt_error.rb +31 -0
- data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
- data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
- data/lib/mongo/error/kms_error.rb +22 -0
- data/lib/mongo/error/max_bson_size.rb +14 -3
- data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
- data/lib/mongo/error/no_server_available.rb +8 -3
- data/lib/mongo/error/operation_failure.rb +1 -0
- data/lib/mongo/grid/file.rb +0 -5
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/file/info.rb +2 -1
- data/lib/mongo/grid/fs_bucket.rb +13 -15
- data/lib/mongo/grid/stream/write.rb +3 -9
- data/lib/mongo/index/view.rb +3 -3
- data/lib/mongo/monitoring/event/command_started.rb +6 -1
- data/lib/mongo/operation/collections_info.rb +6 -3
- data/lib/mongo/operation/delete/op_msg.rb +1 -1
- data/lib/mongo/operation/find/op_msg.rb +4 -1
- data/lib/mongo/operation/get_more/op_msg.rb +4 -1
- data/lib/mongo/operation/insert/command.rb +2 -2
- data/lib/mongo/operation/insert/legacy.rb +2 -2
- data/lib/mongo/operation/insert/op_msg.rb +3 -3
- data/lib/mongo/operation/result.rb +36 -27
- data/lib/mongo/operation/shared/executable.rb +10 -8
- data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
- data/lib/mongo/operation/shared/write.rb +17 -10
- data/lib/mongo/operation/update/op_msg.rb +1 -1
- data/lib/mongo/protocol/compressed.rb +6 -5
- data/lib/mongo/protocol/insert.rb +3 -1
- data/lib/mongo/protocol/message.rb +72 -8
- data/lib/mongo/protocol/msg.rb +191 -37
- data/lib/mongo/protocol/query.rb +7 -9
- data/lib/mongo/protocol/serializers.rb +6 -2
- data/lib/mongo/server.rb +10 -4
- data/lib/mongo/server/connection.rb +20 -9
- data/lib/mongo/server/connection_base.rb +81 -12
- data/lib/mongo/server/connection_common.rb +61 -0
- data/lib/mongo/server/connection_pool.rb +37 -1
- data/lib/mongo/server/description.rb +9 -11
- data/lib/mongo/server/monitor.rb +2 -0
- data/lib/mongo/server/monitor/connection.rb +3 -18
- data/lib/mongo/server/pending_connection.rb +2 -1
- data/lib/mongo/session.rb +2 -2
- data/lib/mongo/session/session_pool.rb +8 -3
- data/lib/mongo/socket.rb +29 -16
- data/lib/mongo/socket/ssl.rb +23 -8
- data/lib/mongo/socket/tcp.rb +12 -3
- data/lib/mongo/timeout.rb +49 -0
- data/lib/mongo/uri.rb +30 -1
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/README.md +134 -7
- data/spec/integration/auth_spec.rb +53 -0
- data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
- data/spec/integration/client_construction_spec.rb +76 -1
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +351 -0
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +301 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +71 -0
- data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +76 -0
- data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +216 -0
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +600 -0
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +183 -0
- data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +74 -0
- data/spec/integration/client_side_encryption/client_close_spec.rb +59 -0
- data/spec/integration/client_side_encryption/corpus_spec.rb +228 -0
- data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
- data/spec/integration/client_side_encryption/data_key_spec.rb +163 -0
- data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
- data/spec/integration/client_side_encryption/external_key_vault_spec.rb +137 -0
- data/spec/integration/client_side_encryption/views_spec.rb +42 -0
- data/spec/integration/client_update_spec.rb +120 -0
- data/spec/integration/command_monitoring_spec.rb +3 -1
- data/spec/integration/command_spec.rb +44 -10
- data/spec/integration/connection_spec.rb +57 -0
- data/spec/integration/reconnect_spec.rb +7 -6
- data/spec/integration/size_limit_spec.rb +94 -0
- data/spec/integration/srv_monitoring_spec.rb +14 -6
- data/spec/lite_spec_helper.rb +31 -22
- data/spec/mongo/auth/cr_spec.rb +8 -0
- data/spec/mongo/auth/ldap_spec.rb +5 -1
- data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
- data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
- data/spec/mongo/auth/scram_spec.rb +45 -35
- data/spec/mongo/auth/x509_spec.rb +5 -1
- data/spec/mongo/client_construction_spec.rb +206 -3
- data/spec/mongo/client_encryption_spec.rb +408 -0
- data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
- data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
- data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
- data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
- data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
- data/spec/mongo/collection/view_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +4 -33
- data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
- data/spec/mongo/crypt/auto_encrypter_spec.rb +182 -0
- data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
- data/spec/mongo/crypt/binary_spec.rb +115 -0
- data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
- data/spec/mongo/crypt/binding/context_spec.rb +257 -0
- data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
- data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
- data/spec/mongo/crypt/binding/status_spec.rb +99 -0
- data/spec/mongo/crypt/binding/version_spec.rb +22 -0
- data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
- data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
- data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
- data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
- data/spec/mongo/crypt/handle_spec.rb +198 -0
- data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
- data/spec/mongo/crypt/status_spec.rb +152 -0
- data/spec/mongo/cursor_spec.rb +24 -4
- data/spec/mongo/database_spec.rb +20 -0
- data/spec/mongo/error/crypt_error_spec.rb +26 -0
- data/spec/mongo/error/max_bson_size_spec.rb +35 -0
- data/spec/mongo/error/no_server_available_spec.rb +11 -1
- data/spec/mongo/error/operation_failure_spec.rb +6 -6
- data/spec/mongo/operation/aggregate_spec.rb +1 -1
- data/spec/mongo/operation/collections_info_spec.rb +1 -1
- data/spec/mongo/operation/command_spec.rb +3 -3
- data/spec/mongo/operation/create_index_spec.rb +3 -3
- data/spec/mongo/operation/create_user_spec.rb +3 -3
- data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
- data/spec/mongo/operation/delete_spec.rb +7 -7
- data/spec/mongo/operation/drop_index_spec.rb +2 -2
- data/spec/mongo/operation/find/legacy_spec.rb +1 -1
- data/spec/mongo/operation/get_more_spec.rb +1 -1
- data/spec/mongo/operation/indexes_spec.rb +1 -1
- data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
- data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/insert_spec.rb +12 -12
- data/spec/mongo/operation/map_reduce_spec.rb +2 -2
- data/spec/mongo/operation/remove_user_spec.rb +3 -3
- data/spec/mongo/operation/update/bulk_spec.rb +6 -6
- data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
- data/spec/mongo/operation/update_spec.rb +7 -7
- data/spec/mongo/operation/update_user_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +2 -3
- data/spec/mongo/protocol/delete_spec.rb +9 -8
- data/spec/mongo/protocol/get_more_spec.rb +9 -8
- data/spec/mongo/protocol/insert_spec.rb +9 -8
- data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
- data/spec/mongo/protocol/msg_spec.rb +57 -53
- data/spec/mongo/protocol/query_spec.rb +12 -12
- data/spec/mongo/protocol/registry_spec.rb +1 -1
- data/spec/mongo/protocol/reply_spec.rb +1 -1
- data/spec/mongo/protocol/update_spec.rb +10 -9
- data/spec/mongo/server/connection_pool_spec.rb +1 -1
- data/spec/mongo/server/connection_spec.rb +28 -7
- data/spec/mongo/socket_spec.rb +1 -1
- data/spec/mongo/timeout_spec.rb +85 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
- data/spec/mongo/uri_spec.rb +52 -5
- data/spec/mongo/write_concern_spec.rb +13 -1
- data/spec/{support → runners}/auth.rb +14 -1
- data/spec/{support → runners}/change_streams.rb +1 -1
- data/spec/{support → runners}/change_streams/operation.rb +0 -0
- data/spec/{support → runners}/cmap.rb +1 -1
- data/spec/{support → runners}/cmap/verifier.rb +0 -0
- data/spec/{support → runners}/command_monitoring.rb +0 -0
- data/spec/runners/connection_string.rb +358 -4
- data/spec/{support → runners}/crud.rb +9 -9
- data/spec/{support → runners}/crud/context.rb +0 -0
- data/spec/{support → runners}/crud/operation.rb +7 -3
- data/spec/{support → runners}/crud/outcome.rb +0 -0
- data/spec/{support → runners}/crud/requirement.rb +1 -1
- data/spec/{support → runners}/crud/spec.rb +12 -1
- data/spec/{support → runners}/crud/test.rb +0 -0
- data/spec/{support → runners}/crud/test_base.rb +0 -0
- data/spec/{support → runners}/crud/verifier.rb +10 -12
- data/spec/{support → runners}/gridfs.rb +0 -0
- data/spec/{support → runners}/sdam_monitoring.rb +0 -0
- data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
- data/spec/{support → runners}/server_selection.rb +0 -0
- data/spec/{support → runners}/server_selection_rtt.rb +0 -0
- data/spec/{support → runners}/transactions.rb +4 -4
- data/spec/{support → runners}/transactions/context.rb +0 -0
- data/spec/{support → runners}/transactions/operation.rb +0 -0
- data/spec/{support → runners}/transactions/spec.rb +0 -0
- data/spec/{support → runners}/transactions/test.rb +37 -5
- data/spec/spec_helper.rb +0 -5
- data/spec/spec_tests/auth_spec.rb +3 -3
- data/spec/spec_tests/client_side_encryption_spec.rb +13 -0
- data/spec/spec_tests/connection_string_spec.rb +1 -1
- data/spec/spec_tests/data/auth/connection-string.yml +13 -0
- data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
- data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
- data/spec/spec_tests/data/client_side_encryption/bulk.yml +85 -0
- data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
- data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
- data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
- data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
- data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
- data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
- data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
- data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
- data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
- data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
- data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
- data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
- data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
- data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
- data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
- data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
- data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +61 -0
- data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
- data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
- data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
- data/spec/spec_tests/data/client_side_encryption/updateOne.yml +168 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
- data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
- data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
- data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
- data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
- data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
- data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
- data/spec/spec_tests/data/sdam/rs/{secondary_wrong_set_name_with_primary_second.yml → ruby_secondary_wrong_set_name_with_primary_second.yml} +0 -0
- data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
- data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
- data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
- data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
- data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
- data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
- data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
- data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
- data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
- data/spec/spec_tests/uri_options_spec.rb +6 -8
- data/spec/stress/connection_pool_timing_spec.rb +6 -3
- data/spec/support/certificates/README.md +4 -0
- data/spec/support/certificates/server-second-level-bundle.pem +77 -77
- data/spec/support/certificates/server-second-level.crt +52 -52
- data/spec/support/certificates/server-second-level.key +25 -25
- data/spec/support/certificates/server-second-level.pem +77 -77
- data/spec/support/client_registry.rb +19 -3
- data/spec/support/cluster_config.rb +9 -1
- data/spec/support/common_shortcuts.rb +12 -0
- data/spec/support/constraints.rb +16 -0
- data/spec/support/crypt.rb +140 -0
- data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
- data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
- data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
- data/spec/support/crypt/corpus/corpus.json +3657 -0
- data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
- data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
- data/spec/support/crypt/data_keys/key_document_local.json +31 -0
- data/spec/support/crypt/external/external-key.json +31 -0
- data/spec/support/crypt/external/external-schema.json +19 -0
- data/spec/support/crypt/limits/limits-doc.json +102 -0
- data/spec/support/crypt/limits/limits-key.json +31 -0
- data/spec/support/crypt/limits/limits-schema.json +1405 -0
- data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
- data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/lite_constraints.rb +17 -1
- data/spec/support/matchers.rb +19 -0
- data/spec/support/shared/protocol.rb +2 -0
- data/spec/support/spec_config.rb +43 -13
- data/spec/support/utils.rb +132 -10
- metadata +277 -81
- metadata.gz.sig +0 -0
- data/spec/integration/grid_fs_bucket_spec.rb +0 -48
- data/spec/integration/zlib_compression_spec.rb +0 -25
- data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
- data/spec/support/connection_string.rb +0 -354
@@ -48,6 +48,10 @@ describe Mongo::Auth::X509 do
|
|
48
48
|
|
49
49
|
context 'when the user is not authorized for the database' do
|
50
50
|
|
51
|
+
before do
|
52
|
+
connection.connect!
|
53
|
+
end
|
54
|
+
|
51
55
|
let(:x509) do
|
52
56
|
described_class.new(user)
|
53
57
|
end
|
@@ -56,7 +60,7 @@ describe Mongo::Auth::X509 do
|
|
56
60
|
x509.login(connection).documents[0]
|
57
61
|
end
|
58
62
|
|
59
|
-
it '
|
63
|
+
it 'attempts to log the user into the connection' do
|
60
64
|
expect {
|
61
65
|
x509.login(connection)
|
62
66
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
@@ -167,8 +167,212 @@ describe Mongo::Client do
|
|
167
167
|
end
|
168
168
|
|
169
169
|
describe '#initialize' do
|
170
|
-
|
171
170
|
context 'when providing options' do
|
171
|
+
context 'with auto_encryption_options' do
|
172
|
+
require_libmongocrypt
|
173
|
+
|
174
|
+
include_context 'define shared FLE helpers'
|
175
|
+
|
176
|
+
let(:client) do
|
177
|
+
new_local_client_nmio(
|
178
|
+
SpecConfig.instance.addresses,
|
179
|
+
SpecConfig.instance.test_options.merge(client_opts)
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
let(:client_opts) { { auto_encryption_options: auto_encryption_options } }
|
184
|
+
|
185
|
+
let(:auto_encryption_options) do
|
186
|
+
{
|
187
|
+
key_vault_client: key_vault_client,
|
188
|
+
key_vault_namespace: key_vault_namespace,
|
189
|
+
kms_providers: kms_providers,
|
190
|
+
schema_map: schema_map,
|
191
|
+
bypass_auto_encryption: bypass_auto_encryption,
|
192
|
+
extra_options: extra_options,
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
let(:key_vault_client) { new_local_client_nmio(SpecConfig.instance.addresses) }
|
197
|
+
|
198
|
+
let(:bypass_auto_encryption) { true }
|
199
|
+
|
200
|
+
let(:extra_options) do
|
201
|
+
{
|
202
|
+
mongocryptd_uri: mongocryptd_uri,
|
203
|
+
mongocryptd_bypass_spawn: mongocryptd_bypass_spawn,
|
204
|
+
mongocryptd_spawn_path: mongocryptd_spawn_path,
|
205
|
+
mongocryptd_spawn_args: mongocryptd_spawn_args,
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
let(:mongocryptd_uri) { 'mongodb://localhost:27021' }
|
210
|
+
let(:mongocryptd_bypass_spawn) { true }
|
211
|
+
let(:mongocryptd_spawn_path) { '/spawn/path' }
|
212
|
+
let(:mongocryptd_spawn_args) { ['--idleShutdownTimeoutSecs=100'] }
|
213
|
+
|
214
|
+
shared_examples 'a functioning auto encryption client' do
|
215
|
+
let(:encryption_options) { client.encrypter.options }
|
216
|
+
|
217
|
+
context 'when auto_encrypt_opts are nil' do
|
218
|
+
let(:auto_encryption_options) { nil }
|
219
|
+
|
220
|
+
it 'does not raise an exception' do
|
221
|
+
expect { client }.not_to raise_error
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'when key_vault_namespace is nil' do
|
226
|
+
let(:key_vault_namespace) { nil }
|
227
|
+
|
228
|
+
it 'raises an exception' do
|
229
|
+
expect { client }.to raise_error(ArgumentError, /key_vault_namespace option cannot be nil/)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when key_vault_namespace is incorrectly formatted' do
|
234
|
+
let(:key_vault_namespace) { 'not.good.formatting' }
|
235
|
+
|
236
|
+
it 'raises an exception' do
|
237
|
+
expect { client }.to raise_error(ArgumentError, /key_vault_namespace option must be in the format database.collection/)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'when kms_providers is nil' do
|
242
|
+
let(:kms_providers) { nil }
|
243
|
+
|
244
|
+
it 'raises an exception' do
|
245
|
+
expect { client }.to raise_error(ArgumentError, /kms_providers option must not be nil/)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when kms_providers doesn\'t have local or aws keys' do
|
250
|
+
let(:kms_providers) { { random_key: 'hello' } }
|
251
|
+
|
252
|
+
it 'raises an exception' do
|
253
|
+
expect { client }.to raise_error(ArgumentError, /kms_providers option must have one of the following keys: :aws, :local/)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when local kms_provider is incorrectly formatted' do
|
258
|
+
let(:kms_providers) { { local: { wrong_key: 'hello' } } }
|
259
|
+
|
260
|
+
it 'raises an exception' do
|
261
|
+
expect { client }.to raise_error(ArgumentError, /kms_providers with :local key must be in the format: { local: { key: 'MASTER-KEY' } }/)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context 'when aws kms_provider is incorrectly formatted' do
|
266
|
+
let(:kms_providers) { { aws: { wrong_key: 'hello' } } }
|
267
|
+
|
268
|
+
it 'raises an exception' do
|
269
|
+
expect { client }.to raise_error(ArgumentError, /kms_providers with :aws key must be in the format: { aws: { access_key_id: 'YOUR-ACCESS-KEY-ID', secret_access_key: 'SECRET-ACCESS-KEY' } }/)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context 'with an invalid schema map' do
|
274
|
+
let(:schema_map) { '' }
|
275
|
+
|
276
|
+
it 'raises an exception' do
|
277
|
+
expect { client }.to raise_error(ArgumentError, /schema_map must be a Hash or nil/)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'with valid options' do
|
282
|
+
it 'does not raise an exception' do
|
283
|
+
expect { client }.not_to raise_error
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'with a nil schema_map' do
|
287
|
+
let(:schema_map) { nil }
|
288
|
+
|
289
|
+
it 'does not raise an exception' do
|
290
|
+
expect { client }.not_to raise_error
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'sets options on the client' do
|
295
|
+
expect(encryption_options[:key_vault_client]).to eq(key_vault_client)
|
296
|
+
expect(encryption_options[:key_vault_namespace]).to eq(key_vault_namespace)
|
297
|
+
# Don't explicitly expect kms_providers to avoid accidentally exposing
|
298
|
+
# sensitive data in evergreen logs
|
299
|
+
expect(encryption_options[:kms_providers]).to be_a_kind_of(Hash)
|
300
|
+
expect(encryption_options[:schema_map]).to eq(schema_map)
|
301
|
+
expect(encryption_options[:bypass_auto_encryption]).to eq(bypass_auto_encryption)
|
302
|
+
expect(encryption_options[:extra_options][:mongocryptd_uri]).to eq(mongocryptd_uri)
|
303
|
+
expect(encryption_options[:extra_options][:mongocryptd_bypass_spawn]).to eq(mongocryptd_bypass_spawn)
|
304
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_path]).to eq(mongocryptd_spawn_path)
|
305
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_args]).to eq(mongocryptd_spawn_args)
|
306
|
+
|
307
|
+
expect(client.encrypter.mongocryptd_client.options[:monitoring_io]).to be false
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'with default extra options' do
|
311
|
+
let(:auto_encryption_options) do
|
312
|
+
{
|
313
|
+
key_vault_namespace: key_vault_namespace,
|
314
|
+
kms_providers: kms_providers,
|
315
|
+
schema_map: schema_map,
|
316
|
+
}
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'sets key_vault_client as a clone of self with no encryption options' do
|
320
|
+
key_vault_client = client.encrypter.key_vault_client
|
321
|
+
expect(key_vault_client).to eq(client)
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'sets bypass_auto_encryption to false' do
|
325
|
+
expect(encryption_options[:bypass_auto_encryption]).to be false
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'sets extra options to defaults' do
|
329
|
+
expect(encryption_options[:extra_options][:mongocryptd_uri]).to eq('mongodb://localhost:27020')
|
330
|
+
expect(encryption_options[:extra_options][:mongocryptd_bypass_spawn]).to be false
|
331
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_path]).to eq('mongocryptd')
|
332
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_args]).to eq(['--idleShutdownTimeoutSecs=60'])
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'with mongocryptd_spawn_args that don\'t include idleShutdownTimeoutSecs' do
|
337
|
+
let(:mongocryptd_spawn_args) { ['--otherArgument=true'] }
|
338
|
+
|
339
|
+
it 'adds a default value to mongocryptd_spawn_args' do
|
340
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_args]).to eq(mongocryptd_spawn_args + ['--idleShutdownTimeoutSecs=60'])
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'with mongocryptd_spawn_args that has idleShutdownTimeoutSecs as two arguments' do
|
345
|
+
let(:mongocryptd_spawn_args) { ['--idleShutdownTimeoutSecs', 100] }
|
346
|
+
|
347
|
+
it 'does not modify mongocryptd_spawn_args' do
|
348
|
+
expect(encryption_options[:extra_options][:mongocryptd_spawn_args]).to eq(mongocryptd_spawn_args)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'with default key_vault_client' do
|
353
|
+
let(:key_vault_client) { nil }
|
354
|
+
|
355
|
+
it 'creates a key_vault_client' do
|
356
|
+
key_vault_client = encryption_options[:key_vault_client]
|
357
|
+
|
358
|
+
expect(key_vault_client).to be_a_kind_of(Mongo::Client)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context 'with AWS KMS providers' do
|
365
|
+
include_context 'with AWS kms_providers' do
|
366
|
+
it_behaves_like 'a functioning auto encryption client'
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context 'with local KMS providers' do
|
371
|
+
include_context 'with local kms_providers' do
|
372
|
+
it_behaves_like 'a functioning auto encryption client'
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
172
376
|
|
173
377
|
context 'retry_writes option' do
|
174
378
|
let(:client) do
|
@@ -235,8 +439,7 @@ describe Mongo::Client do
|
|
235
439
|
min_server_fcv '3.6'
|
236
440
|
|
237
441
|
it 'uses compression for messages' do
|
238
|
-
|
239
|
-
expect(Mongo::Protocol::Compressed).to receive(:new).twice.and_call_original
|
442
|
+
expect(Mongo::Protocol::Compressed).to receive(:new).at_least(:once).and_call_original
|
240
443
|
client[TEST_COLL].find({}, limit: 1).first
|
241
444
|
end
|
242
445
|
end
|
@@ -0,0 +1,408 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'base64'
|
3
|
+
require 'lite_spec_helper'
|
4
|
+
|
5
|
+
describe Mongo::ClientEncryption do
|
6
|
+
require_libmongocrypt
|
7
|
+
include_context 'define shared FLE helpers'
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
ClientRegistry.instance.new_local_client(
|
11
|
+
[SpecConfig.instance.addresses.first]
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:client_encryption) do
|
16
|
+
described_class.new(client, {
|
17
|
+
key_vault_namespace: key_vault_namespace,
|
18
|
+
kms_providers: kms_providers
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#initialize' do
|
23
|
+
shared_examples 'a functioning ClientEncryption' do
|
24
|
+
context 'with nil key_vault_namespace' do
|
25
|
+
let(:key_vault_namespace) { nil }
|
26
|
+
|
27
|
+
it 'raises an exception' do
|
28
|
+
expect do
|
29
|
+
client_encryption
|
30
|
+
end.to raise_error(ArgumentError, /:key_vault_namespace option cannot be nil/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with invalid key_vault_namespace' do
|
35
|
+
let(:key_vault_namespace) { 'three.word.namespace' }
|
36
|
+
|
37
|
+
it 'raises an exception' do
|
38
|
+
expect do
|
39
|
+
client_encryption
|
40
|
+
end.to raise_error(ArgumentError, /invalid key vault namespace/)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with valid options' do
|
45
|
+
it 'creates a ClientEncryption object' do
|
46
|
+
expect do
|
47
|
+
client_encryption
|
48
|
+
end.not_to raise_error
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with local KMS providers' do
|
54
|
+
include_context 'with local kms_providers'
|
55
|
+
it_behaves_like 'a functioning ClientEncryption'
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with AWS KMS providers' do
|
59
|
+
include_context 'with AWS kms_providers'
|
60
|
+
it_behaves_like 'a functioning ClientEncryption'
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with invalid KMS provider information' do
|
64
|
+
let(:kms_providers) { { random_key: {} } }
|
65
|
+
|
66
|
+
it 'raises an exception' do
|
67
|
+
expect do
|
68
|
+
client_encryption
|
69
|
+
end.to raise_error(ArgumentError, /kms_providers option must have one of the following keys/)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#create_data_key' do
|
75
|
+
let(:data_key_id) { client_encryption.create_data_key(kms_provider_name, options) }
|
76
|
+
let(:key_alt_names) { nil }
|
77
|
+
|
78
|
+
shared_examples 'it creates a data key' do |with_key_alt_names: false|
|
79
|
+
it 'returns the data key id and inserts it into the key vault collection' do
|
80
|
+
expect(data_key_id).to be_uuid
|
81
|
+
|
82
|
+
documents = client.use(key_vault_db)[key_vault_coll].find(_id: data_key_id)
|
83
|
+
|
84
|
+
expect(documents.count).to eq(1)
|
85
|
+
|
86
|
+
if with_key_alt_names
|
87
|
+
expect(documents.first['keyAltNames']).to match_array(key_alt_names)
|
88
|
+
else
|
89
|
+
expect(documents.first['keyAltNames']).to be_nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
shared_examples 'it supports key_alt_names' do
|
95
|
+
let(:options) { base_options.merge(key_alt_names: key_alt_names) }
|
96
|
+
|
97
|
+
context 'with one value in key_alt_names' do
|
98
|
+
let(:key_alt_names) { ['keyAltName1'] }
|
99
|
+
it_behaves_like 'it creates a data key', **{ with_key_alt_names: true }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with multiple values in key_alt_names' do
|
103
|
+
let(:key_alt_names) { ['keyAltName1', 'keyAltName2'] }
|
104
|
+
it_behaves_like 'it creates a data key', **{ with_key_alt_names: true }
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with empty key_alt_names' do
|
108
|
+
let(:key_alt_names) { [] }
|
109
|
+
it_behaves_like 'it creates a data key'
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'with invalid key_alt_names option' do
|
113
|
+
let(:key_alt_names) { 'keyAltName1' }
|
114
|
+
|
115
|
+
it 'raises an exception' do
|
116
|
+
expect do
|
117
|
+
data_key_id
|
118
|
+
end.to raise_error(ArgumentError, /key_alt_names option must be an Array/)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'with invalid key_alt_names values' do
|
123
|
+
let(:key_alt_names) { ['keyAltNames1', 3] }
|
124
|
+
|
125
|
+
it 'raises an exception' do
|
126
|
+
expect do
|
127
|
+
data_key_id
|
128
|
+
end.to raise_error(ArgumentError, /values of the :key_alt_names option Array must be Strings/)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'with AWS KMS provider' do
|
134
|
+
include_context 'with AWS kms_providers'
|
135
|
+
|
136
|
+
let(:base_options) { { master_key: { region: aws_region, key: aws_arn } } }
|
137
|
+
it_behaves_like 'it supports key_alt_names'
|
138
|
+
|
139
|
+
context 'with nil options' do
|
140
|
+
let(:options) { nil }
|
141
|
+
|
142
|
+
it 'raises an exception' do
|
143
|
+
expect do
|
144
|
+
data_key_id
|
145
|
+
end.to raise_error(ArgumentError, /options cannot be nil/)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'with empty options' do
|
150
|
+
let(:options) { {} }
|
151
|
+
|
152
|
+
it 'raises an exception' do
|
153
|
+
expect do
|
154
|
+
data_key_id
|
155
|
+
end.to raise_error(ArgumentError, /options Hash must contain a key named :master_key/)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'with nil master key' do
|
160
|
+
let(:options) { { master_key: nil } }
|
161
|
+
|
162
|
+
it 'raises an exception' do
|
163
|
+
expect do
|
164
|
+
data_key_id
|
165
|
+
end.to raise_error(ArgumentError, /The :master_key option cannot be nil/)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'with invalid master key' do
|
170
|
+
let(:options) { { master_key: 'master-key' } }
|
171
|
+
|
172
|
+
it 'raises an exception' do
|
173
|
+
expect do
|
174
|
+
data_key_id
|
175
|
+
end.to raise_error(ArgumentError, /master-key is an invalid :master_key option/)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'with empty master key' do
|
180
|
+
let(:options) { { master_key: {} } }
|
181
|
+
|
182
|
+
it 'raises an exception' do
|
183
|
+
expect do
|
184
|
+
data_key_id
|
185
|
+
end.to raise_error(ArgumentError, /The value of :region option of the :master_key options hash cannot be nil/)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'with nil region' do
|
190
|
+
let(:options) { { master_key: { region: nil, key: aws_arn } } }
|
191
|
+
|
192
|
+
it 'raises an exception' do
|
193
|
+
expect do
|
194
|
+
data_key_id
|
195
|
+
end.to raise_error(ArgumentError, /The value of :region option of the :master_key options hash cannot be nil/)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'with invalid region' do
|
200
|
+
let(:options) { { master_key: { region: 5, key: aws_arn } } }
|
201
|
+
|
202
|
+
it 'raises an exception' do
|
203
|
+
expect do
|
204
|
+
data_key_id
|
205
|
+
end.to raise_error(ArgumentError, /5 is an invalid AWS master_key region. The value of :region option of the :master_key options hash must be a String/)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'with nil key' do
|
210
|
+
let(:options) { { master_key: { key: nil, region: aws_region } } }
|
211
|
+
|
212
|
+
it 'raises an exception' do
|
213
|
+
expect do
|
214
|
+
data_key_id
|
215
|
+
end.to raise_error(ArgumentError, /The value of :key option of the :master_key options hash cannot be nil/)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'with invalid key' do
|
220
|
+
let(:options) { { master_key: { key: 5, region: aws_region } } }
|
221
|
+
|
222
|
+
it 'raises an exception' do
|
223
|
+
expect do
|
224
|
+
data_key_id
|
225
|
+
end.to raise_error(ArgumentError, /5 is an invalid AWS master_key key. The value of :key option of the :master_key options hash must be a String/)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'with invalid endpoint' do
|
230
|
+
let(:options) { { master_key: { key: aws_arn, region: aws_region, endpoint: 5 } } }
|
231
|
+
|
232
|
+
it 'raises an exception' do
|
233
|
+
expect do
|
234
|
+
data_key_id
|
235
|
+
end.to raise_error(ArgumentError, /5 is an invalid AWS master_key endpoint. The value of :endpoint option of the :master_key options hash must be a String/)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'with nil endpoint' do
|
240
|
+
let(:options) do
|
241
|
+
{
|
242
|
+
master_key: {
|
243
|
+
key: aws_arn,
|
244
|
+
region: aws_region,
|
245
|
+
endpoint: nil
|
246
|
+
}
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
it_behaves_like 'it creates a data key'
|
251
|
+
end
|
252
|
+
|
253
|
+
context 'with valid endpoint, no port' do
|
254
|
+
let(:options) do
|
255
|
+
{
|
256
|
+
master_key: {
|
257
|
+
key: aws_arn,
|
258
|
+
region: aws_region,
|
259
|
+
endpoint: aws_endpoint_host
|
260
|
+
}
|
261
|
+
}
|
262
|
+
end
|
263
|
+
|
264
|
+
it_behaves_like 'it creates a data key'
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'with valid endpoint' do
|
268
|
+
let(:options) { data_key_options }
|
269
|
+
it_behaves_like 'it creates a data key'
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'with invalid endpoint' do
|
273
|
+
let(:options) do
|
274
|
+
{
|
275
|
+
master_key: {
|
276
|
+
key: aws_arn,
|
277
|
+
region: aws_region,
|
278
|
+
endpoint: "https://#{aws_endpoint_host}:#{aws_endpoint_port}"
|
279
|
+
}
|
280
|
+
}
|
281
|
+
end
|
282
|
+
|
283
|
+
let(:expected_message) do
|
284
|
+
# RUBY-2129: This error message could be more specific and inform the user
|
285
|
+
# that there is a problem with their KMS endpoint
|
286
|
+
if BSON::Environment.jruby?
|
287
|
+
/getservbyname.* failed/
|
288
|
+
else
|
289
|
+
/SocketError/
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'raises an exception' do
|
294
|
+
expect do
|
295
|
+
data_key_id
|
296
|
+
end.to raise_error(Mongo::Error::KmsError, expected_message)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'when socket connect errors out' do
|
301
|
+
let(:options) { data_key_options }
|
302
|
+
|
303
|
+
before do
|
304
|
+
allow_any_instance_of(OpenSSL::SSL::SSLSocket)
|
305
|
+
.to receive(:connect)
|
306
|
+
.and_raise('Error while connecting to socket')
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'raises a KmsError' do
|
310
|
+
expect do
|
311
|
+
data_key_id
|
312
|
+
end.to raise_error(Mongo::Error::KmsError, /Error while connecting to socket/)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'when socket connect errors out' do
|
317
|
+
let(:options) { data_key_options }
|
318
|
+
|
319
|
+
before do
|
320
|
+
allow_any_instance_of(OpenSSL::SSL::SSLSocket)
|
321
|
+
.to receive(:sysclose)
|
322
|
+
.and_raise('Error while closing socket')
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'does not raise an exception' do
|
326
|
+
expect do
|
327
|
+
data_key_id
|
328
|
+
end.not_to raise_error
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context 'with local KMS provider' do
|
334
|
+
include_context 'with local kms_providers'
|
335
|
+
let(:options) { {} }
|
336
|
+
let(:base_options) { {} }
|
337
|
+
|
338
|
+
it_behaves_like 'it supports key_alt_names'
|
339
|
+
it_behaves_like 'it creates a data key'
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
describe '#encrypt/decrypt' do
|
344
|
+
let(:value) { ssn }
|
345
|
+
let(:encrypted_value) { encrypted_ssn }
|
346
|
+
|
347
|
+
before do
|
348
|
+
key_vault_collection = client.use(key_vault_db)[key_vault_coll]
|
349
|
+
key_vault_collection.drop
|
350
|
+
|
351
|
+
key_vault_collection.insert_one(data_key)
|
352
|
+
end
|
353
|
+
|
354
|
+
shared_examples 'an encrypter' do
|
355
|
+
let(:encrypted) do
|
356
|
+
client_encryption.encrypt(
|
357
|
+
value,
|
358
|
+
{
|
359
|
+
key_id: key_id,
|
360
|
+
key_alt_name: key_alt_name,
|
361
|
+
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
|
362
|
+
}
|
363
|
+
)
|
364
|
+
end
|
365
|
+
|
366
|
+
context 'with key_id option' do
|
367
|
+
let(:key_alt_name) { nil }
|
368
|
+
|
369
|
+
it 'correctly encrypts a string' do
|
370
|
+
expect(encrypted).to be_ciphertext
|
371
|
+
expect(encrypted.data).to eq(Base64.decode64(encrypted_value))
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'with key_alt_name option' do
|
376
|
+
let(:key_id) { nil }
|
377
|
+
|
378
|
+
it 'correctly encrypts a string' do
|
379
|
+
expect(encrypted).to be_ciphertext
|
380
|
+
expect(encrypted.data).to eq(Base64.decode64(encrypted_value))
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
shared_examples 'a decrypter' do
|
386
|
+
it 'correctly decrypts a string' do
|
387
|
+
encrypted = BSON::Binary.new(Base64.decode64(encrypted_value), :ciphertext)
|
388
|
+
|
389
|
+
result = client_encryption.decrypt(encrypted)
|
390
|
+
expect(result).to eq(value)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'with local KMS providers' do
|
395
|
+
include_context 'with local kms_providers'
|
396
|
+
|
397
|
+
it_behaves_like 'an encrypter'
|
398
|
+
it_behaves_like 'a decrypter'
|
399
|
+
end
|
400
|
+
|
401
|
+
context 'with AWS KMS providers' do
|
402
|
+
include_context 'with AWS kms_providers'
|
403
|
+
|
404
|
+
it_behaves_like 'an encrypter'
|
405
|
+
it_behaves_like 'a decrypter'
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|