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.
Files changed (327) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -2
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/lib/mongo.rb +3 -0
  6. data/lib/mongo/address.rb +13 -2
  7. data/lib/mongo/auth.rb +1 -0
  8. data/lib/mongo/auth/credential_cache.rb +51 -0
  9. data/lib/mongo/auth/scram/conversation.rb +20 -16
  10. data/lib/mongo/auth/user.rb +0 -8
  11. data/lib/mongo/auth/user/view.rb +4 -4
  12. data/lib/mongo/background_thread.rb +1 -1
  13. data/lib/mongo/bulk_write.rb +5 -5
  14. data/lib/mongo/client.rb +126 -11
  15. data/lib/mongo/client_encryption.rb +103 -0
  16. data/lib/mongo/cluster.rb +2 -2
  17. data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
  18. data/lib/mongo/cluster/sdam_flow.rb +54 -58
  19. data/lib/mongo/cluster/srv_monitor.rb +1 -1
  20. data/lib/mongo/collection.rb +3 -3
  21. data/lib/mongo/collection/view.rb +1 -1
  22. data/lib/mongo/collection/view/aggregation.rb +1 -1
  23. data/lib/mongo/collection/view/change_stream.rb +12 -3
  24. data/lib/mongo/collection/view/iterable.rb +14 -5
  25. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  26. data/lib/mongo/collection/view/readable.rb +7 -9
  27. data/lib/mongo/collection/view/writable.rb +7 -7
  28. data/lib/mongo/crypt.rb +33 -0
  29. data/lib/mongo/crypt/auto_decryption_context.rb +42 -0
  30. data/lib/mongo/crypt/auto_encrypter.rb +169 -0
  31. data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
  32. data/lib/mongo/crypt/binary.rb +155 -0
  33. data/lib/mongo/crypt/binding.rb +1162 -0
  34. data/lib/mongo/crypt/context.rb +135 -0
  35. data/lib/mongo/crypt/data_key_context.rb +162 -0
  36. data/lib/mongo/crypt/encryption_io.rb +283 -0
  37. data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
  38. data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
  39. data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
  40. data/lib/mongo/crypt/handle.rb +293 -0
  41. data/lib/mongo/crypt/hooks.rb +90 -0
  42. data/lib/mongo/crypt/kms_context.rb +67 -0
  43. data/lib/mongo/crypt/status.rb +131 -0
  44. data/lib/mongo/cursor.rb +64 -32
  45. data/lib/mongo/database.rb +13 -6
  46. data/lib/mongo/database/view.rb +13 -4
  47. data/lib/mongo/dbref.rb +9 -2
  48. data/lib/mongo/error.rb +5 -1
  49. data/lib/mongo/error/crypt_error.rb +31 -0
  50. data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
  51. data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
  52. data/lib/mongo/error/kms_error.rb +22 -0
  53. data/lib/mongo/error/max_bson_size.rb +14 -3
  54. data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
  55. data/lib/mongo/error/no_server_available.rb +8 -3
  56. data/lib/mongo/error/operation_failure.rb +1 -0
  57. data/lib/mongo/grid/file.rb +0 -5
  58. data/lib/mongo/grid/file/chunk.rb +0 -2
  59. data/lib/mongo/grid/file/info.rb +2 -1
  60. data/lib/mongo/grid/fs_bucket.rb +13 -15
  61. data/lib/mongo/grid/stream/write.rb +3 -9
  62. data/lib/mongo/index/view.rb +3 -3
  63. data/lib/mongo/monitoring/event/command_started.rb +6 -1
  64. data/lib/mongo/operation/collections_info.rb +6 -3
  65. data/lib/mongo/operation/delete/op_msg.rb +1 -1
  66. data/lib/mongo/operation/find/op_msg.rb +4 -1
  67. data/lib/mongo/operation/get_more/op_msg.rb +4 -1
  68. data/lib/mongo/operation/insert/command.rb +2 -2
  69. data/lib/mongo/operation/insert/legacy.rb +2 -2
  70. data/lib/mongo/operation/insert/op_msg.rb +3 -3
  71. data/lib/mongo/operation/result.rb +36 -27
  72. data/lib/mongo/operation/shared/executable.rb +10 -8
  73. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  74. data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
  75. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
  76. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
  77. data/lib/mongo/operation/shared/write.rb +17 -10
  78. data/lib/mongo/operation/update/op_msg.rb +1 -1
  79. data/lib/mongo/protocol/compressed.rb +6 -5
  80. data/lib/mongo/protocol/insert.rb +3 -1
  81. data/lib/mongo/protocol/message.rb +72 -8
  82. data/lib/mongo/protocol/msg.rb +191 -37
  83. data/lib/mongo/protocol/query.rb +7 -9
  84. data/lib/mongo/protocol/serializers.rb +6 -2
  85. data/lib/mongo/server.rb +10 -4
  86. data/lib/mongo/server/connection.rb +20 -9
  87. data/lib/mongo/server/connection_base.rb +81 -12
  88. data/lib/mongo/server/connection_common.rb +61 -0
  89. data/lib/mongo/server/connection_pool.rb +37 -1
  90. data/lib/mongo/server/description.rb +9 -11
  91. data/lib/mongo/server/monitor.rb +2 -0
  92. data/lib/mongo/server/monitor/connection.rb +3 -18
  93. data/lib/mongo/server/pending_connection.rb +2 -1
  94. data/lib/mongo/session.rb +2 -2
  95. data/lib/mongo/session/session_pool.rb +8 -3
  96. data/lib/mongo/socket.rb +29 -16
  97. data/lib/mongo/socket/ssl.rb +23 -8
  98. data/lib/mongo/socket/tcp.rb +12 -3
  99. data/lib/mongo/timeout.rb +49 -0
  100. data/lib/mongo/uri.rb +30 -1
  101. data/lib/mongo/version.rb +1 -1
  102. data/mongo.gemspec +1 -1
  103. data/spec/README.md +134 -7
  104. data/spec/integration/auth_spec.rb +53 -0
  105. data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
  106. data/spec/integration/client_construction_spec.rb +76 -1
  107. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +351 -0
  108. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +301 -0
  109. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +71 -0
  110. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +76 -0
  111. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +216 -0
  112. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +600 -0
  113. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +183 -0
  114. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +74 -0
  115. data/spec/integration/client_side_encryption/client_close_spec.rb +59 -0
  116. data/spec/integration/client_side_encryption/corpus_spec.rb +228 -0
  117. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
  118. data/spec/integration/client_side_encryption/data_key_spec.rb +163 -0
  119. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
  120. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +137 -0
  121. data/spec/integration/client_side_encryption/views_spec.rb +42 -0
  122. data/spec/integration/client_update_spec.rb +120 -0
  123. data/spec/integration/command_monitoring_spec.rb +3 -1
  124. data/spec/integration/command_spec.rb +44 -10
  125. data/spec/integration/connection_spec.rb +57 -0
  126. data/spec/integration/reconnect_spec.rb +7 -6
  127. data/spec/integration/size_limit_spec.rb +94 -0
  128. data/spec/integration/srv_monitoring_spec.rb +14 -6
  129. data/spec/lite_spec_helper.rb +31 -22
  130. data/spec/mongo/auth/cr_spec.rb +8 -0
  131. data/spec/mongo/auth/ldap_spec.rb +5 -1
  132. data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
  133. data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
  134. data/spec/mongo/auth/scram_spec.rb +45 -35
  135. data/spec/mongo/auth/x509_spec.rb +5 -1
  136. data/spec/mongo/client_construction_spec.rb +206 -3
  137. data/spec/mongo/client_encryption_spec.rb +408 -0
  138. data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
  139. data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
  140. data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
  141. data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
  142. data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
  143. data/spec/mongo/collection/view_spec.rb +1 -1
  144. data/spec/mongo/collection_spec.rb +4 -33
  145. data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
  146. data/spec/mongo/crypt/auto_encrypter_spec.rb +182 -0
  147. data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
  148. data/spec/mongo/crypt/binary_spec.rb +115 -0
  149. data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
  150. data/spec/mongo/crypt/binding/context_spec.rb +257 -0
  151. data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
  152. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
  153. data/spec/mongo/crypt/binding/status_spec.rb +99 -0
  154. data/spec/mongo/crypt/binding/version_spec.rb +22 -0
  155. data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
  156. data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
  157. data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
  158. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
  159. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
  160. data/spec/mongo/crypt/handle_spec.rb +198 -0
  161. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
  162. data/spec/mongo/crypt/status_spec.rb +152 -0
  163. data/spec/mongo/cursor_spec.rb +24 -4
  164. data/spec/mongo/database_spec.rb +20 -0
  165. data/spec/mongo/error/crypt_error_spec.rb +26 -0
  166. data/spec/mongo/error/max_bson_size_spec.rb +35 -0
  167. data/spec/mongo/error/no_server_available_spec.rb +11 -1
  168. data/spec/mongo/error/operation_failure_spec.rb +6 -6
  169. data/spec/mongo/operation/aggregate_spec.rb +1 -1
  170. data/spec/mongo/operation/collections_info_spec.rb +1 -1
  171. data/spec/mongo/operation/command_spec.rb +3 -3
  172. data/spec/mongo/operation/create_index_spec.rb +3 -3
  173. data/spec/mongo/operation/create_user_spec.rb +3 -3
  174. data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
  175. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
  176. data/spec/mongo/operation/delete_spec.rb +7 -7
  177. data/spec/mongo/operation/drop_index_spec.rb +2 -2
  178. data/spec/mongo/operation/find/legacy_spec.rb +1 -1
  179. data/spec/mongo/operation/get_more_spec.rb +1 -1
  180. data/spec/mongo/operation/indexes_spec.rb +1 -1
  181. data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
  182. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
  183. data/spec/mongo/operation/insert_spec.rb +12 -12
  184. data/spec/mongo/operation/map_reduce_spec.rb +2 -2
  185. data/spec/mongo/operation/remove_user_spec.rb +3 -3
  186. data/spec/mongo/operation/update/bulk_spec.rb +6 -6
  187. data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
  188. data/spec/mongo/operation/update_spec.rb +7 -7
  189. data/spec/mongo/operation/update_user_spec.rb +1 -1
  190. data/spec/mongo/protocol/compressed_spec.rb +2 -3
  191. data/spec/mongo/protocol/delete_spec.rb +9 -8
  192. data/spec/mongo/protocol/get_more_spec.rb +9 -8
  193. data/spec/mongo/protocol/insert_spec.rb +9 -8
  194. data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
  195. data/spec/mongo/protocol/msg_spec.rb +57 -53
  196. data/spec/mongo/protocol/query_spec.rb +12 -12
  197. data/spec/mongo/protocol/registry_spec.rb +1 -1
  198. data/spec/mongo/protocol/reply_spec.rb +1 -1
  199. data/spec/mongo/protocol/update_spec.rb +10 -9
  200. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  201. data/spec/mongo/server/connection_spec.rb +28 -7
  202. data/spec/mongo/socket_spec.rb +1 -1
  203. data/spec/mongo/timeout_spec.rb +85 -0
  204. data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
  205. data/spec/mongo/uri_spec.rb +52 -5
  206. data/spec/mongo/write_concern_spec.rb +13 -1
  207. data/spec/{support → runners}/auth.rb +14 -1
  208. data/spec/{support → runners}/change_streams.rb +1 -1
  209. data/spec/{support → runners}/change_streams/operation.rb +0 -0
  210. data/spec/{support → runners}/cmap.rb +1 -1
  211. data/spec/{support → runners}/cmap/verifier.rb +0 -0
  212. data/spec/{support → runners}/command_monitoring.rb +0 -0
  213. data/spec/runners/connection_string.rb +358 -4
  214. data/spec/{support → runners}/crud.rb +9 -9
  215. data/spec/{support → runners}/crud/context.rb +0 -0
  216. data/spec/{support → runners}/crud/operation.rb +7 -3
  217. data/spec/{support → runners}/crud/outcome.rb +0 -0
  218. data/spec/{support → runners}/crud/requirement.rb +1 -1
  219. data/spec/{support → runners}/crud/spec.rb +12 -1
  220. data/spec/{support → runners}/crud/test.rb +0 -0
  221. data/spec/{support → runners}/crud/test_base.rb +0 -0
  222. data/spec/{support → runners}/crud/verifier.rb +10 -12
  223. data/spec/{support → runners}/gridfs.rb +0 -0
  224. data/spec/{support → runners}/sdam_monitoring.rb +0 -0
  225. data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
  226. data/spec/{support → runners}/server_selection.rb +0 -0
  227. data/spec/{support → runners}/server_selection_rtt.rb +0 -0
  228. data/spec/{support → runners}/transactions.rb +4 -4
  229. data/spec/{support → runners}/transactions/context.rb +0 -0
  230. data/spec/{support → runners}/transactions/operation.rb +0 -0
  231. data/spec/{support → runners}/transactions/spec.rb +0 -0
  232. data/spec/{support → runners}/transactions/test.rb +37 -5
  233. data/spec/spec_helper.rb +0 -5
  234. data/spec/spec_tests/auth_spec.rb +3 -3
  235. data/spec/spec_tests/client_side_encryption_spec.rb +13 -0
  236. data/spec/spec_tests/connection_string_spec.rb +1 -1
  237. data/spec/spec_tests/data/auth/connection-string.yml +13 -0
  238. data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
  239. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
  240. data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
  241. data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
  242. data/spec/spec_tests/data/client_side_encryption/bulk.yml +85 -0
  243. data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
  244. data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
  245. data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
  246. data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
  247. data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
  248. data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
  249. data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
  250. data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
  251. data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
  252. data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
  253. data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
  254. data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
  255. data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
  256. data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
  257. data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
  258. data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
  259. data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
  260. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
  261. data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
  262. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +61 -0
  263. data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
  264. data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
  265. data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
  266. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +168 -0
  267. data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
  268. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
  269. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
  270. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
  271. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
  272. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
  273. data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
  274. data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
  275. 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
  276. data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
  277. data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  278. data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  279. data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  280. data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  281. data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
  282. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
  283. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
  284. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
  285. data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
  286. data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
  287. data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
  288. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
  289. data/spec/spec_tests/uri_options_spec.rb +6 -8
  290. data/spec/stress/connection_pool_timing_spec.rb +6 -3
  291. data/spec/support/certificates/README.md +4 -0
  292. data/spec/support/certificates/server-second-level-bundle.pem +77 -77
  293. data/spec/support/certificates/server-second-level.crt +52 -52
  294. data/spec/support/certificates/server-second-level.key +25 -25
  295. data/spec/support/certificates/server-second-level.pem +77 -77
  296. data/spec/support/client_registry.rb +19 -3
  297. data/spec/support/cluster_config.rb +9 -1
  298. data/spec/support/common_shortcuts.rb +12 -0
  299. data/spec/support/constraints.rb +16 -0
  300. data/spec/support/crypt.rb +140 -0
  301. data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
  302. data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
  303. data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
  304. data/spec/support/crypt/corpus/corpus.json +3657 -0
  305. data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
  306. data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
  307. data/spec/support/crypt/data_keys/key_document_local.json +31 -0
  308. data/spec/support/crypt/external/external-key.json +31 -0
  309. data/spec/support/crypt/external/external-schema.json +19 -0
  310. data/spec/support/crypt/limits/limits-doc.json +102 -0
  311. data/spec/support/crypt/limits/limits-key.json +31 -0
  312. data/spec/support/crypt/limits/limits-schema.json +1405 -0
  313. data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
  314. data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  315. data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
  316. data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
  317. data/spec/support/lite_constraints.rb +17 -1
  318. data/spec/support/matchers.rb +19 -0
  319. data/spec/support/shared/protocol.rb +2 -0
  320. data/spec/support/spec_config.rb +43 -13
  321. data/spec/support/utils.rb +132 -10
  322. metadata +277 -81
  323. metadata.gz.sig +0 -0
  324. data/spec/integration/grid_fs_bucket_spec.rb +0 -48
  325. data/spec/integration/zlib_compression_spec.rb +0 -25
  326. data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
  327. data/spec/support/connection_string.rb +0 -354
@@ -0,0 +1,40 @@
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
+ # A Context object initialized for explicit decryption
19
+ #
20
+ # @api private
21
+ class ExplicitDecryptionContext < Context
22
+
23
+ # Create a new ExplicitDecryptionContext object
24
+ #
25
+ # @param [ Mongo::Crypt::Handle ] mongocrypt a Handle that
26
+ # wraps a mongocrypt_t object used to create a new mongocrypt_ctx_t
27
+ # @param [ ClientEncryption::IO ] io A instance of the IO class
28
+ # that implements driver I/O methods required to run the
29
+ # state machine
30
+ # @param [ BSON::Document ] doc A document to decrypt
31
+ def initialize(mongocrypt, io, doc)
32
+ super(mongocrypt, io)
33
+
34
+ # Initialize the underlying mongocrypt_ctx_t object to perform
35
+ # explicit decryption
36
+ Binding.ctx_explicit_decrypt_init(self, doc)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,117 @@
1
+ # Copyright (C) 2020 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
+ # An ExplicitEncrypter is an object that performs explicit encryption
19
+ # operations and handles all associated options and instance variables.
20
+ #
21
+ # @api private
22
+ class ExplicitEncrypter
23
+ # Create a new ExplicitEncrypter object.
24
+ #
25
+ # @params [ Mongo::Client ] key_vault_client An instance of Mongo::Client
26
+ # to connect to the key vault collection.
27
+ # @params [ String ] key_vault_namespace The namespace of the key vault
28
+ # collection in the format "db_name.collection_name".
29
+ # @option options [ Hash ] :kms_providers A hash of key management service
30
+ # configuration information. Valid hash keys are :local or :aws. There
31
+ # may be more than one KMS provider specified.
32
+ def initialize(key_vault_client, key_vault_namespace, kms_providers)
33
+ @crypt_handle = Handle.new(kms_providers)
34
+
35
+ @encryption_io = EncryptionIO.new(
36
+ key_vault_client: key_vault_client,
37
+ key_vault_namespace: key_vault_namespace
38
+ )
39
+ end
40
+
41
+ # Generates a data key used for encryption/decryption and stores
42
+ # that key in the KMS collection. The generated key is encrypted with
43
+ # the KMS master key.
44
+ #
45
+ # @param [ String ] kms_provider The KMS provider to use. Valid values are
46
+ # "aws" and "local".
47
+ # @params [ Hash ] options
48
+ #
49
+ # @option options [ Hash ] :master_key Information about the AWS master key. Required
50
+ # if kms_provider is "aws".
51
+ # - :region [ String ] The The AWS region of the master key (required).
52
+ # - :key [ String ] The Amazon Resource Name (ARN) of the master key (required).
53
+ # - :endpoint [ String ] An alternate host to send KMS requests to (optional).
54
+ # endpoint should be a host name with an optional port number separated
55
+ # by a colon (e.g. "kms.us-east-1.amazonaws.com" or
56
+ # "kms.us-east-1.amazonaws.com:443"). An endpoint in any other format
57
+ # will not be properly parsed.
58
+ # @option options [ Array<String> ] :key_alt_names An optional array of strings specifying
59
+ # alternate names for the new data key.
60
+ #
61
+ # @return [ BSON::Binary ] The 16-byte UUID of the new data key as a
62
+ # BSON::Binary object with type :uuid.
63
+ def create_and_insert_data_key(kms_provider, options)
64
+ data_key_document = Crypt::DataKeyContext.new(
65
+ @crypt_handle,
66
+ @encryption_io,
67
+ kms_provider,
68
+ options
69
+ ).run_state_machine
70
+
71
+ @encryption_io.insert_data_key(data_key_document).inserted_id
72
+ end
73
+
74
+ # Encrypts a value using the specified encryption key and algorithm
75
+ #
76
+ # @param [ Object ] value The value to encrypt
77
+ # @param [ Hash ] options
78
+ #
79
+ # @option options [ BSON::Binary ] :key_id A BSON::Binary object of type :uuid
80
+ # representing the UUID of the encryption key as it is stored in the key
81
+ # vault collection.
82
+ # @option options [ String ] :key_alt_name The alternate name for the
83
+ # encryption key.
84
+ # @option options [ String ] :algorithm The algorithm used to encrypt the value.
85
+ # Valid algorithms are "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
86
+ # or "AEAD_AES_256_CBC_HMAC_SHA_512-Random".
87
+ #
88
+ # @note The :key_id and :key_alt_name options are mutually exclusive. Only
89
+ # one is required to perform explicit encryption.
90
+ #
91
+ # @return [ BSON::Binary ] A BSON Binary object of subtype 6 (ciphertext)
92
+ # representing the encrypted value
93
+ def encrypt(value, options)
94
+ Crypt::ExplicitEncryptionContext.new(
95
+ @crypt_handle,
96
+ @encryption_io,
97
+ { 'v': value },
98
+ options
99
+ ).run_state_machine['v']
100
+ end
101
+
102
+ # Decrypts a value that has already been encrypted
103
+ #
104
+ # @param [ BSON::Binary ] value A BSON Binary object of subtype 6 (ciphertext)
105
+ # that will be decrypted
106
+ #
107
+ # @return [ Object ] The decrypted value
108
+ def decrypt(value)
109
+ result = Crypt::ExplicitDecryptionContext.new(
110
+ @crypt_handle,
111
+ @encryption_io,
112
+ { 'v': value },
113
+ ).run_state_machine['v']
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,89 @@
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
+ # A Context object initialized for explicit encryption
19
+ #
20
+ # @api private
21
+ class ExplicitEncryptionContext < Context
22
+
23
+ # Create a new ExplicitEncryptionContext object
24
+ #
25
+ # @param [ Mongo::Crypt::Handle ] mongocrypt a Handle that
26
+ # wraps a mongocrypt_t object used to create a new mongocrypt_ctx_t
27
+ # @param [ ClientEncryption::IO ] io A instance of the IO class
28
+ # that implements driver I/O methods required to run the
29
+ # state machine
30
+ # @param [ BSON::Document ] doc A document to encrypt
31
+ # @param [ Hash ] options
32
+ #
33
+ # @option options [ BSON::Binary ] :key_id A BSON::Binary object of type
34
+ # :uuid representing the UUID of the data key to use for encryption.
35
+ # @option options [ String ] :key_alt_name The alternate name of the data key
36
+ # that will be used to encrypt the value.
37
+ # @option options [ String ] :algorithm The algorithm used to encrypt the
38
+ # value. Valid algorithms are "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
39
+ # or "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
40
+ #
41
+ # @raises [ ArgumentError|Mongo::Error::CryptError ] If invalid options are provided
42
+ def initialize(mongocrypt, io, doc, options={})
43
+ super(mongocrypt, io)
44
+
45
+ if options[:key_id].nil? && options[:key_alt_name].nil?
46
+ raise ArgumentError.new(
47
+ 'The :key_id and :key_alt_name options cannot both be nil. ' +
48
+ 'Specify a :key_id option or :key_alt_name option (but not both)'
49
+ )
50
+ end
51
+
52
+ if options[:key_id] && options[:key_alt_name]
53
+ raise ArgumentError.new(
54
+ 'The :key_id and :key_alt_name options cannot both be present. ' +
55
+ 'Identify the data key by specifying its id with the :key_id ' +
56
+ 'option or specifying its alternate name with the :key_alt_name option'
57
+ )
58
+ end
59
+
60
+ # Set the key id or key alt name option on the mongocrypt_ctx_t object
61
+ # and raise an exception if the key_id or key_alt_name is invalid.
62
+ if options[:key_id]
63
+ unless options[:key_id].is_a?(BSON::Binary) &&
64
+ options[:key_id].type == :uuid
65
+ raise ArgumentError.new(
66
+ "Expected the :key_id option to be a BSON::Binary object with " +
67
+ "type :uuid. #{options[:key_id]} is an invalid :key_id option"
68
+ )
69
+ end
70
+
71
+ Binding.ctx_setopt_key_id(self, options[:key_id].data)
72
+ elsif options[:key_alt_name]
73
+ unless options[:key_alt_name].is_a?(String)
74
+ raise ArgumentError.new(':key_alt_name option must be a String')
75
+ end
76
+ Binding.ctx_setopt_key_alt_names(self, [options[:key_alt_name]])
77
+ end
78
+
79
+ # Set the algorithm option on the mongocrypt_ctx_t object and raises
80
+ # an exception if the algorithm is invalid.
81
+ Binding.ctx_setopt_algorithm(self, options[:algorithm])
82
+
83
+ # Initializes the mongocrypt_ctx_t object for explicit encryption and
84
+ # passes in the value to be encrypted.
85
+ Binding.ctx_explicit_encrypt_init(self, doc)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,293 @@
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
+ require 'base64'
17
+
18
+ module Mongo
19
+ module Crypt
20
+
21
+ # A handle to the libmongocrypt library that wraps a mongocrypt_t object,
22
+ # allowing clients to set options on that object or perform operations such
23
+ # as encryption and decryption
24
+ #
25
+ # @api private
26
+ class Handle
27
+ # Creates a new Handle object and initializes it with options
28
+ #
29
+ # @param [ Hash ] kms_providers A hash of KMS settings. The only supported
30
+ # key is currently :local. Local KMS options must be passed in the
31
+ # format { local: { key: <master key> } } where the master key is a
32
+ # 96-byte, base64 encoded string.
33
+ # @param [ Hash ] options A hash of options
34
+ #
35
+ # @option options [ Hash | nil ] :schema_map A hash representing the JSON schema
36
+ # of the collection that stores auto encrypted documents.
37
+ # @option options [ Logger ] :logger A Logger object to which libmongocrypt logs
38
+ # will be sent
39
+ def initialize(kms_providers, options={})
40
+ # FFI::AutoPointer uses a custom release strategy to automatically free
41
+ # the pointer once this object goes out of scope
42
+ @mongocrypt = FFI::AutoPointer.new(
43
+ Binding.mongocrypt_new,
44
+ Binding.method(:mongocrypt_destroy)
45
+ )
46
+
47
+ @schema_map = options[:schema_map]
48
+ set_schema_map if @schema_map
49
+
50
+ @logger = options[:logger]
51
+ set_logger_callback if @logger
52
+
53
+ set_crypto_hooks
54
+
55
+ set_kms_providers(kms_providers)
56
+ initialize_mongocrypt
57
+ end
58
+
59
+ # Return the reference to the underlying @mongocrypt object
60
+ #
61
+ # @return [ FFI::Pointer ]
62
+ def ref
63
+ @mongocrypt
64
+ end
65
+
66
+ private
67
+
68
+ # Set the schema map option on the underlying mongocrypt_t object
69
+ def set_schema_map
70
+ unless @schema_map.is_a?(Hash)
71
+ raise ArgumentError.new(
72
+ "#{@schema_map} is an invalid schema_map; schema_map must be a Hash or nil"
73
+ )
74
+ end
75
+
76
+ Binding.setopt_schema_map(self, @schema_map)
77
+ end
78
+
79
+ # Send the logs from libmongocrypt to the Mongo::Logger
80
+ def set_logger_callback
81
+ @log_callback = Proc.new do |level, msg|
82
+ @logger.send(level, msg)
83
+ end
84
+
85
+ Binding.setopt_log_handler(@mongocrypt, @log_callback)
86
+ end
87
+
88
+ # Yields to the provided block and rescues exceptions raised by
89
+ # the block. If an exception was raised, sets the specified status
90
+ # to the exception message and returns false. If no exceptions were
91
+ # raised, does not modify the status and returns true.
92
+ #
93
+ # This method is meant to be used with libmongocrypt callbacks and
94
+ # follows the API defined by libmongocrypt.
95
+ #
96
+ # @param [ FFI::Pointer ] status_p A pointer to libmongocrypt status object
97
+ #
98
+ # @return [ true | false ] Whether block executed without raising
99
+ # exceptions.
100
+ def handle_error(status_p)
101
+ begin
102
+ yield
103
+
104
+ true
105
+ rescue => e
106
+ status = Status.from_pointer(status_p)
107
+ status.update(:error_client, 1, "#{e.class}: #{e}")
108
+ false
109
+ end
110
+ end
111
+
112
+ # Yields to the provided block and writes the return value of block
113
+ # to the specified mongocrypt_binary_t object. If an exception is
114
+ # raised during execution of the block, writes the exception message
115
+ # to the specified status object and returns false. If no exception is
116
+ # raised, does not modify status and returns true.
117
+ # message to the mongocrypt_status_t object.
118
+ #
119
+ # @param [ FFI::Pointer ] output_binary_p A pointer to libmongocrypt
120
+ # Binary object to receive the result of block's execution
121
+ # @param [ FFI::Pointer ] status_p A pointer to libmongocrypt status object
122
+ #
123
+ # @return [ true | false ] Whether block executed without raising
124
+ # exceptions.
125
+ def write_binary_string_and_set_status(output_binary_p, status_p)
126
+ handle_error(status_p) do
127
+ output = yield
128
+
129
+ Binary.from_pointer(output_binary_p).write(output)
130
+ end
131
+ end
132
+
133
+ # Perform AES encryption or decryption and write the output to the
134
+ # provided mongocrypt_binary_t object.
135
+ def do_aes(key_binary_p, iv_binary_p, input_binary_p, output_binary_p,
136
+ response_length_p, status_p, decrypt: false)
137
+ key = Binary.from_pointer(key_binary_p).to_s
138
+ iv = Binary.from_pointer(iv_binary_p).to_s
139
+ input = Binary.from_pointer(input_binary_p).to_s
140
+
141
+ write_binary_string_and_set_status(output_binary_p, status_p) do
142
+ output = Hooks.aes(key, iv, input, decrypt: decrypt)
143
+ response_length_p.write_int(output.bytesize)
144
+
145
+ output
146
+ end
147
+ end
148
+
149
+ # Perform HMAC SHA encryption and write the output to the provided
150
+ # mongocrypt_binary_t object.
151
+ def do_hmac_sha(digest_name, key_binary_p, input_binary_p,
152
+ output_binary_p, status_p)
153
+ key = Binary.from_pointer(key_binary_p).to_s
154
+ input = Binary.from_pointer(input_binary_p).to_s
155
+
156
+ write_binary_string_and_set_status(output_binary_p, status_p) do
157
+ Hooks.hmac_sha(digest_name, key, input)
158
+ end
159
+ end
160
+
161
+ # We are buildling libmongocrypt without crypto functions to remove the
162
+ # external dependency on OpenSSL. This method binds native Ruby crypto
163
+ # methods to the underlying mongocrypt_t object so that libmongocrypt can
164
+ # still perform cryptography.
165
+ #
166
+ # Every crypto binding ignores its first argument, which is an option
167
+ # mongocrypt_ctx_t object and is not required to use crypto hooks.
168
+ def set_crypto_hooks
169
+ @aes_encrypt = Proc.new do |_, key_binary_p, iv_binary_p, input_binary_p,
170
+ output_binary_p, response_length_p, status_p|
171
+ do_aes(
172
+ key_binary_p,
173
+ iv_binary_p,
174
+ input_binary_p,
175
+ output_binary_p,
176
+ response_length_p,
177
+ status_p
178
+ )
179
+ end
180
+
181
+ @aes_decrypt = Proc.new do |_, key_binary_p, iv_binary_p, input_binary_p,
182
+ output_binary_p, response_length_p, status_p|
183
+ do_aes(
184
+ key_binary_p,
185
+ iv_binary_p,
186
+ input_binary_p,
187
+ output_binary_p,
188
+ response_length_p,
189
+ status_p,
190
+ decrypt: true
191
+ )
192
+ end
193
+
194
+ @random = Proc.new do |_, output_binary_p, num_bytes, status_p|
195
+ write_binary_string_and_set_status(output_binary_p, status_p) do
196
+ Hooks.random(num_bytes)
197
+ end
198
+ end
199
+
200
+ @hmac_sha_512 = Proc.new do |_, key_binary_p, input_binary_p,
201
+ output_binary_p, status_p|
202
+ do_hmac_sha('SHA512', key_binary_p, input_binary_p, output_binary_p, status_p)
203
+ end
204
+
205
+ @hmac_sha_256 = Proc.new do |_, key_binary_p, input_binary_p,
206
+ output_binary_p, status_p|
207
+ do_hmac_sha('SHA256', key_binary_p, input_binary_p, output_binary_p, status_p)
208
+ end
209
+
210
+ @hmac_hash = Proc.new do |_, input_binary_p, output_binary_p, status_p|
211
+ input = Binary.from_pointer(input_binary_p).to_s
212
+
213
+ write_binary_string_and_set_status(output_binary_p, status_p) do
214
+ Hooks.hash_sha256(input)
215
+ end
216
+ end
217
+
218
+ Binding.setopt_crypto_hooks(
219
+ self,
220
+ @aes_encrypt,
221
+ @aes_decrypt,
222
+ @random,
223
+ @hmac_sha_512,
224
+ @hmac_sha_256,
225
+ @hmac_hash,
226
+ )
227
+ end
228
+
229
+ # Validate the kms_providers option and use it to set the KMS provider
230
+ # information on the underlying mongocrypt_t object
231
+ def set_kms_providers(kms_providers)
232
+ unless kms_providers
233
+ raise ArgumentError.new("The kms_providers option must not be nil")
234
+ end
235
+
236
+ unless kms_providers.key?(:local) || kms_providers.key?(:aws)
237
+ raise ArgumentError.new(
238
+ 'The kms_providers option must have one of the following keys: ' +
239
+ ':aws, :local'
240
+ )
241
+ end
242
+
243
+ set_kms_providers_local(kms_providers) if kms_providers.key?(:local)
244
+ set_kms_providers_aws(kms_providers) if kms_providers.key?(:aws)
245
+ end
246
+
247
+ # Validate and set the local KMS provider information on the underlying
248
+ # mongocrypt_t object and raise an exception if the operation fails
249
+ def set_kms_providers_local(kms_providers)
250
+ unless kms_providers[:local][:key] && kms_providers[:local][:key].is_a?(String)
251
+ raise ArgumentError.new(
252
+ "The specified local kms_providers option is invalid: " +
253
+ "#{kms_providers[:local]}. kms_providers with :local key must be " +
254
+ "in the format: { local: { key: 'MASTER-KEY' } }"
255
+ )
256
+ end
257
+
258
+ master_key = kms_providers[:local][:key]
259
+ Binding.setopt_kms_provider_local(self, master_key)
260
+ end
261
+
262
+ # Validate and set the aws KMS provider information on the underlying
263
+ # mongocrypt_t object and raise an exception if the operation fails
264
+ def set_kms_providers_aws(kms_providers)
265
+ unless kms_providers[:aws]
266
+ raise ArgumentError.new('The :aws KMS provider must not be nil')
267
+ end
268
+
269
+ access_key_id = kms_providers[:aws][:access_key_id]
270
+ secret_access_key = kms_providers[:aws][:secret_access_key]
271
+
272
+ valid_access_key_id = access_key_id && access_key_id.is_a?(String)
273
+ valid_secret_access_key = secret_access_key && secret_access_key.is_a?(String)
274
+
275
+ unless valid_access_key_id && valid_secret_access_key
276
+ raise ArgumentError.new(
277
+ "The specified aws kms_providers option is invalid: #{kms_providers[:aws]}. " +
278
+ "kms_providers with :aws key must be in the format: " +
279
+ "{ aws: { access_key_id: 'YOUR-ACCESS-KEY-ID', secret_access_key: 'SECRET-ACCESS-KEY' } }"
280
+ )
281
+ end
282
+
283
+ Binding.setopt_kms_provider_aws(self, access_key_id, secret_access_key)
284
+ end
285
+
286
+ # Initialize the underlying mongocrypt_t object and raise an error if the operation fails
287
+ def initialize_mongocrypt
288
+ Binding.init(self)
289
+ # There is currently no test for the error(?) code path
290
+ end
291
+ end
292
+ end
293
+ end