mongo 2.11.6 → 2.12.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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