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
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (C) 2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'securerandom'
|
16
|
+
require 'digest'
|
17
|
+
|
18
|
+
module Mongo
|
19
|
+
module Crypt
|
20
|
+
|
21
|
+
# A helper module that implements cryptography methods required
|
22
|
+
# for native Ruby crypto hooks. These methods are passed into FFI
|
23
|
+
# as C callbacks and called from the libmongocrypt library.
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
module Hooks
|
27
|
+
|
28
|
+
# An AES encrypt or decrypt method.
|
29
|
+
#
|
30
|
+
# @param [ String ] key The 32-byte AES encryption key
|
31
|
+
# @param [ String ] iv The 16-byte AES IV
|
32
|
+
# @param [ String ] input The data to be encrypted/decrypted
|
33
|
+
# @param [ true | false ] decrypt Whether this method is decrypting. Default is
|
34
|
+
# false, which means the method will create an encryption cipher by default
|
35
|
+
#
|
36
|
+
# @return [ String ] Output
|
37
|
+
# @raise [ Exception ] Exceptions raised during encryption are propagated
|
38
|
+
# to caller.
|
39
|
+
def aes(key, iv, input, decrypt: false)
|
40
|
+
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
|
41
|
+
|
42
|
+
decrypt ? cipher.decrypt : cipher.encrypt
|
43
|
+
cipher.key = key
|
44
|
+
cipher.iv = iv
|
45
|
+
cipher.padding = 0
|
46
|
+
|
47
|
+
encrypted = cipher.update(input)
|
48
|
+
end
|
49
|
+
module_function :aes
|
50
|
+
|
51
|
+
# Crypto secure random function
|
52
|
+
#
|
53
|
+
# @param [ Integer ] num_bytes The number of random bytes requested
|
54
|
+
#
|
55
|
+
# @return [ String ]
|
56
|
+
# @raise [ Exception ] Exceptions raised during encryption are propagated
|
57
|
+
# to caller.
|
58
|
+
def random(num_bytes)
|
59
|
+
SecureRandom.random_bytes(num_bytes)
|
60
|
+
end
|
61
|
+
module_function :random
|
62
|
+
|
63
|
+
# An HMAC SHA-512 or SHA-256 function
|
64
|
+
#
|
65
|
+
# @param [ String ] The name of the digest, either "SHA256" or "SHA512"
|
66
|
+
# @param [ String ] key The 32-byte AES encryption key
|
67
|
+
# @param [ String ] input The data to be tagged
|
68
|
+
#
|
69
|
+
# @return [ String ]
|
70
|
+
# @raise [ Exception ] Exceptions raised during encryption are propagated
|
71
|
+
# to caller.
|
72
|
+
def hmac_sha(digest_name, key, input)
|
73
|
+
OpenSSL::HMAC.digest(digest_name, key, input)
|
74
|
+
end
|
75
|
+
module_function :hmac_sha
|
76
|
+
|
77
|
+
# A crypto hash (SHA-256) function
|
78
|
+
#
|
79
|
+
# @param [ String ] input The data to be hashed
|
80
|
+
#
|
81
|
+
# @return [ String ]
|
82
|
+
# @raise [ Exception ] Exceptions raised during encryption are propagated
|
83
|
+
# to caller.
|
84
|
+
def hash_sha256(input)
|
85
|
+
Digest::SHA2.new(256).digest(input)
|
86
|
+
end
|
87
|
+
module_function :hash_sha256
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Copyright (C) 2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
module Crypt
|
17
|
+
|
18
|
+
# Wraps a libmongocrypt mongocrypt_kms_ctx_t object. Contains information
|
19
|
+
# about making an HTTP request to fetch information about a KMS
|
20
|
+
# data key.
|
21
|
+
class KmsContext
|
22
|
+
# Create a new KmsContext object.
|
23
|
+
#
|
24
|
+
# @param [ FFI::Pointer ] kms_ctx A pointer to a mongocrypt_kms_ctx_t
|
25
|
+
# object. This object is managed by the mongocrypt_ctx_t object that
|
26
|
+
# created it; this class is not responsible for de-allocating resources.
|
27
|
+
def initialize(kms_ctx)
|
28
|
+
@kms_ctx_p = kms_ctx
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return the pointer to the underlying mongocrypt_kms_ctx_t object.
|
32
|
+
#
|
33
|
+
# @return [ FFI::Pointer ] A pointer to a mongocrypt_kms_ctx_t object.
|
34
|
+
attr_reader :kms_ctx_p
|
35
|
+
|
36
|
+
# Return the endpoint at which to make the HTTP request.
|
37
|
+
#
|
38
|
+
# @return [ String ] The endpoint.
|
39
|
+
def endpoint
|
40
|
+
Binding.kms_ctx_endpoint(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return the HTTP message to send to fetch information about the relevant
|
44
|
+
# KMS data key.
|
45
|
+
#
|
46
|
+
# @return [ String ] The HTTP message.
|
47
|
+
def message
|
48
|
+
Binding.kms_ctx_message(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return the number of bytes still needed by libmongocrypt to complete
|
52
|
+
# the request for information about the AWS data key.
|
53
|
+
#
|
54
|
+
# @return [ Integer ] The number of bytes needed.
|
55
|
+
def bytes_needed
|
56
|
+
Binding.kms_ctx_bytes_needed(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Feed a response from the HTTP request to libmongocrypt.
|
60
|
+
#
|
61
|
+
# @param [ String ] data Data to feed to libmongocrypt.
|
62
|
+
def feed(data)
|
63
|
+
Binding.kms_ctx_feed(self, data)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
## Copyright (C) 2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'ffi'
|
16
|
+
|
17
|
+
module Mongo
|
18
|
+
module Crypt
|
19
|
+
|
20
|
+
# A wrapper around mongocrypt_status_t, representing the status of
|
21
|
+
# a mongocrypt_t handle.
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
class Status
|
25
|
+
# Create a new Status object
|
26
|
+
#
|
27
|
+
# @param [ FFI::Pointer | nil ] pointer A pointer to an existing
|
28
|
+
# mongocrypt_status_t object. Defaults to nil.
|
29
|
+
#
|
30
|
+
# @note When initializing a Status object with a pointer, it is
|
31
|
+
# recommended that you use the #self.from_pointer method
|
32
|
+
def initialize(pointer: nil)
|
33
|
+
# If a pointer is passed in, this class is not responsible for
|
34
|
+
# destroying that pointer and deallocating data.
|
35
|
+
#
|
36
|
+
# FFI::AutoPointer uses a custom release strategy to automatically free
|
37
|
+
# the pointer once this object goes out of scope
|
38
|
+
@status = pointer || FFI::AutoPointer.new(
|
39
|
+
Binding.mongocrypt_status_new,
|
40
|
+
Binding.method(:mongocrypt_status_destroy)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initialize a Status object from an existing pointer to a
|
45
|
+
# mongocrypt_status_t object.
|
46
|
+
#
|
47
|
+
# @param [ FFI::Pointer ] pointer A pointer to an existing
|
48
|
+
# mongocrypt_status_t object
|
49
|
+
#
|
50
|
+
# @return [ Mongo::Crypt::Status ] A new Status object
|
51
|
+
def self.from_pointer(pointer)
|
52
|
+
self.new(pointer: pointer)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set a label, code, and message on the Status
|
56
|
+
#
|
57
|
+
# @param [ Symbol ] label One of :ok, :error_client, or :error_kms
|
58
|
+
# @param [ Integer ] code
|
59
|
+
# @param [ String ] message
|
60
|
+
#
|
61
|
+
# @return [ Mongo::Crypt::Status ] returns self
|
62
|
+
def update(label, code, message)
|
63
|
+
unless [:ok, :error_client, :error_kms].include?(label)
|
64
|
+
raise ArgumentError.new(
|
65
|
+
"#{label} is an invalid value for a Mongo::Crypt::Status label. " +
|
66
|
+
"Label must have one of the following values: :ok, :error_client, :error_kms"
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
message_length = message ? message.bytesize + 1 : 0
|
71
|
+
Binding.mongocrypt_status_set(@status, label, code, message, message_length)
|
72
|
+
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return the label of the status
|
77
|
+
#
|
78
|
+
# @return [ Symbol ] The status label, either :ok, :error_kms, or :error_client,
|
79
|
+
# defaults to :ok
|
80
|
+
def label
|
81
|
+
Binding.mongocrypt_status_type(@status)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Return the integer code associated with the status
|
85
|
+
#
|
86
|
+
# @return [ Integer ] The status code, defaults to 0
|
87
|
+
def code
|
88
|
+
Binding.mongocrypt_status_code(@status)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Return the status message
|
92
|
+
#
|
93
|
+
# @return [ String ] The status message, defaults to empty string
|
94
|
+
def message
|
95
|
+
message = Binding.mongocrypt_status_message(@status, nil)
|
96
|
+
message || ''
|
97
|
+
end
|
98
|
+
|
99
|
+
# Checks whether the status is labeled :ok
|
100
|
+
#
|
101
|
+
# @return [ Boolean ] Whether the status is :ok
|
102
|
+
def ok?
|
103
|
+
Binding.mongocrypt_status_ok(@status)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns the reference to the underlying mongocrypt_status_t
|
107
|
+
# object
|
108
|
+
#
|
109
|
+
# @return [ FFI::Pointer ] Pointer to the underlying mongocrypt_status_t oject
|
110
|
+
def ref
|
111
|
+
@status
|
112
|
+
end
|
113
|
+
|
114
|
+
# Raises a Mongo::Error:CryptError corresponding to the
|
115
|
+
# information stored in this status
|
116
|
+
#
|
117
|
+
# Does nothing if self.ok? is true
|
118
|
+
def raise_crypt_error
|
119
|
+
return if ok?
|
120
|
+
|
121
|
+
if label == :error_kms
|
122
|
+
error = Error::KmsError.new(message, code: code)
|
123
|
+
else
|
124
|
+
error = Error::CryptError.new(message, code: code)
|
125
|
+
end
|
126
|
+
|
127
|
+
raise error
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -19,8 +19,9 @@ module Mongo
|
|
19
19
|
# Client-side representation of an iterator over a query result set on
|
20
20
|
# the server.
|
21
21
|
#
|
22
|
-
#
|
23
|
-
#
|
22
|
+
# +Cursor+ objects are not directly exposed to application code. Rather,
|
23
|
+
# +Collection::View+ exposes the +Enumerable+ interface to the applications,
|
24
|
+
# and the enumerator is backed by a +Cursor+ instance.
|
24
25
|
#
|
25
26
|
# @example Get an array of 5 users named Emily.
|
26
27
|
# users.find({:name => 'Emily'}).limit(5).to_a
|
@@ -28,8 +29,7 @@ module Mongo
|
|
28
29
|
# @example Call a block on each user doc.
|
29
30
|
# users.find.each { |doc| puts doc }
|
30
31
|
#
|
31
|
-
# @
|
32
|
-
# @api semipublic
|
32
|
+
# @api private
|
33
33
|
class Cursor
|
34
34
|
extend Forwardable
|
35
35
|
include Enumerable
|
@@ -71,11 +71,14 @@ module Mongo
|
|
71
71
|
@initial_result = result
|
72
72
|
@remaining = limit if limited?
|
73
73
|
@cursor_id = result.cursor_id
|
74
|
+
if @cursor_id.nil?
|
75
|
+
raise ArgumentError, 'Cursor id must be present in the result'
|
76
|
+
end
|
74
77
|
@coll_name = nil
|
75
78
|
@options = options
|
76
79
|
@session = @options[:session]
|
77
|
-
|
78
|
-
|
80
|
+
unless closed?
|
81
|
+
register
|
79
82
|
ObjectSpace.define_finalizer(self, self.class.finalize(@cursor_id,
|
80
83
|
cluster,
|
81
84
|
kill_cursors_op_spec,
|
@@ -122,6 +125,10 @@ module Mongo
|
|
122
125
|
|
123
126
|
# Iterate through documents returned from the query.
|
124
127
|
#
|
128
|
+
# A cursor may be iterated at most once. Incomplete iteration is also
|
129
|
+
# allowed. Attempting to iterate the cursor more than once raises
|
130
|
+
# InvalidCursorOperation.
|
131
|
+
#
|
125
132
|
# @example Iterate over the documents in the cursor.
|
126
133
|
# cursor.each do |doc|
|
127
134
|
# ...
|
@@ -142,19 +149,29 @@ module Mongo
|
|
142
149
|
# end of previous iteration or would always restart from the
|
143
150
|
# beginning.
|
144
151
|
if @get_more_called
|
145
|
-
raise
|
152
|
+
raise Error::InvalidCursorOperation, 'Cannot restart iteration of a cursor which issued a getMore'
|
146
153
|
end
|
147
154
|
|
148
155
|
# To maintain compatibility with pre-2.10 driver versions, reset
|
149
156
|
# the documents array each time a new iteration is started.
|
150
157
|
@documents = nil
|
151
158
|
|
152
|
-
|
153
|
-
|
154
|
-
|
159
|
+
if block_given?
|
160
|
+
# StopIteration raised by try_next ends this loop.
|
161
|
+
loop do
|
162
|
+
document = try_next
|
163
|
+
yield document if document
|
164
|
+
end
|
165
|
+
self
|
166
|
+
else
|
167
|
+
documents = []
|
168
|
+
# StopIteration raised by try_next ends this loop.
|
169
|
+
loop do
|
170
|
+
document = try_next
|
171
|
+
documents << document if document
|
172
|
+
end
|
173
|
+
documents
|
155
174
|
end
|
156
|
-
rescue StopIteration => e
|
157
|
-
return self
|
158
175
|
end
|
159
176
|
|
160
177
|
# Return one document from the query, if one is available.
|
@@ -168,6 +185,10 @@ module Mongo
|
|
168
185
|
# @note This method is experimental and subject to change.
|
169
186
|
#
|
170
187
|
# @return [ BSON::Document | nil ] A document.
|
188
|
+
#
|
189
|
+
# @raise [ StopIteration ] Raised on the calls after the cursor had been
|
190
|
+
# completely iterated.
|
191
|
+
#
|
171
192
|
# @api private
|
172
193
|
def try_next
|
173
194
|
if @documents.nil?
|
@@ -184,9 +205,9 @@ module Mongo
|
|
184
205
|
# On empty batches, we cache the batch resume token
|
185
206
|
cache_batch_resume_token
|
186
207
|
|
187
|
-
|
208
|
+
unless closed?
|
188
209
|
if exhausted?
|
189
|
-
|
210
|
+
close
|
190
211
|
raise StopIteration
|
191
212
|
end
|
192
213
|
@documents = get_more
|
@@ -233,7 +254,28 @@ module Mongo
|
|
233
254
|
#
|
234
255
|
# @since 2.2.0
|
235
256
|
def closed?
|
236
|
-
|
257
|
+
# @cursor_id should in principle never be nil
|
258
|
+
@cursor_id.nil? || @cursor_id == 0
|
259
|
+
end
|
260
|
+
|
261
|
+
# Closes this cursor, freeing any associated resources on the client and
|
262
|
+
# the server.
|
263
|
+
#
|
264
|
+
# @return [ nil ] Always nil.
|
265
|
+
#
|
266
|
+
# @raise [ Error::OperationFailure ] If the server cursor close fails.
|
267
|
+
def close
|
268
|
+
return if closed?
|
269
|
+
|
270
|
+
unregister
|
271
|
+
read_with_one_retry do
|
272
|
+
kill_cursors_operation.execute(@server, client: client)
|
273
|
+
end
|
274
|
+
|
275
|
+
nil
|
276
|
+
ensure
|
277
|
+
end_session
|
278
|
+
@cursor_id = 0
|
237
279
|
end
|
238
280
|
|
239
281
|
# Get the parsed collection name.
|
@@ -289,7 +331,7 @@ module Mongo
|
|
289
331
|
# doing so may result in silent data loss, the driver no longer retries
|
290
332
|
# getMore operations in any circumstance.
|
291
333
|
# https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#qa
|
292
|
-
process(get_more_operation.execute(@server))
|
334
|
+
process(get_more_operation.execute(@server, client: client))
|
293
335
|
end
|
294
336
|
|
295
337
|
private
|
@@ -317,16 +359,6 @@ module Mongo
|
|
317
359
|
Operation::GetMore.new(spec)
|
318
360
|
end
|
319
361
|
|
320
|
-
def kill_cursors
|
321
|
-
unregister
|
322
|
-
read_with_one_retry do
|
323
|
-
kill_cursors_operation.execute(@server)
|
324
|
-
end
|
325
|
-
ensure
|
326
|
-
end_session
|
327
|
-
@cursor_id = 0
|
328
|
-
end
|
329
|
-
|
330
362
|
def end_session
|
331
363
|
@session.end_session if @session && @session.implicit?
|
332
364
|
end
|
@@ -347,21 +379,21 @@ module Mongo
|
|
347
379
|
limit ? limit > 0 : false
|
348
380
|
end
|
349
381
|
|
350
|
-
def more?
|
351
|
-
@cursor_id != 0
|
352
|
-
end
|
353
|
-
|
354
382
|
def process(result)
|
355
383
|
@remaining -= result.returned_count if limited?
|
356
384
|
@coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
|
357
|
-
|
385
|
+
# #process is called for the first batch of results. In this case
|
386
|
+
# the @cursor_id may be zero (all results fit in the first batch).
|
387
|
+
# Thus we need to check both @cursor_id and the cursor_id of the result
|
388
|
+
# prior to calling unregister here.
|
389
|
+
unregister if !closed? && result.cursor_id == 0
|
358
390
|
@cursor_id = result.cursor_id
|
359
391
|
|
360
392
|
if result.respond_to?(:post_batch_resume_token)
|
361
393
|
@post_batch_resume_token = result.post_batch_resume_token
|
362
394
|
end
|
363
395
|
|
364
|
-
end_session if
|
396
|
+
end_session if closed?
|
365
397
|
|
366
398
|
# Since our iteration code mutates the documents array by calling #shift
|
367
399
|
# on it, duplicate the documents here to permit restarting iteration
|