mongo 2.4.3 → 2.5.0.beta
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -2
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +3 -2
- data/lib/mongo/auth/cr.rb +6 -4
- data/lib/mongo/auth/cr/conversation.rb +33 -17
- data/lib/mongo/auth/ldap.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +19 -9
- data/lib/mongo/auth/scram.rb +7 -4
- data/lib/mongo/auth/scram/conversation.rb +62 -24
- data/lib/mongo/auth/user.rb +10 -0
- data/lib/mongo/auth/user/view.rb +44 -22
- data/lib/mongo/auth/x509.rb +4 -2
- data/lib/mongo/auth/x509/conversation.rb +19 -9
- data/lib/mongo/bulk_write.rb +33 -27
- data/lib/mongo/bulk_write/combineable.rb +5 -0
- data/lib/mongo/bulk_write/transformable.rb +2 -0
- data/lib/mongo/bulk_write/validatable.rb +4 -0
- data/lib/mongo/client.rb +123 -12
- data/lib/mongo/cluster.rb +52 -11
- data/lib/mongo/cluster/app_metadata.rb +8 -2
- data/lib/mongo/cluster/cursor_reaper.rb +0 -1
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +114 -27
- data/lib/mongo/collection/view.rb +8 -2
- data/lib/mongo/collection/view/aggregation.rb +11 -7
- data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/find_command.rb +5 -3
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/builder/op_query.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +160 -0
- data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
- data/lib/mongo/collection/view/iterable.rb +11 -10
- data/lib/mongo/collection/view/map_reduce.rb +22 -18
- data/lib/mongo/collection/view/readable.rb +51 -37
- data/lib/mongo/collection/view/writable.rb +72 -40
- data/lib/mongo/cursor.rb +25 -4
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
- data/lib/mongo/database.rb +22 -11
- data/lib/mongo/database/view.rb +16 -12
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_session.rb +36 -0
- data/lib/mongo/error/missing_resume_token.rb +39 -0
- data/lib/mongo/error/operation_failure.rb +17 -0
- data/lib/mongo/error/parser.rb +3 -2
- data/lib/mongo/error/unknown_payload_type.rb +41 -0
- data/lib/mongo/error/unsupported_array_filters.rb +51 -0
- data/lib/mongo/error/unsupported_message_type.rb +23 -0
- data/lib/mongo/grid/fs_bucket.rb +5 -4
- data/lib/mongo/grid/stream/read.rb +3 -2
- data/lib/mongo/grid/stream/write.rb +2 -2
- data/lib/mongo/index/view.rb +35 -25
- data/lib/mongo/monitoring/event/secure.rb +14 -0
- data/lib/mongo/operation.rb +16 -0
- data/lib/mongo/operation/commands.rb +1 -0
- data/lib/mongo/operation/commands/aggregate.rb +9 -5
- data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
- data/lib/mongo/operation/commands/collections_info.rb +6 -6
- data/lib/mongo/operation/commands/command.rb +2 -1
- data/lib/mongo/operation/commands/create.rb +6 -2
- data/lib/mongo/operation/commands/drop.rb +6 -2
- data/lib/mongo/operation/commands/drop_database.rb +6 -2
- data/lib/mongo/operation/commands/explain.rb +27 -0
- data/lib/mongo/operation/commands/explain/result.rb +52 -0
- data/lib/mongo/operation/commands/indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_collections.rb +1 -1
- data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
- data/lib/mongo/operation/commands/map_reduce.rb +8 -4
- data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
- data/lib/mongo/operation/commands/user_query.rb +1 -1
- data/lib/mongo/operation/commands/users_info.rb +6 -2
- data/lib/mongo/operation/executable.rb +4 -1
- data/lib/mongo/operation/read_preference.rb +10 -5
- data/lib/mongo/operation/result.rb +26 -2
- data/lib/mongo/operation/specifiable.rb +13 -1
- data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
- data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
- data/lib/mongo/operation/write/command/create_index.rb +6 -1
- data/lib/mongo/operation/write/command/delete.rb +28 -4
- data/lib/mongo/operation/write/command/drop_index.rb +6 -1
- data/lib/mongo/operation/write/command/insert.rb +22 -18
- data/lib/mongo/operation/write/command/update.rb +24 -9
- data/lib/mongo/operation/write/command/writable.rb +14 -1
- data/lib/mongo/operation/write/insert.rb +4 -1
- data/lib/mongo/operation/write/insert/result.rb +2 -2
- data/lib/mongo/operation/write/update.rb +7 -1
- data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
- data/lib/mongo/protocol.rb +3 -0
- data/lib/mongo/protocol/bit_vector.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +135 -0
- data/lib/mongo/protocol/delete.rb +8 -6
- data/lib/mongo/protocol/get_more.rb +8 -6
- data/lib/mongo/protocol/insert.rb +8 -6
- data/lib/mongo/protocol/kill_cursors.rb +8 -6
- data/lib/mongo/protocol/message.rb +31 -3
- data/lib/mongo/protocol/msg.rb +172 -0
- data/lib/mongo/protocol/query.rb +26 -6
- data/lib/mongo/protocol/registry.rb +76 -0
- data/lib/mongo/protocol/reply.rb +10 -5
- data/lib/mongo/protocol/serializers.rb +224 -0
- data/lib/mongo/protocol/update.rb +8 -6
- data/lib/mongo/retryable.rb +4 -2
- data/lib/mongo/server.rb +6 -3
- data/lib/mongo/server/connectable.rb +1 -1
- data/lib/mongo/server/connection.rb +30 -8
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/description/features.rb +4 -1
- data/lib/mongo/server/monitor.rb +5 -0
- data/lib/mongo/server/monitor/connection.rb +50 -2
- data/lib/mongo/server_selector/nearest.rb +10 -4
- data/lib/mongo/server_selector/primary.rb +20 -0
- data/lib/mongo/server_selector/primary_preferred.rb +10 -4
- data/lib/mongo/server_selector/secondary.rb +10 -4
- data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
- data/lib/mongo/session.rb +180 -0
- data/lib/mongo/session/server_session.rb +73 -0
- data/lib/mongo/session/session_pool.rb +161 -0
- data/lib/mongo/uri.rb +11 -0
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -1
- data/spec/mongo/auth/cr_spec.rb +12 -0
- data/spec/mongo/auth/ldap_spec.rb +2 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
- data/spec/mongo/auth/scram_spec.rb +25 -1
- data/spec/mongo/auth/user/view_spec.rb +268 -76
- data/spec/mongo/auth/x509_spec.rb +2 -0
- data/spec/mongo/bulk_write_spec.rb +435 -5
- data/spec/mongo/client_spec.rb +356 -39
- data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +176 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
- data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
- data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
- data/spec/mongo/collection/view/readable_spec.rb +3 -12
- data/spec/mongo/collection_spec.rb +1048 -42
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
- data/spec/mongo/cursor_spec.rb +2 -2
- data/spec/mongo/database_spec.rb +50 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +146 -8
- data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
- data/spec/mongo/operation/read/query_spec.rb +2 -1
- data/spec/mongo/operation/specifiable_spec.rb +2 -2
- data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
- data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
- data/spec/mongo/operation/write/command/update_spec.rb +93 -10
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +1 -1
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +66 -0
- data/spec/mongo/protocol/delete_spec.rb +14 -0
- data/spec/mongo/protocol/get_more_spec.rb +14 -0
- data/spec/mongo/protocol/insert_spec.rb +14 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
- data/spec/mongo/protocol/msg_spec.rb +499 -0
- data/spec/mongo/protocol/query_spec.rb +45 -0
- data/spec/mongo/protocol/registry_spec.rb +31 -0
- data/spec/mongo/protocol/reply_spec.rb +14 -0
- data/spec/mongo/protocol/update_spec.rb +14 -0
- data/spec/mongo/retryable_spec.rb +6 -2
- data/spec/mongo/sdam_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +4 -2
- data/spec/mongo/server/description_spec.rb +28 -1
- data/spec/mongo/session/server_session_spec.rb +16 -0
- data/spec/mongo/session/session_pool_spec.rb +194 -0
- data/spec/mongo/uri_spec.rb +31 -2
- data/spec/spec_helper.rb +104 -0
- data/spec/support/authorization.rb +6 -1
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/write.rb +6 -1
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
- data/spec/support/sdam/rs/discover_passives.yml +2 -2
- data/spec/support/sdam/rs/discover_primary.yml +1 -1
- data/spec/support/sdam/rs/discover_secondary.yml +1 -1
- data/spec/support/sdam/rs/discovery.yml +4 -4
- data/spec/support/sdam/rs/equal_electionids.yml +1 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
- data/spec/support/sdam/rs/ls_timeout.yml +88 -0
- data/spec/support/sdam/rs/member_reconfig.yml +2 -2
- data/spec/support/sdam/rs/member_standalone.yml +2 -2
- data/spec/support/sdam/rs/new_primary.yml +2 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/non_rs_member.yml +1 -1
- data/spec/support/sdam/rs/normalize_case.yml +1 -1
- data/spec/support/sdam/rs/null_election_id.yml +4 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
- data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/response_from_removed.yml +2 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
- data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
- data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
- data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
- data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
- data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
- data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
- data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
- data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
- data/spec/support/sdam/single/not_ok_response.yml +1 -1
- data/spec/support/sdam/single/standalone_removed.yml +1 -1
- data/spec/support/sdam/single/unavailable_seed.yml +1 -1
- data/spec/support/server_discovery_and_monitoring.rb +4 -0
- data/spec/support/shared/session.rb +236 -0
- metadata +53 -15
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4e52038faa9ef6ff0419d1c5855800d4ce07066
|
4
|
+
data.tar.gz: a7b342d735714530107b7b513ee91c8d071472ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb58160cfaa1676ee31df0fcd375e2cad12953b46ba063b8a5f46c6e9dcbdcbf750a5c299e8b4222b3af57c9a0902c9f64fe4dfc33dc37df689730cf19f88e27
|
7
|
+
data.tar.gz: 97cc226f8bc3fc8fd7bda2d1be3b29be4a8d03f1e444b572dc74008e1276f733a3408851132cef3241df936c4e1613e4bce2ef2b3597e2fb55031ccfed49fb4c
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
�Ca�? @�7��G�I�ͥ'
|
2
|
+
m�OF/�
|
3
|
+
Z�/(詏�v-�v���d�A�e.R%-Ş�O@Y̽͛�W㞧��ȁC�&�E��>qa�*!~7�>�?[�P�k�H��͍���N�:Yg�S�3ͭ�yf�!���0�|�sd�jٯ�z��"�'J7e��V�i¥~V���+J�<AOs�o���m�!�b���([�|k'���� �#jݱr���@�C<MTAv kA旆Ԧ^�f�ӛ��Ñ�� wX���dx
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mongo.rb
CHANGED
@@ -26,17 +26,18 @@ require 'mongo/error'
|
|
26
26
|
require 'mongo/event'
|
27
27
|
require 'mongo/address'
|
28
28
|
require 'mongo/auth'
|
29
|
+
require 'mongo/protocol'
|
29
30
|
require 'mongo/client'
|
30
31
|
require 'mongo/cluster'
|
31
|
-
require 'mongo/collection'
|
32
32
|
require 'mongo/cursor'
|
33
|
+
require 'mongo/collection'
|
33
34
|
require 'mongo/database'
|
34
35
|
require 'mongo/dbref'
|
35
36
|
require 'mongo/grid'
|
36
37
|
require 'mongo/index'
|
37
|
-
require 'mongo/protocol'
|
38
38
|
require 'mongo/server'
|
39
39
|
require 'mongo/server_selector'
|
40
|
+
require 'mongo/session'
|
40
41
|
require 'mongo/socket'
|
41
42
|
require 'mongo/uri'
|
42
43
|
require 'mongo/version'
|
data/lib/mongo/auth/cr.rb
CHANGED
@@ -49,14 +49,16 @@ module Mongo
|
|
49
49
|
#
|
50
50
|
# @param [ Mongo::Connection ] connection The connection to log into.
|
51
51
|
#
|
52
|
-
# @return [ Protocol::
|
52
|
+
# @return [ Protocol::Message ] The authentication response.
|
53
53
|
#
|
54
54
|
# @since 2.0.0
|
55
55
|
def login(connection)
|
56
56
|
conversation = Conversation.new(user)
|
57
|
-
reply = connection.dispatch([ conversation.start ])
|
58
|
-
|
59
|
-
conversation.
|
57
|
+
reply = connection.dispatch([ conversation.start(connection) ])
|
58
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
59
|
+
reply = connection.dispatch([ conversation.continue(reply, connection) ])
|
60
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
61
|
+
conversation.finalize(reply, connection)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
@@ -27,7 +27,7 @@ module Mongo
|
|
27
27
|
# @since 2.0.0
|
28
28
|
LOGIN = { authenticate: 1 }.freeze
|
29
29
|
|
30
|
-
# @return [ Protocol::
|
30
|
+
# @return [ Protocol::Message ] reply The current reply in the
|
31
31
|
# conversation.
|
32
32
|
attr_reader :reply
|
33
33
|
|
@@ -47,20 +47,29 @@ module Mongo
|
|
47
47
|
# @example Continue the conversation.
|
48
48
|
# conversation.continue(reply)
|
49
49
|
#
|
50
|
-
# @param [ Protocol::
|
50
|
+
# @param [ Protocol::Message ] reply The reply of the previous
|
51
51
|
# message.
|
52
|
+
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
52
53
|
#
|
53
54
|
# @return [ Protocol::Query ] The next message to send.
|
54
55
|
#
|
55
56
|
# @since 2.0.0
|
56
|
-
def continue(reply)
|
57
|
+
def continue(reply, connection = nil)
|
57
58
|
validate!(reply)
|
58
|
-
|
59
|
-
user.
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
if connection && connection.features.op_msg_enabled?
|
60
|
+
selector = LOGIN.merge(user: user.name, nonce: nonce, key: user.auth_key(nonce))
|
61
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = user.auth_source
|
62
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
63
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
64
|
+
Protocol::Msg.new([:none], {}, selector)
|
65
|
+
else
|
66
|
+
Protocol::Query.new(
|
67
|
+
user.auth_source,
|
68
|
+
Database::COMMAND,
|
69
|
+
LOGIN.merge(user: user.name, nonce: nonce, key: user.auth_key(nonce)),
|
70
|
+
limit: -1
|
71
|
+
)
|
72
|
+
end
|
64
73
|
end
|
65
74
|
|
66
75
|
# Finalize the CR conversation. This is meant to be iterated until
|
@@ -69,13 +78,13 @@ module Mongo
|
|
69
78
|
# @example Finalize the conversation.
|
70
79
|
# conversation.finalize(reply)
|
71
80
|
#
|
72
|
-
# @param [ Protocol::
|
81
|
+
# @param [ Protocol::Message ] reply The reply of the previous
|
73
82
|
# message.
|
74
83
|
#
|
75
84
|
# @return [ Protocol::Query ] The next message to send.
|
76
85
|
#
|
77
86
|
# @since 2.0.0
|
78
|
-
def finalize(reply)
|
87
|
+
def finalize(reply, connection = nil)
|
79
88
|
validate!(reply)
|
80
89
|
end
|
81
90
|
|
@@ -88,12 +97,19 @@ module Mongo
|
|
88
97
|
# @return [ Protocol::Query ] The first CR conversation message.
|
89
98
|
#
|
90
99
|
# @since 2.0.0
|
91
|
-
def start
|
92
|
-
|
93
|
-
user.auth_source
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
def start(connection = nil)
|
101
|
+
if connection && connection.features.op_msg_enabled?
|
102
|
+
selector = Auth::GET_NONCE.merge(Protocol::Msg::DATABASE_IDENTIFIER => user.auth_source)
|
103
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
104
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
105
|
+
Protocol::Msg.new([:none], {}, selector)
|
106
|
+
else
|
107
|
+
Protocol::Query.new(
|
108
|
+
user.auth_source,
|
109
|
+
Database::COMMAND,
|
110
|
+
Auth::GET_NONCE,
|
111
|
+
limit: -1)
|
112
|
+
end
|
97
113
|
end
|
98
114
|
|
99
115
|
# Create the new conversation.
|
data/lib/mongo/auth/ldap.rb
CHANGED
@@ -49,12 +49,14 @@ module Mongo
|
|
49
49
|
# @param [ Mongo::Connection ] connection The connection to log into.
|
50
50
|
# on.
|
51
51
|
#
|
52
|
-
# @return [ Protocol::
|
52
|
+
# @return [ Protocol::Message ] The authentication response.
|
53
53
|
#
|
54
54
|
# @since 2.0.0
|
55
55
|
def login(connection)
|
56
56
|
conversation = Conversation.new(user)
|
57
|
-
|
57
|
+
reply = connection.dispatch([ conversation.start(connection) ])
|
58
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
59
|
+
conversation.finalize(reply)
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
@@ -27,7 +27,7 @@ module Mongo
|
|
27
27
|
# @since 2.0.0
|
28
28
|
LOGIN = { saslStart: 1, autoAuthorize: 1 }.freeze
|
29
29
|
|
30
|
-
# @return [ Protocol::
|
30
|
+
# @return [ Protocol::Message ] reply The current reply in the
|
31
31
|
# conversation.
|
32
32
|
attr_reader :reply
|
33
33
|
|
@@ -40,7 +40,7 @@ module Mongo
|
|
40
40
|
# @example Finalize the conversation.
|
41
41
|
# conversation.finalize(reply)
|
42
42
|
#
|
43
|
-
# @param [ Protocol::
|
43
|
+
# @param [ Protocol::Message ] reply The reply of the previous
|
44
44
|
# message.
|
45
45
|
#
|
46
46
|
# @return [ Protocol::Query ] The next message to send.
|
@@ -56,16 +56,26 @@ module Mongo
|
|
56
56
|
# @example Start the conversation.
|
57
57
|
# conversation.start
|
58
58
|
#
|
59
|
+
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
60
|
+
#
|
59
61
|
# @return [ Protocol::Query ] The first PLAIN conversation message.
|
60
62
|
#
|
61
63
|
# @since 2.0.0
|
62
|
-
def start
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
def start(connection = nil)
|
65
|
+
if connection && connection.features.op_msg_enabled?
|
66
|
+
selector = LOGIN.merge(payload: payload, mechanism: LDAP::MECHANISM)
|
67
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = Auth::EXTERNAL
|
68
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
69
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
70
|
+
Protocol::Msg.new([:none], {}, selector)
|
71
|
+
else
|
72
|
+
Protocol::Query.new(
|
73
|
+
Auth::EXTERNAL,
|
74
|
+
Database::COMMAND,
|
75
|
+
LOGIN.merge(payload: payload, mechanism: LDAP::MECHANISM),
|
76
|
+
limit: -1
|
77
|
+
)
|
78
|
+
end
|
69
79
|
end
|
70
80
|
|
71
81
|
# Create the new conversation.
|
data/lib/mongo/auth/scram.rb
CHANGED
@@ -50,15 +50,18 @@ module Mongo
|
|
50
50
|
# @param [ Mongo::Connection ] connection The connection to log into.
|
51
51
|
# on.
|
52
52
|
#
|
53
|
-
# @return [ Protocol::
|
53
|
+
# @return [ Protocol::Message ] The authentication response.
|
54
54
|
#
|
55
55
|
# @since 2.0.0
|
56
56
|
def login(connection)
|
57
57
|
conversation = Conversation.new(user)
|
58
|
-
reply = connection.dispatch([ conversation.start ])
|
59
|
-
|
58
|
+
reply = connection.dispatch([ conversation.start(connection) ])
|
59
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
60
|
+
reply = connection.dispatch([ conversation.continue(reply, connection) ])
|
61
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
60
62
|
until reply.documents[0][Conversation::DONE]
|
61
|
-
reply = connection.dispatch([ conversation.finalize(reply) ])
|
63
|
+
reply = connection.dispatch([ conversation.finalize(reply, connection) ])
|
64
|
+
connection.update_cluster_time(Operation::Result.new(reply))
|
62
65
|
end
|
63
66
|
reply
|
64
67
|
end
|
@@ -88,7 +88,7 @@ module Mongo
|
|
88
88
|
# @return [ String ] nonce The initial user nonce.
|
89
89
|
attr_reader :nonce
|
90
90
|
|
91
|
-
# @return [ Protocol::
|
91
|
+
# @return [ Protocol::Message ] reply The current reply in the
|
92
92
|
# conversation.
|
93
93
|
attr_reader :reply
|
94
94
|
|
@@ -102,20 +102,36 @@ module Mongo
|
|
102
102
|
# @example Continue the conversation.
|
103
103
|
# conversation.continue(reply)
|
104
104
|
#
|
105
|
-
# @param [ Protocol::
|
105
|
+
# @param [ Protocol::Message ] reply The reply of the previous
|
106
106
|
# message.
|
107
|
+
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
107
108
|
#
|
108
109
|
# @return [ Protocol::Query ] The next message to send.
|
109
110
|
#
|
110
111
|
# @since 2.0.0
|
111
|
-
def continue(reply)
|
112
|
+
def continue(reply, connection = nil)
|
112
113
|
validate_first_message!(reply)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
114
|
+
|
115
|
+
# The salted password needs to be calculated now; otherwise, if the
|
116
|
+
# client key is cached from a previous authentication, the salt in the
|
117
|
+
# reply will no longer be available for when the salted password is
|
118
|
+
# needed to calculate the server key.
|
119
|
+
salted_password
|
120
|
+
|
121
|
+
if connection && connection.features.op_msg_enabled?
|
122
|
+
selector = CLIENT_CONTINUE_MESSAGE.merge(payload: client_final_message, conversationId: id)
|
123
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = user.auth_source
|
124
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
125
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
126
|
+
Protocol::Msg.new([:none], {}, selector)
|
127
|
+
else
|
128
|
+
Protocol::Query.new(
|
129
|
+
user.auth_source,
|
130
|
+
Database::COMMAND,
|
131
|
+
CLIENT_CONTINUE_MESSAGE.merge(payload: client_final_message, conversationId: id),
|
132
|
+
limit: -1
|
133
|
+
)
|
134
|
+
end
|
119
135
|
end
|
120
136
|
|
121
137
|
# Finalize the SCRAM conversation. This is meant to be iterated until
|
@@ -124,20 +140,29 @@ module Mongo
|
|
124
140
|
# @example Finalize the conversation.
|
125
141
|
# conversation.finalize(reply)
|
126
142
|
#
|
127
|
-
# @param [ Protocol::
|
143
|
+
# @param [ Protocol::Message ] reply The reply of the previous
|
128
144
|
# message.
|
145
|
+
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
129
146
|
#
|
130
147
|
# @return [ Protocol::Query ] The next message to send.
|
131
148
|
#
|
132
149
|
# @since 2.0.0
|
133
|
-
def finalize(reply)
|
150
|
+
def finalize(reply, connection = nil)
|
134
151
|
validate_final_message!(reply)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
152
|
+
if connection && connection.features.op_msg_enabled?
|
153
|
+
selector = CLIENT_CONTINUE_MESSAGE.merge(payload: client_empty_message, conversationId: id)
|
154
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = user.auth_source
|
155
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
156
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
157
|
+
Protocol::Msg.new([:none], {}, selector)
|
158
|
+
else
|
159
|
+
Protocol::Query.new(
|
160
|
+
user.auth_source,
|
161
|
+
Database::COMMAND,
|
162
|
+
CLIENT_CONTINUE_MESSAGE.merge(payload: client_empty_message, conversationId: id),
|
163
|
+
limit: -1
|
164
|
+
)
|
165
|
+
end
|
141
166
|
end
|
142
167
|
|
143
168
|
# Start the SCRAM conversation. This returns the first message that
|
@@ -146,16 +171,26 @@ module Mongo
|
|
146
171
|
# @example Start the conversation.
|
147
172
|
# conversation.start
|
148
173
|
#
|
174
|
+
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
175
|
+
#
|
149
176
|
# @return [ Protocol::Query ] The first SCRAM conversation message.
|
150
177
|
#
|
151
178
|
# @since 2.0.0
|
152
|
-
def start
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
179
|
+
def start(connection = nil)
|
180
|
+
if connection && connection.features.op_msg_enabled?
|
181
|
+
selector = CLIENT_FIRST_MESSAGE.merge(payload: client_first_message, mechanism: SCRAM::MECHANISM)
|
182
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = user.auth_source
|
183
|
+
cluster_time = connection.mongos? && connection.cluster_time
|
184
|
+
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
185
|
+
Protocol::Msg.new([:none], {}, selector)
|
186
|
+
else
|
187
|
+
Protocol::Query.new(
|
188
|
+
user.auth_source,
|
189
|
+
Database::COMMAND,
|
190
|
+
CLIENT_FIRST_MESSAGE.merge(payload: client_first_message, mechanism: SCRAM::MECHANISM),
|
191
|
+
limit: -1
|
192
|
+
)
|
193
|
+
end
|
159
194
|
end
|
160
195
|
|
161
196
|
# Get the id of the conversation.
|
@@ -181,6 +216,7 @@ module Mongo
|
|
181
216
|
def initialize(user)
|
182
217
|
@user = user
|
183
218
|
@nonce = SecureRandom.base64
|
219
|
+
@client_key = user.send(:client_key)
|
184
220
|
end
|
185
221
|
|
186
222
|
private
|
@@ -247,6 +283,8 @@ module Mongo
|
|
247
283
|
# @since 2.0.0
|
248
284
|
def client_key
|
249
285
|
@client_key ||= hmac(salted_password, CLIENT_KEY)
|
286
|
+
user.instance_variable_set(:@client_key, @client_key) unless user.send(:client_key)
|
287
|
+
@client_key
|
250
288
|
end
|
251
289
|
|
252
290
|
# Client proof algorithm implementation.
|
data/lib/mongo/auth/user.rb
CHANGED
@@ -131,6 +131,8 @@ module Mongo
|
|
131
131
|
# @option options [ String ] :password The user's password.
|
132
132
|
# @option options [ Symbol ] :auth_mech The authorization mechanism.
|
133
133
|
# @option options [ Array<String>, Array<Hash> ] roles The user roles.
|
134
|
+
# @option options [ String ] :client_key The user's client key cached from a previous
|
135
|
+
# authentication on the same connection.
|
134
136
|
#
|
135
137
|
# @since 2.0.0
|
136
138
|
def initialize(options)
|
@@ -141,6 +143,7 @@ module Mongo
|
|
141
143
|
@mechanism = options[:auth_mech] || :mongodb_cr
|
142
144
|
@auth_mech_properties = options[:auth_mech_properties] || {}
|
143
145
|
@roles = options[:roles] || []
|
146
|
+
@client_key = options[:client_key]
|
144
147
|
end
|
145
148
|
|
146
149
|
# Get the specification for the user, used in creation.
|
@@ -154,6 +157,13 @@ module Mongo
|
|
154
157
|
def spec
|
155
158
|
{ pwd: hashed_password, roles: roles }
|
156
159
|
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# The client key for the user.
|
164
|
+
#
|
165
|
+
# @return [ String ] The client key for the user.
|
166
|
+
attr_reader :client_key
|
157
167
|
end
|
158
168
|
end
|
159
169
|
end
|
data/lib/mongo/auth/user/view.rb
CHANGED
@@ -25,7 +25,7 @@ module Mongo
|
|
25
25
|
# @return [ Database ] database The view's database.
|
26
26
|
attr_reader :database
|
27
27
|
|
28
|
-
def_delegators :database, :cluster, :read_preference
|
28
|
+
def_delegators :database, :cluster, :read_preference, :client
|
29
29
|
def_delegators :cluster, :next_primary
|
30
30
|
|
31
31
|
# Create a new user in the database.
|
@@ -36,15 +36,20 @@ module Mongo
|
|
36
36
|
# @param [ Auth::User, String ] user_or_name The user object or user name.
|
37
37
|
# @param [ Hash ] options The user options.
|
38
38
|
#
|
39
|
+
# @option options [ Session ] :session The session to use for the operation.
|
40
|
+
#
|
39
41
|
# @return [ Result ] The command response.
|
40
42
|
#
|
41
43
|
# @since 2.0.0
|
42
44
|
def create(user_or_name, options = {})
|
43
45
|
user = generate(user_or_name, options)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
client.send(:with_session, options) do |session|
|
47
|
+
Operation::Write::CreateUser.new(
|
48
|
+
user: user,
|
49
|
+
db_name: database.name,
|
50
|
+
session: session
|
51
|
+
).execute(next_primary)
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
# Initialize the new user view.
|
@@ -65,15 +70,21 @@ module Mongo
|
|
65
70
|
# view.remove('user')
|
66
71
|
#
|
67
72
|
# @param [ String ] name The user name.
|
73
|
+
# @param [ Hash ] options The options for the remove operation.
|
74
|
+
#
|
75
|
+
# @option options [ Session ] :session The session to use for the operation.
|
68
76
|
#
|
69
77
|
# @return [ Result ] The command response.
|
70
78
|
#
|
71
79
|
# @since 2.0.0
|
72
|
-
def remove(name)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
def remove(name, options = {})
|
81
|
+
client.send(:with_session, options) do |session|
|
82
|
+
Operation::Write::RemoveUser.new(
|
83
|
+
user_name: name,
|
84
|
+
db_name: database.name,
|
85
|
+
session: session
|
86
|
+
).execute(next_primary)
|
87
|
+
end
|
77
88
|
end
|
78
89
|
|
79
90
|
# Update a user in the database.
|
@@ -84,15 +95,20 @@ module Mongo
|
|
84
95
|
# @param [ Auth::User, String ] user_or_name The user object or user name.
|
85
96
|
# @param [ Hash ] options The user options.
|
86
97
|
#
|
98
|
+
# @option options [ Session ] :session The session to use for the operation.
|
99
|
+
#
|
87
100
|
# @return [ Result ] The response.
|
88
101
|
#
|
89
102
|
# @since 2.0.0
|
90
103
|
def update(user_or_name, options = {})
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
104
|
+
client.send(:with_session, options) do |session|
|
105
|
+
user = generate(user_or_name, options)
|
106
|
+
Operation::Write::UpdateUser.new(
|
107
|
+
user: user,
|
108
|
+
db_name: database.name,
|
109
|
+
session: session
|
110
|
+
).execute(next_primary)
|
111
|
+
end
|
96
112
|
end
|
97
113
|
|
98
114
|
# Get info for a particular user in the database.
|
@@ -101,21 +117,27 @@ module Mongo
|
|
101
117
|
# view.info('emily')
|
102
118
|
#
|
103
119
|
# @param [ String ] name The user name.
|
120
|
+
# @param [ Hash ] options The options for the info operation.
|
121
|
+
#
|
122
|
+
# @option options [ Session ] :session The session to use for the operation.
|
104
123
|
#
|
105
124
|
# @return [ Hash ] A document containing information on a particular user.
|
106
125
|
#
|
107
126
|
# @since 2.1.0
|
108
|
-
def info(name)
|
109
|
-
user_query(name).documents
|
127
|
+
def info(name, options = {})
|
128
|
+
user_query(name, options).documents
|
110
129
|
end
|
111
130
|
|
112
131
|
private
|
113
132
|
|
114
|
-
def user_query(name)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
133
|
+
def user_query(name, options = {})
|
134
|
+
client.send(:with_session, options) do |session|
|
135
|
+
Operation::Commands::UserQuery.new(
|
136
|
+
user_name: name,
|
137
|
+
db_name: database.name,
|
138
|
+
session: session
|
139
|
+
).execute(next_primary)
|
140
|
+
end
|
119
141
|
end
|
120
142
|
|
121
143
|
def generate(user, options)
|