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,183 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Client-Side Encryption' do
4
+ describe 'Prose tests: BSON size limits and batch splitting' do
5
+ require_libmongocrypt
6
+ require_enterprise
7
+ min_server_fcv '4.2'
8
+
9
+ include_context 'define shared FLE helpers'
10
+
11
+ let(:subscriber) { EventSubscriber.new }
12
+
13
+ let(:client) do
14
+ authorized_client.use('db')
15
+ end
16
+
17
+ let(:json_schema) do
18
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/limits/limits-schema.json'))
19
+ end
20
+
21
+ let(:limits_doc) do
22
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/limits/limits-doc.json'))
23
+ end
24
+
25
+ let(:client_encrypted) do
26
+ new_local_client(
27
+ SpecConfig.instance.addresses,
28
+ SpecConfig.instance.test_options.merge(
29
+ auto_encryption_options: {
30
+ kms_providers: {
31
+ local: { key: local_master_key },
32
+ },
33
+ key_vault_namespace: 'admin.datakeys',
34
+ },
35
+ database: 'db',
36
+ )
37
+ ).tap do |client|
38
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
39
+ end
40
+ end
41
+
42
+ before do
43
+ client['coll'].drop
44
+ client['coll',
45
+ {
46
+ 'validator' => { '$jsonSchema' => json_schema }
47
+ }
48
+ ].create
49
+
50
+ client.use('admin')['datakeys'].drop
51
+ client.use('admin')['datakeys'].insert_one(
52
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/limits/limits-key.json'))
53
+ )
54
+ end
55
+
56
+ let(:_2mib) { 2097152 }
57
+ let(:_16mib) { 16777216 }
58
+
59
+ context 'when a single, unencrypted document is larger than 2MiB' do
60
+ it 'can perform insert_one using the encrypted client' do
61
+ document = {
62
+ _id: "over_2mib_under_16mib",
63
+ unencrypted: 'a' * _2mib
64
+ }
65
+
66
+ result = client_encrypted['coll'].insert_one(document)
67
+
68
+ expect(result).to be_ok
69
+ end
70
+ end
71
+
72
+ context 'when a single encrypted document is larger than 2MiB' do
73
+ it 'can perform insert_one using the encrypted client' do
74
+ result = client_encrypted['coll'].insert_one(
75
+ limits_doc.merge(
76
+ _id: "encryption_exceeds_2mi",
77
+ unencrypted: 'a' * (_2mib - 2000)
78
+ )
79
+ )
80
+
81
+ expect(result).to be_ok
82
+ end
83
+ end
84
+
85
+ context 'when bulk inserting two unencrypted documents under 2MiB' do
86
+ it 'can perform bulk insert using the encrypted client' do
87
+ bulk_write = Mongo::BulkWrite.new(
88
+ client_encrypted[:coll],
89
+ [
90
+ { insert_one: { _id: 'over_2mib_1', unencrypted: 'a' * _2mib } },
91
+ { insert_one: { _id: 'over_2mib_2', unencrypted: 'a' * _2mib } },
92
+ ]
93
+ )
94
+
95
+ result = bulk_write.execute
96
+ expect(result.inserted_count).to eq(2)
97
+
98
+ command_succeeded_events = subscriber.succeeded_events.select do |event|
99
+ event.command_name == 'insert'
100
+ end
101
+
102
+ expect(command_succeeded_events.length).to eq(2)
103
+ end
104
+ end
105
+
106
+ context 'when bulk deletes two unencrypted documents under 2MiB' do
107
+ it 'can perform bulk delete using the encrypted client' do
108
+ # Insert documents that we can match and delete later
109
+ bulk_write = Mongo::BulkWrite.new(
110
+ client_encrypted[:coll],
111
+ [
112
+ { insert_one: { _id: 'over_2mib_1', unencrypted: 'a' * _2mib } },
113
+ { insert_one: { _id: 'over_2mib_2', unencrypted: 'a' * _2mib } },
114
+ ]
115
+ )
116
+
117
+ result = bulk_write.execute
118
+ expect(result.inserted_count).to eq(2)
119
+
120
+ command_succeeded_events = subscriber.succeeded_events.select do |event|
121
+ event.command_name == 'insert'
122
+ end
123
+
124
+ expect(command_succeeded_events.length).to eq(2)
125
+ end
126
+ end
127
+
128
+ context 'when bulk inserting two encrypted documents under 2MiB' do
129
+ it 'can perform bulk_insert using the encrypted client' do
130
+ bulk_write = Mongo::BulkWrite.new(
131
+ client_encrypted[:coll],
132
+ [
133
+ {
134
+ insert_one: limits_doc.merge(
135
+ _id: "encryption_exceeds_2mib_1",
136
+ unencrypted: 'a' * (_2mib - 2000)
137
+ )
138
+ },
139
+ {
140
+ insert_one: limits_doc.merge(
141
+ _id: 'encryption_exceeds_2mib_2',
142
+ unencrypted: 'a' * (_2mib - 2000)
143
+ )
144
+ },
145
+ ]
146
+ )
147
+
148
+ result = bulk_write.execute
149
+ expect(result.inserted_count).to eq(2)
150
+
151
+ command_succeeded_events = subscriber.succeeded_events.select do |event|
152
+ event.command_name == 'insert'
153
+ end
154
+
155
+ expect(command_succeeded_events.length).to eq(2)
156
+ end
157
+ end
158
+
159
+ context 'when a single document is just smaller than 16MiB' do
160
+ it 'can perform insert_one using the encrypted client' do
161
+ result = client_encrypted[:coll].insert_one(
162
+ _id: "under_16mib",
163
+ unencrypted: "a" * (_16mib - 2000)
164
+ )
165
+
166
+ expect(result).to be_ok
167
+ end
168
+ end
169
+
170
+ context 'when an encrypted document is greater than the 16MiB limit' do
171
+ it 'raises an exception when attempting to insert the document' do
172
+ expect do
173
+ client_encrypted[:coll].insert_one(
174
+ limits_doc.merge(
175
+ _id: "encryption_exceeds_16mib",
176
+ unencrypted: "a" * (16*1024*1024 + 500*1024),
177
+ )
178
+ )
179
+ end.to raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Client-Side Encryption' do
4
+ describe 'Prose tests: Bypass mongocryptd spawn' do
5
+ require_libmongocrypt
6
+ require_enterprise
7
+ min_server_fcv '4.2'
8
+
9
+ include_context 'define shared FLE helpers'
10
+
11
+ context 'via mongocryptdBypassSpawn' do
12
+ let(:test_schema_map) do
13
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/external/external-schema.json'))
14
+ end
15
+
16
+ let(:client) do
17
+ new_local_client(
18
+ SpecConfig.instance.addresses,
19
+ SpecConfig.instance.test_options.merge(
20
+ auto_encryption_options: {
21
+ kms_providers: local_kms_providers,
22
+ key_vault_namespace: 'admin.datakeys',
23
+ schema_map: { 'db.coll' => test_schema_map },
24
+ extra_options: {
25
+ mongocryptd_bypass_spawn: true,
26
+ mongocryptd_uri: "mongodb://localhost:27090/db?serverSelectionTimeoutMS=1000",
27
+ mongocryptd_spawn_args: [ "--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27090"],
28
+ },
29
+ },
30
+ database: :db
31
+ ),
32
+ )
33
+ end
34
+
35
+ it 'does not spawn' do
36
+ lambda do
37
+ client[:coll].insert_one(encrypted: 'test')
38
+ end.should raise_error(Mongo::Error::NoServerAvailable, /Server address=localhost:27090 UNKNOWN/)
39
+ end
40
+ end
41
+
42
+ context 'via bypassAutoEncryption' do
43
+ let(:client) do
44
+ new_local_client(
45
+ SpecConfig.instance.addresses,
46
+ SpecConfig.instance.test_options.merge(
47
+ auto_encryption_options: {
48
+ kms_providers: local_kms_providers,
49
+ key_vault_namespace: 'admin.datakeys',
50
+ bypass_auto_encryption: true,
51
+ extra_options: {
52
+ mongocryptd_spawn_args: [ "--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27090"],
53
+ },
54
+ },
55
+ database: :db
56
+ ),
57
+ )
58
+ end
59
+
60
+ let(:mongocryptd_client) do
61
+ new_local_client(['localhost:27090'], server_selection_timeout: 1)
62
+ end
63
+
64
+ it 'does not spawn' do
65
+ lambda do
66
+ client[:coll].insert_one(encrypted: 'test')
67
+ end.should_not raise_error
68
+ lambda do
69
+ mongocryptd_client.database.command(ismaster: 1)
70
+ end.should raise_error(Mongo::Error::NoServerAvailable)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Auto encryption client' do
4
+ require_libmongocrypt
5
+ require_enterprise
6
+ min_server_fcv '4.2'
7
+
8
+ context 'after client is disconnected' do
9
+
10
+ include_context 'define shared FLE helpers'
11
+ include_context 'with local kms_providers'
12
+
13
+ let(:client) do
14
+ new_local_client(
15
+ SpecConfig.instance.addresses,
16
+ SpecConfig.instance.test_options.merge(
17
+ auto_encryption_options: {
18
+ kms_providers: kms_providers,
19
+ key_vault_namespace: 'admin.datakeys',
20
+ schema_map: { 'auto_encryption.users' => schema_map },
21
+ },
22
+ database: :auto_encryption,
23
+ )
24
+ )
25
+ end
26
+
27
+ shared_examples 'a functioning auto-encrypter' do
28
+ it 'can still perform encryption' do
29
+ result = client[:users].insert_one(ssn: '000-000-0000')
30
+ expect(result).to be_ok
31
+
32
+ encrypted_document = authorized_client
33
+ .use(:auto_encryption)[:users]
34
+ .find(_id: result.inserted_ids.first)
35
+ .first
36
+
37
+ expect(encrypted_document['ssn']).to be_ciphertext
38
+ end
39
+ end
40
+
41
+ context 'after performing operation with auto encryption' do
42
+ before do
43
+ client[:users].insert_one(ssn: ssn)
44
+ client.close
45
+ end
46
+
47
+ it_behaves_like 'a functioning auto-encrypter'
48
+ end
49
+
50
+ context 'after performing operation without auto encryption' do
51
+ before do
52
+ client[:users].insert_one(age: 23)
53
+ client.close
54
+ end
55
+
56
+ it_behaves_like 'a functioning auto-encrypter'
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,228 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Client-Side Encryption' do
4
+ describe 'Prose tests: Corpus Test' do
5
+ require_libmongocrypt
6
+ require_enterprise
7
+ min_server_fcv '4.2'
8
+
9
+ include_context 'define shared FLE helpers'
10
+
11
+ let(:client) do
12
+ new_local_client(
13
+ SpecConfig.instance.addresses,
14
+ SpecConfig.instance.test_options
15
+ )
16
+ end
17
+
18
+ let(:test_schema_map) { BSON::ExtJSON.parse(File.read('spec/support/crypt/corpus/corpus-schema.json')) }
19
+ let(:local_data_key) { BSON::ExtJSON.parse(File.read('spec/support/crypt/corpus/corpus-key-local.json')) }
20
+ let(:aws_data_key) { BSON::ExtJSON.parse(File.read('spec/support/crypt/corpus/corpus-key-aws.json')) }
21
+
22
+ let(:client_encrypted) do
23
+ new_local_client(
24
+ SpecConfig.instance.addresses,
25
+ SpecConfig.instance.test_options.merge(
26
+ auto_encryption_options: {
27
+ kms_providers: {
28
+ local: { key: local_master_key },
29
+ aws: {
30
+ access_key_id: SpecConfig.instance.fle_aws_key,
31
+ secret_access_key: SpecConfig.instance.fle_aws_secret,
32
+ },
33
+ },
34
+ key_vault_namespace: 'admin.datakeys',
35
+ schema_map: local_schema_map,
36
+ },
37
+ database: :db,
38
+ )
39
+ )
40
+ end
41
+
42
+ let(:client_encryption) do
43
+ Mongo::ClientEncryption.new(
44
+ client,
45
+ {
46
+ kms_providers: {
47
+ local: { key: local_master_key },
48
+ aws: {
49
+ access_key_id: SpecConfig.instance.fle_aws_key,
50
+ secret_access_key: SpecConfig.instance.fle_aws_secret,
51
+ }
52
+ },
53
+ key_vault_namespace: 'admin.datakeys',
54
+ },
55
+ )
56
+ end
57
+
58
+ let(:corpus) do
59
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/corpus/corpus.json'), mode: :bson)
60
+ end
61
+
62
+ let(:corpus_encrypted_expected) do
63
+ BSON::ExtJSON.parse(File.read('spec/support/crypt/corpus/corpus_encrypted.json'))
64
+ end
65
+
66
+ let(:corpus_copied) do
67
+ # As per the instructions of the prose spec, corpus_copied is a copy of
68
+ # the corpus BSON::Document that encrypts all fields that are meant to
69
+ # be explicitly encrypted. corpus is a document containing many
70
+ # sub-documents, each with a value to encrypt and information about how
71
+ # to encrypt that value.
72
+ corpus_copied = BSON::Document.new
73
+ corpus.each do |key, doc|
74
+ if ['_id', 'altname_aws', 'altname_local'].include?(key)
75
+ corpus_copied[key] = doc
76
+ next
77
+ end
78
+
79
+ if doc['method'] == 'auto'
80
+ corpus_copied[key] = doc
81
+ elsif doc['method'] == 'explicit'
82
+ options = if doc['identifier'] == 'id'
83
+ key_id = if doc['kms'] == 'local'
84
+ 'LOCALAAAAAAAAAAAAAAAAA=='
85
+ else
86
+ 'AWSAAAAAAAAAAAAAAAAAAA=='
87
+ end
88
+
89
+ { key_id: BSON::Binary.new(Base64.decode64(key_id), :uuid) }
90
+ elsif doc['identifier'] == 'altname'
91
+ { key_alt_name: doc['kms'] }
92
+ end
93
+
94
+ algorithm = if doc['algo'] == 'rand'
95
+ 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'
96
+ else
97
+ 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
98
+ end
99
+
100
+ begin
101
+ encrypted_value = client_encryption.encrypt(
102
+ doc['value'],
103
+ options.merge({ algorithm: algorithm })
104
+ )
105
+
106
+ corpus_copied[key] = doc.merge('value' => encrypted_value)
107
+ rescue => e
108
+ # If doc['allowed'] is true, it means that this field should have
109
+ # been encrypted without error, and thus that this error is unexpected.
110
+ # If doc['allowed'] is false, this error was expected and the value
111
+ # should be copied over without being encrypted.
112
+ if doc['allowed']
113
+ raise "Unexpected error occured in client-side encryption " +
114
+ "corpus tests: #{e.class}: #{e.message}"
115
+ end
116
+
117
+ corpus_copied[key] = doc
118
+ end
119
+ end
120
+ end
121
+
122
+ corpus_copied
123
+ end
124
+
125
+ before do
126
+ client.use(:db)[:coll].drop
127
+
128
+ client.use(:admin)[:datakeys].drop
129
+ client.use(:admin)[:datakeys].insert_one(local_data_key)
130
+ client.use(:admin)[:datakeys].insert_one(aws_data_key)
131
+ end
132
+
133
+ shared_context 'with jsonSchema collection validator' do
134
+ let(:local_schema_map) { nil }
135
+
136
+ before do
137
+ client.use(:db)[:coll,
138
+ {
139
+ 'validator' => { '$jsonSchema' => test_schema_map }
140
+ }
141
+ ].create
142
+ end
143
+ end
144
+
145
+ shared_context 'with local schema map' do
146
+ let(:local_schema_map) { { 'db.coll' => test_schema_map } }
147
+ end
148
+
149
+ shared_examples 'a functioning encrypter' do
150
+ it 'properly encrypts and decrypts a document' do
151
+ corpus_encrypted_id = client_encrypted[:coll]
152
+ .insert_one(corpus_copied)
153
+ .inserted_id
154
+
155
+ corpus_decrypted = client_encrypted[:coll]
156
+ .find(_id: corpus_encrypted_id)
157
+ .first
158
+
159
+ # Ensure that corpus_decrypted is the same as the original corpus
160
+ # document by checking that they have the same set of keys, and that
161
+ # they have the same values at those keys (improved diagnostics).
162
+ expect(corpus_decrypted.keys).to eq(corpus.keys)
163
+
164
+ corpus_decrypted.each do |key, doc|
165
+ expect(key => doc).to eq(key => corpus[key])
166
+ end
167
+
168
+ corpus_encrypted_actual = client
169
+ .use(:db)[:coll]
170
+ .find(_id: corpus_encrypted_id)
171
+ .first
172
+
173
+ # Check that the actual encrypted document matches the expected
174
+ # encrypted document.
175
+ expect(corpus_encrypted_actual.keys).to eq(corpus_encrypted_expected.keys)
176
+
177
+ corpus_encrypted_actual.each do |key, value|
178
+ # If it was deterministically encrypted, test the encrypted values
179
+ # for equality.
180
+ if value['algo'] == 'det'
181
+ expect(value['value']).to eq(corpus_encrypted_expected[key]['value'])
182
+ else
183
+ # If the document was randomly encrypted, the two encrypted values
184
+ # will not be equal. Ensure that they are equal when decrypted.
185
+ if value['allowed']
186
+ actual_decrypted_value = client_encryption.decrypt(value['value'])
187
+ expected_decrypted_value = client_encryption.decrypt(corpus_encrypted_expected[key]['value'])
188
+
189
+ expect(actual_decrypted_value).to eq(expected_decrypted_value)
190
+ else
191
+ # If 'allowed' was false, the value was never encrypted; ensure
192
+ # that it is equal to the original, unencrypted value.
193
+ expect(value['value']).to eq(corpus[key]['value'])
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ context 'with local KMS provider' do
201
+ include_context 'with local kms_providers'
202
+
203
+ context 'with collection validator' do
204
+ include_context 'with jsonSchema collection validator'
205
+ it_behaves_like 'a functioning encrypter'
206
+ end
207
+
208
+ context 'with schema map' do
209
+ include_context 'with local schema map'
210
+ it_behaves_like 'a functioning encrypter'
211
+ end
212
+ end
213
+
214
+ context 'with AWS KMS provider' do
215
+ include_context 'with AWS kms_providers'
216
+
217
+ context 'with collection validator' do
218
+ include_context 'with jsonSchema collection validator'
219
+ it_behaves_like 'a functioning encrypter'
220
+ end
221
+
222
+ context 'with schema map' do
223
+ include_context 'with local schema map'
224
+ it_behaves_like 'a functioning encrypter'
225
+ end
226
+ end
227
+ end
228
+ end