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,600 @@
1
+ require 'spec_helper'
2
+ require 'bson'
3
+ require 'json'
4
+
5
+ describe 'Auto Encryption' do
6
+ require_libmongocrypt
7
+ min_server_fcv '4.2'
8
+ require_enterprise
9
+
10
+ # Diagnostics of leaked background threads only, these tests do not
11
+ # actually require a clean slate. https://jira.mongodb.org/browse/RUBY-2138
12
+ clean_slate
13
+
14
+ include_context 'define shared FLE helpers'
15
+
16
+ let(:encryption_client) do
17
+ new_local_client(
18
+ SpecConfig.instance.addresses,
19
+ SpecConfig.instance.test_options.merge(
20
+ auto_encryption_options: {
21
+ kms_providers: kms_providers,
22
+ key_vault_namespace: key_vault_namespace,
23
+ schema_map: local_schema,
24
+ bypass_auto_encryption: bypass_auto_encryption
25
+ },
26
+ database: 'auto_encryption'
27
+ ),
28
+ )
29
+ end
30
+
31
+ let(:client) { authorized_client.use(:auto_encryption) }
32
+ let(:admin_client) { authorized_client.use(:admin) }
33
+
34
+ let(:bypass_auto_encryption) { false }
35
+
36
+ let(:encrypted_ssn_binary) do
37
+ BSON::Binary.new(Base64.decode64(encrypted_ssn), :ciphertext)
38
+ end
39
+
40
+ shared_context 'bypass auto encryption' do
41
+ let(:bypass_auto_encryption) { true }
42
+ end
43
+
44
+ shared_context 'jsonSchema validator on collection' do
45
+ let(:local_schema) { nil }
46
+
47
+ before do
48
+ client[:users,
49
+ {
50
+ 'validator' => { '$jsonSchema' => schema_map }
51
+ }
52
+ ].create
53
+ end
54
+ end
55
+
56
+ shared_context 'schema map in client options' do
57
+ let(:local_schema) { { "auto_encryption.users" => schema_map } }
58
+
59
+ before do
60
+ client[:users].create
61
+ end
62
+ end
63
+
64
+ shared_context 'encrypted document in collection' do
65
+ before do
66
+ client[:users].insert_one(ssn: encrypted_ssn_binary)
67
+ end
68
+ end
69
+
70
+ shared_context 'multiple encrypted documents in collection' do
71
+ before do
72
+ client[:users].insert_one(ssn: encrypted_ssn_binary)
73
+ client[:users].insert_one(ssn: encrypted_ssn_binary)
74
+ end
75
+ end
76
+
77
+ before(:each) do
78
+ client[:users].drop
79
+ admin_client[:datakeys].drop
80
+ admin_client[:datakeys].insert_one(data_key)
81
+ end
82
+
83
+ shared_examples 'an encrypted command' do
84
+ context 'with AWS KMS provider' do
85
+ include_context 'with AWS kms_providers'
86
+
87
+ context 'with validator' do
88
+ include_context 'jsonSchema validator on collection'
89
+ it_behaves_like 'it performs an encrypted command'
90
+ end
91
+
92
+ context 'with schema map' do
93
+ include_context 'schema map in client options'
94
+ it_behaves_like 'it performs an encrypted command'
95
+ end
96
+ end
97
+
98
+ context 'with local KMS provider' do
99
+ include_context 'with local kms_providers'
100
+
101
+ context 'with validator' do
102
+ include_context 'jsonSchema validator on collection'
103
+ it_behaves_like 'it performs an encrypted command'
104
+ end
105
+
106
+ context 'with schema map' do
107
+ include_context 'schema map in client options'
108
+ it_behaves_like 'it performs an encrypted command'
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '#aggregate' do
114
+ shared_examples 'it performs an encrypted command' do
115
+ include_context 'encrypted document in collection'
116
+
117
+ let(:result) do
118
+ encryption_client[:users].aggregate([
119
+ { '$match' => { 'ssn' => ssn } }
120
+ ]).first
121
+ end
122
+
123
+ it 'encrypts the command and decrypts the response' do
124
+ result.should_not be_nil
125
+ result['ssn'].should == ssn
126
+ end
127
+
128
+ context 'when bypass_auto_encryption=true' do
129
+ include_context 'bypass auto encryption'
130
+
131
+ it 'does not encrypt the command' do
132
+ result.should be_nil
133
+ end
134
+
135
+ it 'does auto decrypt the response' do
136
+ result = encryption_client[:users].aggregate([
137
+ { '$match' => { 'ssn' => encrypted_ssn_binary } }
138
+ ]).first
139
+
140
+ result.should_not be_nil
141
+ result['ssn'].should == ssn
142
+ end
143
+ end
144
+ end
145
+
146
+ it_behaves_like 'an encrypted command'
147
+ end
148
+
149
+ describe '#count' do
150
+ shared_examples 'it performs an encrypted command' do
151
+ include_context 'multiple encrypted documents in collection'
152
+
153
+ let(:result) { encryption_client[:users].count(ssn: ssn) }
154
+
155
+ it 'encrypts the command and finds the documents' do
156
+ expect(result).to eq(2)
157
+ end
158
+
159
+ context 'with bypass_auto_encryption=true' do
160
+ include_context 'bypass auto encryption'
161
+
162
+ it 'does not encrypt the command' do
163
+ expect(result).to eq(0)
164
+ end
165
+ end
166
+ end
167
+
168
+ it_behaves_like 'an encrypted command'
169
+ end
170
+
171
+ describe '#distinct' do
172
+ shared_examples 'it performs an encrypted command' do
173
+ include_context 'encrypted document in collection'
174
+
175
+ let(:result) { encryption_client[:users].distinct(:ssn) }
176
+
177
+ it 'decrypts the SSN field' do
178
+ expect(result.length).to eq(1)
179
+ expect(result).to include(ssn)
180
+ end
181
+
182
+ context 'with bypass_auto_encryption=true' do
183
+ include_context 'bypass auto encryption'
184
+
185
+ it 'still decrypts the SSN field' do
186
+ expect(result.length).to eq(1)
187
+ expect(result).to include(ssn)
188
+ end
189
+ end
190
+ end
191
+
192
+ it_behaves_like 'an encrypted command'
193
+ end
194
+
195
+ describe '#delete_one' do
196
+ shared_examples 'it performs an encrypted command' do
197
+ include_context 'encrypted document in collection'
198
+
199
+ let(:result) { encryption_client[:users].delete_one(ssn: ssn) }
200
+
201
+ it 'encrypts the SSN field' do
202
+ expect(result.deleted_count).to eq(1)
203
+ end
204
+
205
+ context 'with bypass_auto_encryption=true' do
206
+ include_context 'bypass auto encryption'
207
+
208
+ it 'does not encrypt the SSN field' do
209
+ expect(result.deleted_count).to eq(0)
210
+ end
211
+ end
212
+ end
213
+
214
+ it_behaves_like 'an encrypted command'
215
+ end
216
+
217
+ describe '#delete_many' do
218
+ shared_examples 'it performs an encrypted command' do
219
+ include_context 'multiple encrypted documents in collection'
220
+
221
+ let(:result) { encryption_client[:users].delete_many(ssn: ssn) }
222
+
223
+ it 'decrypts the SSN field' do
224
+ expect(result.deleted_count).to eq(2)
225
+ end
226
+
227
+ context 'with bypass_auto_encryption=true' do
228
+ include_context 'bypass auto encryption'
229
+
230
+ it 'does not encrypt the SSN field' do
231
+ expect(result.deleted_count).to eq(0)
232
+ end
233
+ end
234
+ end
235
+
236
+ it_behaves_like 'an encrypted command'
237
+ end
238
+
239
+ describe '#find' do
240
+ shared_examples 'it performs an encrypted command' do
241
+ include_context 'encrypted document in collection'
242
+
243
+ let(:result) { encryption_client[:users].find(ssn: ssn).first }
244
+
245
+ it 'encrypts the command and decrypts the response' do
246
+ result.should_not be_nil
247
+ expect(result['ssn']).to eq(ssn)
248
+ end
249
+
250
+ context 'when bypass_auto_encryption=true' do
251
+ include_context 'bypass auto encryption'
252
+
253
+ it 'does not encrypt the command' do
254
+ expect(result).to be_nil
255
+ end
256
+ end
257
+ end
258
+
259
+ it_behaves_like 'an encrypted command'
260
+ end
261
+
262
+ describe '#find_one_and_delete' do
263
+ shared_examples 'it performs an encrypted command' do
264
+ include_context 'encrypted document in collection'
265
+
266
+ let(:result) { encryption_client[:users].find_one_and_delete(ssn: ssn) }
267
+
268
+ it 'encrypts the command and decrypts the response' do
269
+ expect(result['ssn']).to eq(ssn)
270
+ end
271
+
272
+ context 'when bypass_auto_encryption=true' do
273
+ include_context 'bypass auto encryption'
274
+
275
+ it 'does not encrypt the command' do
276
+ expect(result).to be_nil
277
+ end
278
+
279
+ it 'still decrypts the command' do
280
+ result = encryption_client[:users].find_one_and_delete(ssn: encrypted_ssn_binary)
281
+ expect(result['ssn']).to eq(ssn)
282
+ end
283
+ end
284
+ end
285
+
286
+ it_behaves_like 'an encrypted command'
287
+ end
288
+
289
+ describe '#find_one_and_replace' do
290
+ shared_examples 'it performs an encrypted command' do
291
+ let(:name) { 'Alan Turing' }
292
+
293
+ context 'with :return_document => :before' do
294
+ include_context 'encrypted document in collection'
295
+
296
+ let(:result) do
297
+ encryption_client[:users].find_one_and_replace(
298
+ { ssn: ssn },
299
+ { name: name },
300
+ return_document: :before
301
+ )
302
+ end
303
+
304
+ it 'encrypts the command and decrypts the response, returning original document' do
305
+ expect(result['ssn']).to eq(ssn)
306
+
307
+ documents = client[:users].find
308
+ expect(documents.count).to eq(1)
309
+ expect(documents.first['ssn']).to be_nil
310
+ end
311
+ end
312
+
313
+ context 'with :return_document => :after' do
314
+ before do
315
+ client[:users].insert_one(name: name)
316
+ end
317
+
318
+ let(:result) do
319
+ encryption_client[:users].find_one_and_replace(
320
+ { name: name },
321
+ { ssn: ssn },
322
+ return_document: :after
323
+ )
324
+ end
325
+
326
+ it 'encrypts the command and decrypts the response, returning new document' do
327
+ expect(result['ssn']).to eq(ssn)
328
+
329
+ documents = client[:users].find
330
+ expect(documents.count).to eq(1)
331
+ expect(documents.first['ssn']).to eq(encrypted_ssn_binary)
332
+ end
333
+ end
334
+
335
+ context 'when bypass_auto_encryption=true' do
336
+ include_context 'bypass auto encryption'
337
+ include_context 'encrypted document in collection'
338
+
339
+ let(:result) do
340
+ encryption_client[:users].find_one_and_replace(
341
+ { ssn: encrypted_ssn_binary },
342
+ { name: name },
343
+ :return_document => :before
344
+ )
345
+ end
346
+
347
+ it 'does not encrypt the command but still decrypts the response, returning original document' do
348
+ expect(result['ssn']).to eq(ssn)
349
+
350
+ documents = client[:users].find
351
+ expect(documents.count).to eq(1)
352
+ expect(documents.first['ssn']).to be_nil
353
+ end
354
+ end
355
+ end
356
+
357
+ it_behaves_like 'an encrypted command'
358
+ end
359
+
360
+ describe '#find_one_and_update' do
361
+ shared_examples 'it performs an encrypted command' do
362
+ include_context 'encrypted document in collection'
363
+
364
+ let(:name) { 'Alan Turing' }
365
+
366
+ let(:result) do
367
+ encryption_client[:users].find_one_and_update(
368
+ { ssn: ssn },
369
+ { name: name }
370
+ )
371
+ end
372
+
373
+ it 'encrypts the command and decrypts the response' do
374
+ expect(result['ssn']).to eq(ssn)
375
+
376
+ documents = client[:users].find
377
+ expect(documents.count).to eq(1)
378
+ expect(documents.first['ssn']).to be_nil
379
+ end
380
+
381
+ context 'with bypass_auto_encryption=true' do
382
+ include_context 'bypass auto encryption'
383
+
384
+ it 'does not encrypt the command' do
385
+ expect(result).to be_nil
386
+ end
387
+
388
+ it 'still decrypts the response' do
389
+ # Query using the encrypted ssn value so the find will succeed
390
+ result = encryption_client[:users].find_one_and_update(
391
+ { ssn: encrypted_ssn_binary },
392
+ { name: name }
393
+ )
394
+
395
+ expect(result['ssn']).to eq(ssn)
396
+ end
397
+ end
398
+ end
399
+
400
+ it_behaves_like 'an encrypted command'
401
+ end
402
+
403
+ describe '#insert_one' do
404
+ let(:query) { { ssn: ssn } }
405
+ let(:result) { encryption_client[:users].insert_one(query) }
406
+
407
+ shared_examples 'it performs an encrypted command' do
408
+ it 'encrypts the ssn field' do
409
+ expect(result).to be_ok
410
+ expect(result.inserted_ids.length).to eq(1)
411
+
412
+ id = result.inserted_ids.first
413
+
414
+ document = client[:users].find(_id: id).first
415
+ document.should_not be_nil
416
+ expect(document['ssn']).to eq(encrypted_ssn_binary)
417
+ end
418
+ end
419
+
420
+ shared_examples 'it obeys bypass_auto_encryption option' do
421
+ include_context 'bypass auto encryption'
422
+
423
+ it 'does not encrypt the command' do
424
+ result = encryption_client[:users].insert_one(ssn: ssn)
425
+ expect(result).to be_ok
426
+ expect(result.inserted_ids.length).to eq(1)
427
+
428
+ id = result.inserted_ids.first
429
+
430
+ document = client[:users].find(_id: id).first
431
+ expect(document['ssn']).to eq(ssn)
432
+ end
433
+ end
434
+
435
+ it_behaves_like 'an encrypted command'
436
+
437
+ context 'with jsonSchema in schema_map option' do
438
+ include_context 'schema map in client options'
439
+
440
+ context 'with AWS KMS provider' do
441
+ include_context 'with AWS kms_providers'
442
+ it_behaves_like 'it obeys bypass_auto_encryption option'
443
+ end
444
+
445
+ context 'with local KMS provider and ' do
446
+ include_context 'with local kms_providers'
447
+ it_behaves_like 'it obeys bypass_auto_encryption option'
448
+ end
449
+ end
450
+
451
+ context 'with schema_map client option pointing to wrong collection' do
452
+ let(:local_schema) { { 'wrong_db.wrong_coll' => schema_map } }
453
+
454
+ include_context 'with local kms_providers'
455
+
456
+ it 'does not raise an exception but doesn\'t encrypt either' do
457
+ expect do
458
+ result
459
+ end.not_to raise_error
460
+
461
+ expect(result).to be_ok
462
+ id = result.inserted_ids.first
463
+
464
+ document = client[:users].find(_id: id).first
465
+ document.should_not be_nil
466
+ # Document was not encrypted
467
+ expect(document['ssn']).to eq(ssn)
468
+ end
469
+ end
470
+
471
+ context 'encrypting using key alt name' do
472
+ include_context 'schema map in client options'
473
+
474
+ let(:query) { { ssn: ssn, altname: key_alt_name } }
475
+
476
+ context 'with AWS KMS provider' do
477
+ include_context 'with AWS kms_providers and key alt names'
478
+ it 'encrypts the ssn field' do
479
+ expect(result).to be_ok
480
+ expect(result.inserted_ids.length).to eq(1)
481
+
482
+ id = result.inserted_ids.first
483
+
484
+ document = client[:users].find(_id: id).first
485
+ document.should_not be_nil
486
+ # Auto-encryption with key alt names only works with random encryption,
487
+ # so it will not generate the same result on every test run.
488
+ expect(document['ssn']).to be_ciphertext
489
+ end
490
+ end
491
+
492
+ context 'with local KMS provider' do
493
+ include_context 'with local kms_providers and key alt names'
494
+ it 'encrypts the ssn field' do
495
+ expect(result).to be_ok
496
+ expect(result.inserted_ids.length).to eq(1)
497
+
498
+ id = result.inserted_ids.first
499
+
500
+ document = client[:users].find(_id: id).first
501
+ document.should_not be_nil
502
+ # Auto-encryption with key alt names only works with random encryption,
503
+ # so it will not generate the same result on every test run.
504
+ expect(document['ssn']).to be_a_kind_of(BSON::Binary)
505
+ end
506
+ end
507
+ end
508
+ end
509
+
510
+ describe '#replace_one' do
511
+ shared_examples 'it performs an encrypted command' do
512
+ include_context 'encrypted document in collection'
513
+
514
+ let(:replacement_ssn) { '098-765-4321' }
515
+
516
+ let(:result) do
517
+ encryption_client[:users].replace_one(
518
+ { ssn: ssn },
519
+ { ssn: replacement_ssn }
520
+ )
521
+ end
522
+
523
+ it 'encrypts the ssn field' do
524
+ expect(result.modified_count).to eq(1)
525
+
526
+ find_result = encryption_client[:users].find(ssn: '098-765-4321')
527
+ expect(find_result.count).to eq(1)
528
+ end
529
+
530
+ context 'with bypass_auto_encryption=true' do
531
+ include_context 'bypass auto encryption'
532
+
533
+ it 'does not encrypt the command' do
534
+ expect(result.modified_count).to eq(0)
535
+ end
536
+ end
537
+ end
538
+
539
+ it_behaves_like 'an encrypted command'
540
+ end
541
+
542
+ describe '#update_one' do
543
+ shared_examples 'it performs an encrypted command' do
544
+ include_context 'encrypted document in collection'
545
+
546
+ let(:result) do
547
+ encryption_client[:users].update_one({ ssn: ssn }, { ssn: '098-765-4321' })
548
+ end
549
+
550
+ it 'encrypts the ssn field' do
551
+ expect(result.n).to eq(1)
552
+
553
+ find_result = encryption_client[:users].find(ssn: '098-765-4321')
554
+ expect(find_result.count).to eq(1)
555
+ end
556
+
557
+ context 'with bypass_auto_encryption=true' do
558
+ include_context 'bypass auto encryption'
559
+
560
+ it 'does not encrypt the command' do
561
+ expect(result.n).to eq(0)
562
+ end
563
+ end
564
+ end
565
+
566
+ it_behaves_like 'an encrypted command'
567
+ end
568
+
569
+ describe '#update_many' do
570
+ shared_examples 'it performs an encrypted command' do
571
+ before do
572
+ client[:users].insert_one(ssn: encrypted_ssn_binary, age: 25)
573
+ client[:users].insert_one(ssn: encrypted_ssn_binary, age: 43)
574
+ end
575
+
576
+ let(:result) do
577
+ encryption_client[:users].update_many({ ssn: ssn }, { "$inc" => { :age => 1 } })
578
+ end
579
+
580
+ it 'encrypts the ssn field' do
581
+ expect(result.n).to eq(2)
582
+
583
+ updated_documents = encryption_client[:users].find(ssn: ssn)
584
+ ages = updated_documents.map { |doc| doc['age'] }
585
+ expect(ages).to include(26)
586
+ expect(ages).to include(44)
587
+ end
588
+
589
+ context 'with bypass_auto_encryption=true' do
590
+ include_context 'bypass auto encryption'
591
+
592
+ it 'does not encrypt the command' do
593
+ expect(result.n).to eq(0)
594
+ end
595
+ end
596
+ end
597
+
598
+ it_behaves_like 'an encrypted command'
599
+ end
600
+ end