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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2f8d74abb00ab2e9753a3918841a7242a83e956c91f88fe5182febd2fba7897
4
- data.tar.gz: 6de9cab3c254bec7adba15f964806188d8eb664100dd0aa1fe0d6608841ae2de
3
+ metadata.gz: 056e2cbfcb67349d4d1c9c530c110e8d27b9a7035b202b52665b8cddc3c5d3f7
4
+ data.tar.gz: cd3752037a07e808bb9c45714546cd9cb450d6cfdae632bb81c09bc269e88b71
5
5
  SHA512:
6
- metadata.gz: 7c1e95f38f68232e57fc3f39195053dfaa7ac1aa1e0b2f80bea847bbaf0db108c671a4cca5ccdb92951822203de784bd4d8152d3721edf7424da43ed20586800
7
- data.tar.gz: 1c7ce8ac18fb2a899166fca64831c9cc18fee6b217f60f0dbfb1006f6b7ef831b34a5d6e7e1a39414b3e1109cb6fc76e0eff90c2a359166b6cfb074bfceedd5a
6
+ metadata.gz: 13e11a08e91b16021e2fbe9663de2e1fe8319f547cebb3c101b6519ab45993eb3abdbbe18f8e48b3b7591a595c448f0cbb6d8077237c69331cbca8dcf6ff3a9f
7
+ data.tar.gz: a1bb9120bac5385a6adf16ee960c3f8529c1c7c075dfd77ada2e9e7370ef4aecd5bbf1a94df3c099966800066db9824158235a2ca69e6e7d3bf0864d0defc426
@@ -1,2 +1,2 @@
1
- '?��iḫ����K�]��f�,VI8>H�썟��*��4�&�OK>4u `+/� Ql
2
- m�2�z��xR��BY��*E�Y8�^���g��J�� �"l�b4&�S�ZE\9�g�>?&/��$Uc �O��$=`�dB\.����~�ѵ�盀Z�Ug��88Q�<O �"`����0B����콰�-�mؑ���c�����~�6!(�w@�l-!�����~�Cڹa��mZ�f�2���1�'S�
1
+ z��$���l��C��$ 6�{᪑m|B{��B�R����1 ��?k��ڛ�ޑ��X����8uX��:��/*"�so E��^��zU�%cD��ƺ���v���/�� �ý'Y� �P����rPV��ho%��3��zK�RYN�0g�������>%�';8�hހx�:����r�N3����M�n�e;�V�F��ш�1�S#ߑ߯�eDr�����H�A�G���7i�@1�Ţ����
2
+ 6
data.tar.gz.sig CHANGED
Binary file
@@ -23,7 +23,7 @@ Environment
23
23
  We recommend using [rbenv](https://github.com/sstephenson/rbenv) to set up
24
24
  the Ruby development and testing environments, though other tools like
25
25
  [RVM](https://rvm.io/) will also work. The driver currently supports
26
- MRI 2.3-2.6 and JRuby 9.2.
26
+ MRI 2.3-2.7 and JRuby 9.2.
27
27
 
28
28
  A MongoDB cluster is required to run the tests. Setup procedures and
29
29
  recommendations for various clusters, as well as how to configure the
@@ -49,6 +49,7 @@ require 'mongo/cluster'
49
49
  require 'mongo/cursor'
50
50
  require 'mongo/collection'
51
51
  require 'mongo/database'
52
+ require 'mongo/crypt'
52
53
  require 'mongo/client' # Purposely out-of-order so that database is loaded first
53
54
  require 'mongo/dbref'
54
55
  require 'mongo/grid'
@@ -58,7 +59,9 @@ require 'mongo/server_selector'
58
59
  require 'mongo/session'
59
60
  require 'mongo/socket'
60
61
  require 'mongo/srv'
62
+ require 'mongo/timeout'
61
63
  require 'mongo/uri'
62
64
  require 'mongo/version'
63
65
  require 'mongo/write_concern'
64
66
  require 'mongo/lint'
67
+ require 'mongo/client_encryption'
@@ -193,11 +193,22 @@ module Mongo
193
193
  connect_timeout: Server::CONNECT_TIMEOUT,
194
194
  }.update(options)
195
195
 
196
+ # When the driver connects to "localhost", it only attempts IPv4
197
+ # connections. When the driver connects to other hosts, it will
198
+ # attempt both IPv4 and IPv6 connections.
196
199
  family = (host == LOCALHOST) ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
197
200
  error = nil
198
- ::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM).each do |info|
201
+ # Sometimes Socket#getaddrinfo returns the same info more than once
202
+ # (multiple identical items in the returned array). It does not make
203
+ # sense to try to connect to the same address more than once, thus
204
+ # eliminate duplicates here.
205
+ infos = ::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM)
206
+ results = infos.map do |info|
207
+ [info[4], info[3]]
208
+ end.uniq
209
+ results.each do |family, address_str|
199
210
  begin
200
- specific_address = FAMILY_MAP[info[4]].new(info[3], port, host)
211
+ specific_address = FAMILY_MAP[family].new(address_str, port, host)
201
212
  socket = specific_address.socket(socket_timeout, ssl_options, options)
202
213
  return socket
203
214
  rescue IOError, SystemCallError, Error::SocketTimeoutError, Error::SocketError => e
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/auth/credential_cache'
15
16
  require 'mongo/auth/cr'
16
17
  require 'mongo/auth/ldap'
17
18
  require 'mongo/auth/scram'
@@ -0,0 +1,51 @@
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 Auth
17
+
18
+ # Cache store for computed SCRAM credentials.
19
+ #
20
+ # @api private
21
+ module CredentialCache
22
+
23
+ class << self
24
+ attr_reader :store
25
+ end
26
+
27
+ module_function def get(key)
28
+ @store ||= {}
29
+ @store[key]
30
+ end
31
+
32
+ module_function def set(key, value)
33
+ @store ||= {}
34
+ @store[key] = value
35
+ end
36
+
37
+ module_function def cache(key)
38
+ value = get(key)
39
+ if value.nil?
40
+ value = yield
41
+ set(key, value)
42
+ end
43
+ value
44
+ end
45
+
46
+ module_function def clear
47
+ @store = {}
48
+ end
49
+ end
50
+ end
51
+ end
@@ -36,6 +36,7 @@ module Mongo
36
36
  # The client key string.
37
37
  #
38
38
  # @since 2.0.0
39
+ # @deprecated
39
40
  CLIENT_KEY = 'Client Key'.freeze
40
41
 
41
42
  # The key for the done field in the responses.
@@ -78,6 +79,7 @@ module Mongo
78
79
  # The server key string.
79
80
  #
80
81
  # @since 2.0.0
82
+ # @deprecated
81
83
  SERVER_KEY = 'Server Key'.freeze
82
84
 
83
85
  # The server signature verifier in the response.
@@ -113,12 +115,6 @@ module Mongo
113
115
  def continue(reply, connection)
114
116
  validate_first_message!(reply, connection.server)
115
117
 
116
- # The salted password needs to be calculated now; otherwise, if the
117
- # client key is cached from a previous authentication, the salt in the
118
- # reply will no longer be available for when the salted password is
119
- # needed to calculate the server key.
120
- salted_password
121
-
122
118
  if connection && connection.features.op_msg_enabled?
123
119
  selector = CLIENT_CONTINUE_MESSAGE.merge(
124
120
  payload: client_final_message,
@@ -234,7 +230,6 @@ module Mongo
234
230
 
235
231
  @user = user
236
232
  @nonce = SecureRandom.base64
237
- @client_key = user.send(:client_key)
238
233
  @mechanism = mechanism
239
234
  end
240
235
 
@@ -301,9 +296,9 @@ module Mongo
301
296
  #
302
297
  # @since 2.0.0
303
298
  def client_key
304
- @client_key ||= hmac(salted_password, CLIENT_KEY)
305
- user.instance_variable_set(:@client_key, @client_key) unless user.send(:client_key)
306
- @client_key
299
+ @client_key ||= CredentialCache.cache(cache_key(:client_key)) do
300
+ hmac(salted_password, 'Client Key')
301
+ end
307
302
  end
308
303
 
309
304
  # Client proof algorithm implementation.
@@ -429,6 +424,11 @@ module Mongo
429
424
  @salt ||= payload_data.match(SALT)[1]
430
425
  end
431
426
 
427
+ # @api private
428
+ def cache_key(*extra)
429
+ [user.password, salt, iterations, @mechanism] + extra
430
+ end
431
+
432
432
  # Salted password algorithm implementation.
433
433
  #
434
434
  # @api private
@@ -437,11 +437,13 @@ module Mongo
437
437
  #
438
438
  # @since 2.0.0
439
439
  def salted_password
440
- @salted_password ||= case @mechanism
441
- when :scram256
442
- hi(user.sasl_prepped_password)
443
- else
444
- hi(user.hashed_password)
440
+ @salted_password ||= CredentialCache.cache(cache_key(:salted_password)) do
441
+ case @mechanism
442
+ when :scram256
443
+ hi(user.sasl_prepped_password)
444
+ else
445
+ hi(user.hashed_password)
446
+ end
445
447
  end
446
448
  end
447
449
 
@@ -453,7 +455,9 @@ module Mongo
453
455
  #
454
456
  # @since 2.0.0
455
457
  def server_key
456
- @server_key ||= hmac(salted_password, SERVER_KEY)
458
+ @server_key ||= CredentialCache.cache(cache_key(:server_key)) do
459
+ hmac(salted_password, 'Server Key')
460
+ end
457
461
  end
458
462
 
459
463
  # Server signature algorithm implementation.
@@ -155,8 +155,6 @@ module Mongo
155
155
  # If :password and :pwd are both specified, :password takes precedence.
156
156
  # @option options [ Symbol ] :auth_mech The authorization mechanism.
157
157
  # @option options [ Array<String>, Array<Hash> ] roles The user roles.
158
- # @option options [ String ] :client_key The user's client key cached from a previous
159
- # authentication on the same connection.
160
158
  #
161
159
  # @since 2.0.0
162
160
  def initialize(options)
@@ -186,7 +184,6 @@ module Mongo
186
184
  end
187
185
  @auth_mech_properties = options[:auth_mech_properties] || {}
188
186
  @roles = options[:roles] || []
189
- @client_key = options[:client_key]
190
187
  end
191
188
 
192
189
  # Get the specification for the user, used in creation.
@@ -207,11 +204,6 @@ module Mongo
207
204
 
208
205
  private
209
206
 
210
- # The client key for the user.
211
- #
212
- # @return [ String ] The client key for the user.
213
- attr_reader :client_key
214
-
215
207
  # Generate default auth source based on the URI and options
216
208
  #
217
209
  # @api private
@@ -50,7 +50,7 @@ module Mongo
50
50
  db_name: database.name,
51
51
  session: session,
52
52
  write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
53
- ).execute(next_primary(nil, session))
53
+ ).execute(next_primary(nil, session), client: client)
54
54
  end
55
55
  end
56
56
 
@@ -87,7 +87,7 @@ module Mongo
87
87
  db_name: database.name,
88
88
  session: session,
89
89
  write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
90
- ).execute(next_primary(nil, session))
90
+ ).execute(next_primary(nil, session), client: client)
91
91
  end
92
92
  end
93
93
 
@@ -113,7 +113,7 @@ module Mongo
113
113
  db_name: database.name,
114
114
  session: session,
115
115
  write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
116
- ).execute(next_primary(nil, session))
116
+ ).execute(next_primary(nil, session), client: client)
117
117
  end
118
118
  end
119
119
 
@@ -142,7 +142,7 @@ module Mongo
142
142
  user_name: name,
143
143
  db_name: database.name,
144
144
  session: session
145
- ).execute(next_primary(nil, session))
145
+ ).execute(next_primary(nil, session), client: client)
146
146
  end
147
147
  end
148
148
 
@@ -122,7 +122,7 @@ module Mongo
122
122
  @thread.join
123
123
  end
124
124
  break
125
- rescue Timeout::Error
125
+ rescue ::Timeout::Error
126
126
  end
127
127
  end
128
128
 
@@ -203,28 +203,28 @@ module Mongo
203
203
 
204
204
  def delete_one(documents, server, operation_id, session, txn_num)
205
205
  spec = base_spec(operation_id, session).merge(:deletes => documents, :txn_num => txn_num)
206
- Operation::Delete.new(spec).bulk_execute(server)
206
+ Operation::Delete.new(spec).bulk_execute(server, client: client)
207
207
  end
208
208
 
209
209
  def delete_many(documents, server, operation_id, session, txn_num)
210
210
  spec = base_spec(operation_id, session).merge(:deletes => documents)
211
- Operation::Delete.new(spec).bulk_execute(server)
211
+ Operation::Delete.new(spec).bulk_execute(server, client: client)
212
212
  end
213
213
 
214
214
  def insert_one(documents, server, operation_id, session, txn_num)
215
215
  spec = base_spec(operation_id, session).merge(:documents => documents, :txn_num => txn_num)
216
- Operation::Insert.new(spec).bulk_execute(server)
216
+ Operation::Insert.new(spec).bulk_execute(server, client: client)
217
217
  end
218
218
 
219
219
  def update_one(documents, server, operation_id, session, txn_num)
220
220
  spec = base_spec(operation_id, session).merge(:updates => documents, :txn_num => txn_num)
221
- Operation::Update.new(spec).bulk_execute(server)
221
+ Operation::Update.new(spec).bulk_execute(server, client: client)
222
222
  end
223
223
  alias :replace_one :update_one
224
224
 
225
225
  def update_many(documents, server, operation_id, session, txn_num)
226
226
  spec = base_spec(operation_id, session).merge(:updates => documents)
227
- Operation::Update.new(spec).bulk_execute(server)
227
+ Operation::Update.new(spec).bulk_execute(server, client: client)
228
228
  end
229
229
  end
230
230
  end
@@ -27,6 +27,7 @@ module Mongo
27
27
  #
28
28
  # @since 2.1.0
29
29
  CRUD_OPTIONS = [
30
+ :auto_encryption_options,
30
31
  :database,
31
32
  :read, :read_concern,
32
33
  :write, :write_concern,
@@ -53,6 +54,7 @@ module Mongo
53
54
  :auth_mech,
54
55
  :auth_mech_properties,
55
56
  :auth_source,
57
+ :auto_encryption_options,
56
58
  :cleanup,
57
59
  :compressors,
58
60
  :connect,
@@ -119,6 +121,10 @@ module Mongo
119
121
  # @return [ Hash ] options The configuration options.
120
122
  attr_reader :options
121
123
 
124
+ # @return [ Mongo::Crypt::AutoEncrypter ] The object that encapsulates
125
+ # auto-encryption behavior
126
+ attr_reader :encrypter
127
+
122
128
  # Delegate command and collections execution to the current database.
123
129
  def_delegators :@database, :command, :collections
124
130
 
@@ -369,6 +375,44 @@ module Mongo
369
375
  # See Ruby's Zlib module for valid levels.
370
376
  # @option options [ Hash ] :resolv_options For internal driver use only.
371
377
  # Options to pass through to Resolv::DNS constructor for SRV lookups.
378
+ # @option options [ Hash ] :auto_encryption_options Auto-encryption related
379
+ # options.
380
+ # - :key_vault_client => Client | nil, a client connected to the MongoDB
381
+ # instance containing the encryption key vault
382
+ # - :key_vault_namespace => String, the namespace of the key vault in the
383
+ # format database.collection
384
+ # - :kms_providers => Hash, A hash of key management service configuration
385
+ # information. Valid hash keys are :local or :aws. There may be more
386
+ # than one kms provider specified.
387
+ # - :schema_map => Hash | nil, JSONSchema for one or more collections
388
+ # specifying which fields should be encrypted.
389
+ # - Note: Schemas supplied in the schema_map only apply to configuring
390
+ # automatic encryption for client side encryption. Other validation
391
+ # rules in the JSON schema will not be enforced by the driver and will
392
+ # result in an error.
393
+ # - Note: Supplying a schema_map provides more security than relying on
394
+ # JSON Schemas obtained from the server. It protects against a
395
+ # malicious server advertising a false JSON Schema, which could trick
396
+ # the client into sending unencrypted data that should be encrypted.
397
+ # - :bypass_auto_encryption => Boolean, when true, disables auto encryption;
398
+ # defaults to false.
399
+ # - :extra_options => Hash | nil, options related to spawning mongocryptd
400
+ # (this part of the API is subject to change).
401
+ #
402
+ # Notes on automatic encryption:
403
+ # - Automatic encryption is an enterprise only feature that only applies
404
+ # to operations on a collection.
405
+ # - Automatic encryption is not supported for operations on a database or
406
+ # view.
407
+ # - Automatic encryption requires the authenticated user to have the
408
+ # listCollections privilege.
409
+ # - At worst, automatic encryption may triple the number of connections
410
+ # used by the Client at any one time.
411
+ # - If automatic encryption fails on an operation, use a MongoClient
412
+ # configured with bypass_auto_encryption: true and use
413
+ # ClientEncryption.encrypt to manually encrypt values.
414
+ # - Enabling Client Side Encryption reduces the maximum write batch size
415
+ # and may have a negative performance impact.
372
416
  #
373
417
  # @since 2.0.0
374
418
  def initialize(addresses_or_uri, options = nil)
@@ -425,11 +469,21 @@ module Mongo
425
469
  sdam_proc.call(self)
426
470
  end
427
471
 
428
- @cluster = Cluster.new(addresses, @monitoring, cluster_options.merge(srv_uri: srv_uri))
472
+ @connect_lock = Mutex.new
473
+ @connect_lock.synchronize do
474
+ @cluster = Cluster.new(addresses, @monitoring,
475
+ cluster_options.merge(srv_uri: srv_uri))
476
+ end
429
477
 
430
478
  # Unset monitoring, it will be taken out of cluster from now on
431
479
  remove_instance_variable('@monitoring')
432
480
 
481
+ if @options[:auto_encryption_options]
482
+ @connect_lock.synchronize do
483
+ build_encrypter
484
+ end
485
+ end
486
+
433
487
  yield(self) if block_given?
434
488
  end
435
489
 
@@ -616,6 +670,8 @@ module Mongo
616
670
  #
617
671
  # @api private
618
672
  def update_options(new_options)
673
+ old_options = @options
674
+
619
675
  validate_new_options!(new_options).tap do |opts|
620
676
  # Our options are frozen
621
677
  options = @options.dup
@@ -625,8 +681,25 @@ module Mongo
625
681
  if options[:write_concern] && opts[:write]
626
682
  options.delete(:write_concern)
627
683
  end
684
+
628
685
  options.update(opts)
629
686
  @options = options.freeze
687
+
688
+ auto_encryption_options_changed =
689
+ @options[:auto_encryption_options] != old_options[:auto_encryption_options]
690
+
691
+ # If there are new auto_encryption_options, create a new encrypter.
692
+ # Otherwise, allow the new client to share an encrypter with the
693
+ # original client.
694
+ #
695
+ # If auto_encryption_options are nil, set @encrypter to nil, but do not
696
+ # close the encrypter because it may still be used by the original client.
697
+ if @options[:auto_encryption_options] && auto_encryption_options_changed
698
+ build_encrypter
699
+ elsif @options[:auto_encryption_options].nil?
700
+ @encrypter = nil
701
+ end
702
+
630
703
  validate_options!
631
704
  validate_authentication_options!
632
705
  end
@@ -664,7 +737,18 @@ module Mongo
664
737
  #
665
738
  # @since 2.1.0
666
739
  def close
667
- @cluster.disconnect!
740
+ @connect_lock.synchronize do
741
+ do_close
742
+ end
743
+ true
744
+ end
745
+
746
+ # Close encrypter and clean up auto-encryption resources.
747
+ #
748
+ # @return [ true ] Always true.
749
+ def close_encrypter
750
+ @encrypter.close if @encrypter
751
+
668
752
  true
669
753
  end
670
754
 
@@ -679,9 +763,16 @@ module Mongo
679
763
  def reconnect
680
764
  addresses = cluster.addresses.map(&:to_s)
681
765
 
682
- @cluster.disconnect! rescue nil
766
+ @connect_lock.synchronize do
767
+ do_close rescue nil
768
+
769
+ @cluster = Cluster.new(addresses, monitoring, cluster_options)
770
+
771
+ if @options[:auto_encryption_options]
772
+ build_encrypter
773
+ end
774
+ end
683
775
 
684
- @cluster = Cluster.new(addresses, monitoring, cluster_options)
685
776
  true
686
777
  end
687
778
 
@@ -805,6 +896,13 @@ module Mongo
805
896
 
806
897
  private
807
898
 
899
+ # Create a new encrypter object using the client's auto encryption options
900
+ def build_encrypter
901
+ @encrypter = Crypt::AutoEncrypter.new(
902
+ @options[:auto_encryption_options].merge(client: self)
903
+ )
904
+ end
905
+
808
906
  # Generate default client options based on the URI and options
809
907
  # passed into the Client constructor.
810
908
  def default_options(options)
@@ -822,6 +920,12 @@ module Mongo
822
920
  end
823
921
  end
824
922
 
923
+ # Implementation for #close, assumes the connect lock is already acquired.
924
+ def do_close
925
+ @cluster.disconnect!
926
+ close_encrypter
927
+ end
928
+
825
929
  # If options[:session] is set, validates that session and returns it.
826
930
  # If deployment supports sessions, creates a new session and returns it.
827
931
  # The session is implicit unless options[:implicit] is given.
@@ -911,7 +1015,11 @@ module Mongo
911
1015
 
912
1016
  if auth_mech.nil?
913
1017
  if user && user.empty?
914
- raise Mongo::Auth::InvalidConfiguration.new('empty username is not supported for default auth mechanism')
1018
+ raise Mongo::Auth::InvalidConfiguration, 'Empty username is not supported for default auth mechanism'
1019
+ end
1020
+
1021
+ if auth_source == ''
1022
+ raise Mongo::Auth::InvalidConfiguration, 'Auth source cannot be empty for default auth mechanism'
915
1023
  end
916
1024
 
917
1025
  return
@@ -922,23 +1030,30 @@ module Mongo
922
1030
  end
923
1031
 
924
1032
  if user.nil? && auth_mech != :mongodb_x509
925
- raise Mongo::Auth::InvalidConfiguration.new("user is required for mechanism #{auth_mech}")
1033
+ raise Mongo::Auth::InvalidConfiguration, "Username is required for auth mechanism #{auth_mech}"
926
1034
  end
927
1035
 
928
1036
  if password.nil? && ![:gssapi, :mongodb_x509].include?(auth_mech)
929
- raise Mongo::Auth::InvalidConfiguration.new("password is required for mechanism #{auth_mech}")
1037
+ raise Mongo::Auth::InvalidConfiguration, "Password is required for auth mechanism #{auth_mech}"
930
1038
  end
931
1039
 
932
1040
  if password && auth_mech == :mongodb_x509
933
- raise Mongo::Auth::InvalidConfiguration.new('password is not supported for mongodb_x509')
1041
+ raise Mongo::Auth::InvalidConfiguration, 'Password is not supported for :mongodb_x509 auth mechanism'
934
1042
  end
935
1043
 
936
- if !['$external', nil].include?(auth_source) && [:gssapi, :mongodb_x509].include?(auth_mech)
937
- raise Mongo::Auth::InvalidConfiguration.new("#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil")
1044
+ if [:gssapi, :mongodb_x509].include?(auth_mech)
1045
+ if !['$external', nil].include?(auth_source)
1046
+ raise Mongo::Auth::InvalidConfiguration, "#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil"
1047
+ end
1048
+ else
1049
+ # Auth source is the database name, and thus cannot be the empty string.
1050
+ if auth_source == ''
1051
+ raise Mongo::Auth::InvalidConfiguration, "Auth source cannot be empty for auth mechanism #{auth_mech}"
1052
+ end
938
1053
  end
939
1054
 
940
1055
  if mech_properties && auth_mech != :gssapi
941
- raise Mongo::Auth::InvalidConfiguration.new("mechanism_properties are not supported for #{auth_mech}")
1056
+ raise Mongo::Auth::InvalidConfiguration, ":mechanism_properties are not supported for auth mechanism #{auth_mech}"
942
1057
  end
943
1058
  end
944
1059