mongo 1.10.2 → 1.11.1
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 +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +43 -9
- data/VERSION +1 -1
- data/lib/mongo.rb +1 -0
- data/lib/mongo/collection.rb +36 -21
- data/lib/mongo/connection/pool.rb +14 -22
- data/lib/mongo/cursor.rb +13 -0
- data/lib/mongo/db.rb +18 -13
- data/lib/mongo/functional.rb +0 -2
- data/lib/mongo/functional/authentication.rb +35 -25
- data/lib/mongo/legacy.rb +4 -4
- data/mongo.gemspec +0 -5
- data/test/functional/authentication_test.rb +3 -2
- data/test/functional/bulk_write_collection_view_test.rb +9 -14
- data/test/functional/client_test.rb +42 -43
- data/test/functional/collection_test.rb +1073 -995
- data/test/functional/collection_writer_test.rb +1 -1
- data/test/functional/cursor_fail_test.rb +3 -9
- data/test/functional/cursor_message_test.rb +14 -15
- data/test/functional/cursor_test.rb +224 -166
- data/test/functional/db_api_test.rb +262 -261
- data/test/functional/db_connection_test.rb +1 -3
- data/test/functional/db_test.rb +116 -115
- data/test/functional/grid_file_system_test.rb +108 -108
- data/test/functional/pool_test.rb +73 -0
- data/test/functional/timeout_test.rb +2 -0
- data/test/helpers/test_unit.rb +146 -11
- data/test/replica_set/authentication_test.rb +4 -2
- data/test/replica_set/basic_test.rb +5 -13
- data/test/replica_set/client_test.rb +8 -6
- data/test/replica_set/complex_connect_test.rb +3 -0
- data/test/replica_set/count_test.rb +2 -0
- data/test/replica_set/cursor_test.rb +5 -0
- data/test/replica_set/insert_test.rb +1 -1
- data/test/replica_set/max_values_test.rb +1 -1
- data/test/replica_set/pinning_test.rb +1 -1
- data/test/replica_set/query_test.rb +1 -1
- data/test/replica_set/read_preference_test.rb +7 -1
- data/test/replica_set/refresh_test.rb +11 -8
- data/test/replica_set/replication_ack_test.rb +2 -1
- data/test/sharded_cluster/basic_test.rb +17 -11
- data/test/shared/authentication/basic_auth_shared.rb +59 -98
- data/test/shared/authentication/bulk_api_auth_shared.rb +11 -21
- data/test/shared/authentication/gssapi_shared.rb +28 -21
- data/test/test_helper.rb +5 -0
- data/test/tools/mongo_config.rb +96 -11
- metadata +4 -5
- metadata.gz.sig +0 -0
- data/lib/mongo/functional/sasl_java.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 047647bfd88def86157a8e4e25df514da21a1364
|
4
|
+
data.tar.gz: 7fd48a7694323f7e4759b94f12058b5e34a6bba4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b360776478001d2b41342764c13dd209954c0bbcf73c5b87dc4f2169d3e42bd27c6650514ca281a1146c33d1d2624edf653cf8ddd51e3ff8f9e37c9bf4505d3
|
7
|
+
data.tar.gz: e4a9d033eb058e0424ecae35599a27be0a7c68e56b2a0557dcbc42a331e940a0c42c73f0b1c1eeb3b76d977fe63a84df5b7310bc001feeb2f8441518e163b2eb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -37,6 +37,17 @@ bundle install
|
|
37
37
|
rake install
|
38
38
|
```
|
39
39
|
|
40
|
+
To be able to use the driver with Kerberos authentication enabled, install the
|
41
|
+
`mongo_kerberos` gem and add it instead of mongo to your application:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
gem install mongo_kerberos
|
45
|
+
```
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
require 'mongo_kerberos'
|
49
|
+
```
|
50
|
+
|
40
51
|
Usage
|
41
52
|
-----
|
42
53
|
Here is a quick example of basic usage for the Ruby driver:
|
@@ -84,10 +95,10 @@ MRI 1.8.7, 1.9.3, 2.0.0<br>JRuby 1.7.x | Windows<br>Linux<br>OS X | x86<br>x64<b
|
|
84
95
|
Support & Feedback
|
85
96
|
-----
|
86
97
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
98
|
+
**Support Channels**
|
99
|
+
|
100
|
+
For issues, questions or feedback related to the Ruby driver, please look into our [support channels](http://www.mongodb.org/about/support).
|
101
|
+
Please do not email any of the Ruby developers directly with issues or questions. You'll get a quicker answer on the [mongodb-user list](http://groups.google.com/group/mongodb-user) Google Group.
|
91
102
|
|
92
103
|
Bugs & Feature Requests
|
93
104
|
-----
|
@@ -100,18 +111,41 @@ Do you have a bug to report or a feature request to make?
|
|
100
111
|
|
101
112
|
When reporting an issue, please keep in mind that all information in JIRA for all driver projects (ex. RUBY, CSHARP, JAVA) and the Core Server (ex. SERVER) project is **PUBLICLY** visible.
|
102
113
|
|
103
|
-
**
|
114
|
+
**HOW TO ASK FOR HELP**
|
104
115
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
116
|
+
Providing enough information so we can reproduce the issue immediately will reduce roundtrip communications and get you a useful response as quickly as possible.
|
117
|
+
That said, please provide the following information when logging an issue:
|
118
|
+
|
119
|
+
1. Environment
|
120
|
+
2. Ruby version, including patch-level
|
121
|
+
3. MongoDB version
|
122
|
+
4. A test case or code snippets
|
123
|
+
5. Stack traces and log data, keeping in mind that this info is public
|
109
124
|
|
110
125
|
**PLEASE DO NOT**
|
111
126
|
|
112
127
|
* Provide any sensitive data or server logs.
|
113
128
|
* Report potential security issues publicly (see 'Security Issues').
|
114
129
|
|
130
|
+
**EXAMPLE BUG REPORT**
|
131
|
+
|
132
|
+
Example taken from [RUBY-775](https://jira.mongodb.org/browse/RUBY-775)
|
133
|
+
|
134
|
+
```
|
135
|
+
There appears to be a recursive locking condition in the replica set connection pooling.
|
136
|
+
|
137
|
+
Environment: AWS Linux 3.10.37-47.135.amzn1.x86_64 / jruby-1.7.12 / JDK java-1.7.0-openjdk-1.7.0.55-2.4.7.1.40.amzn1.x86_64
|
138
|
+
|
139
|
+
Component: Connection Pooling / Replica set
|
140
|
+
|
141
|
+
Here is a stack trace:
|
142
|
+
https://gist.githubusercontent.com/cheald/5ed01172c5b2c9943c87/raw/63075158dac4c78c1775cac8bf84ba3b6537bc1e/gistfile1.txt
|
143
|
+
|
144
|
+
The original lock occurs [here](https://github.com/mongodb/mongo-ruby-driver/blob/1.x-stable/lib/mongo/connection/pool_manager.rb#L60)
|
145
|
+
|
146
|
+
and then the process of reconnecting ends up attempting to resynchronize the same lock [here](https://github.com/mongodb/mongo-ruby-driver/blob/1.x-stable/lib/mongo/connection/pool_manager.rb#L150)
|
147
|
+
```
|
148
|
+
|
115
149
|
Security Issues
|
116
150
|
-----
|
117
151
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.11.1
|
data/lib/mongo.rb
CHANGED
@@ -64,6 +64,7 @@ module Mongo
|
|
64
64
|
INVALID_BSON = 22
|
65
65
|
WRITE_CONCERN_FAILED = 64
|
66
66
|
MULTIPLE_ERRORS_OCCURRED = 65
|
67
|
+
UNAUTHORIZED = 13
|
67
68
|
|
68
69
|
# mongod/s 2.6 and above return code 59 when a command doesn't exist.
|
69
70
|
# mongod versions previous to 2.6 and mongos 2.4.x return no error code
|
data/lib/mongo/collection.rb
CHANGED
@@ -518,8 +518,9 @@ module Mongo
|
|
518
518
|
# @option opts [Boolean] :unique (false) if true, this index will enforce a uniqueness constraint.
|
519
519
|
# @option opts [Boolean] :background (false) indicate that the index should be built in the background. This
|
520
520
|
# feature is only available in MongoDB >= 1.3.2.
|
521
|
-
# @option opts [Boolean] :drop_dups (nil) If creating a unique index on a collection with
|
522
|
-
# this option will keep the first document the database indexes and drop all subsequent
|
521
|
+
# @option opts [Boolean] :drop_dups (nil) (DEPRECATED) If creating a unique index on a collection with
|
522
|
+
# pre-existing records, this option will keep the first document the database indexes and drop all subsequent
|
523
|
+
# with duplicate values.
|
523
524
|
# @option opts [Integer] :bucket_size (nil) For use with geoHaystack indexes. Number of documents to group
|
524
525
|
# together within a certain proximity to a given longitude and latitude.
|
525
526
|
# @option opts [Integer] :min (nil) specify the minimum longitude and latitude for a geo index.
|
@@ -545,15 +546,19 @@ module Mongo
|
|
545
546
|
# @example A geospatial index with alternate longitude and latitude:
|
546
547
|
# @restaurants.create_index([['location', Mongo::GEO2D]], :min => 500, :max => 500)
|
547
548
|
#
|
549
|
+
# @note The :drop_dups option is no longer supported by MongoDB starting with server version 2.7.5.
|
550
|
+
# The option is silently ignored by the server and unique index builds using the option will
|
551
|
+
# fail if a duplicate value is detected.
|
552
|
+
#
|
548
553
|
# @return [String] the name of the index created.
|
549
554
|
def create_index(spec, opts={})
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
name
|
555
|
-
name
|
556
|
-
generate_indexes(field_spec, name,
|
555
|
+
options = opts.dup
|
556
|
+
options[:dropDups] = options.delete(:drop_dups) if options[:drop_dups]
|
557
|
+
options[:bucketSize] = options.delete(:bucket_size) if options[:bucket_size]
|
558
|
+
field_spec = parse_index_spec(spec)
|
559
|
+
name = options.delete(:name) || generate_index_name(field_spec)
|
560
|
+
name = name.to_s if name
|
561
|
+
generate_indexes(field_spec, name, options)
|
557
562
|
name
|
558
563
|
end
|
559
564
|
|
@@ -572,17 +577,22 @@ module Mongo
|
|
572
577
|
# Time t+10min : @posts.ensure_index(:subject => Mongo::ASCENDING) -- calls create_index and
|
573
578
|
# resets the 5 minute counter
|
574
579
|
#
|
580
|
+
# @note The :drop_dups option is no longer supported by MongoDB starting with server version 2.7.5.
|
581
|
+
# The option is silently ignored by the server and unique index builds using the option will
|
582
|
+
# fail if a duplicate value is detected.
|
583
|
+
#
|
575
584
|
# @return [String] the name of the index.
|
576
585
|
def ensure_index(spec, opts={})
|
577
|
-
now
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
name
|
586
|
+
now = Time.now.utc.to_i
|
587
|
+
options = opts.dup
|
588
|
+
options[:dropDups] = options.delete(:drop_dups) if options[:drop_dups]
|
589
|
+
options[:bucketSize] = options.delete(:bucket_size) if options[:bucket_size]
|
590
|
+
field_spec = parse_index_spec(spec)
|
591
|
+
name = options.delete(:name) || generate_index_name(field_spec)
|
592
|
+
name = name.to_s if name
|
583
593
|
|
584
594
|
if !@cache[name] || @cache[name] <= now
|
585
|
-
generate_indexes(field_spec, name,
|
595
|
+
generate_indexes(field_spec, name, options)
|
586
596
|
end
|
587
597
|
|
588
598
|
# Reset the cache here in case there are any errors inserting. Best to be safe.
|
@@ -1029,6 +1039,10 @@ module Mongo
|
|
1029
1039
|
# @option opts [Hash] :query ({}) A query selector for filtering the documents counted.
|
1030
1040
|
# @option opts [Integer] :skip (nil) The number of documents to skip.
|
1031
1041
|
# @option opts [Integer] :limit (nil) The number of documents to limit.
|
1042
|
+
# @option opts [String, Array, OrderedHash] :hint hint for query optimizer, usually not necessary if
|
1043
|
+
# using MongoDB > 1.1. This option is only supported with #count in server version > 2.6.
|
1044
|
+
# @option opts [String] :named_hint for specifying a named index as a hint, will be overridden by :hint
|
1045
|
+
# if :hint is also provided. This option is only supported with #count in server version > 2.6.
|
1032
1046
|
# @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
|
1033
1047
|
# more details.
|
1034
1048
|
# @option opts [String] :comment (nil) a comment to include in profiling logs
|
@@ -1036,12 +1050,13 @@ module Mongo
|
|
1036
1050
|
# @return [Integer]
|
1037
1051
|
def count(opts={})
|
1038
1052
|
find(opts[:query],
|
1039
|
-
:skip
|
1040
|
-
:limit
|
1041
|
-
:
|
1042
|
-
:
|
1053
|
+
:skip => opts[:skip],
|
1054
|
+
:limit => opts[:limit],
|
1055
|
+
:named_hint => opts[:named_hint] || @hint,
|
1056
|
+
:hint => opts[:hint] || @hint,
|
1057
|
+
:read => opts[:read],
|
1058
|
+
:comment => opts[:comment]).count(true)
|
1043
1059
|
end
|
1044
|
-
|
1045
1060
|
alias :size :count
|
1046
1061
|
|
1047
1062
|
protected
|
@@ -182,10 +182,6 @@ module Mongo
|
|
182
182
|
raise ConnectionFailure, "Failed to connect to host #{@host} and port #{@port}: #{ex}"
|
183
183
|
end
|
184
184
|
|
185
|
-
# If any saved authentications exist, we want to apply those
|
186
|
-
# when creating new sockets and process logouts.
|
187
|
-
check_auths(socket)
|
188
|
-
|
189
185
|
@sockets << socket
|
190
186
|
@checked_out << socket
|
191
187
|
@thread_ids_to_sockets[Thread.current.object_id] = socket
|
@@ -199,12 +195,8 @@ module Mongo
|
|
199
195
|
#
|
200
196
|
# @deprecated This method has been replaced by Pool#check_auths (private)
|
201
197
|
# and it isn't necessary to ever invoke this method directly.
|
198
|
+
# Authentication of sockets is handled upon checkout and checkin.
|
202
199
|
def authenticate_existing
|
203
|
-
@connection_mutex.synchronize do
|
204
|
-
@sockets.each do |socket|
|
205
|
-
check_auths(socket)
|
206
|
-
end
|
207
|
-
end
|
208
200
|
end
|
209
201
|
|
210
202
|
# Store the logout op for each existing socket to be applied before
|
@@ -212,12 +204,8 @@ module Mongo
|
|
212
204
|
#
|
213
205
|
# @deprecated This method has been replaced by Pool#check_auths (private)
|
214
206
|
# and it isn't necessary to ever invoke this method directly.
|
207
|
+
# Authentication of sockets is handled upon checkout and checkin.
|
215
208
|
def logout_existing(database)
|
216
|
-
@connection_mutex.synchronize do
|
217
|
-
@sockets.each do |socket|
|
218
|
-
check_auths(socket)
|
219
|
-
end
|
220
|
-
end
|
221
209
|
end
|
222
210
|
|
223
211
|
# Checks out the first available socket from the pool.
|
@@ -291,16 +279,20 @@ module Mongo
|
|
291
279
|
end
|
292
280
|
|
293
281
|
if socket
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
282
|
+
if !socket.closed?
|
283
|
+
begin
|
284
|
+
check_auths(socket)
|
285
|
+
return socket
|
286
|
+
rescue ConnectionFailure
|
287
|
+
# Socket failed authentication and will be cleaned up below
|
288
|
+
end
|
301
289
|
end
|
302
290
|
|
303
|
-
|
291
|
+
# Socket was closed from earlier network error, or just now from
|
292
|
+
# a network error when authenticating.
|
293
|
+
@checked_out.delete(socket)
|
294
|
+
@sockets.delete(socket)
|
295
|
+
@thread_ids_to_sockets.delete(Thread.current.object_id)
|
304
296
|
else
|
305
297
|
# Otherwise, wait
|
306
298
|
@queue.wait(@connection_mutex)
|
data/lib/mongo/cursor.rb
CHANGED
@@ -203,7 +203,12 @@ module Mongo
|
|
203
203
|
command.merge!(BSON::OrderedHash["skip", @skip]) if @skip != 0
|
204
204
|
end
|
205
205
|
|
206
|
+
if @hint
|
207
|
+
hint = @hint.is_a?(String) ? @hint : generate_index_name(@hint)
|
208
|
+
end
|
209
|
+
|
206
210
|
command.merge!(BSON::OrderedHash["fields", @fields])
|
211
|
+
command.merge!(BSON::OrderedHash["hint", hint]) if hint
|
207
212
|
|
208
213
|
response = @db.command(command, :read => @read, :comment => @comment)
|
209
214
|
return response['n'].to_i if Mongo::Support.ok?(response)
|
@@ -715,5 +720,13 @@ module Mongo
|
|
715
720
|
def compile_regex?
|
716
721
|
@compile_regex
|
717
722
|
end
|
723
|
+
|
724
|
+
def generate_index_name(spec)
|
725
|
+
indexes = []
|
726
|
+
spec.each_pair do |field, type|
|
727
|
+
indexes.push("#{field}_#{type}")
|
728
|
+
end
|
729
|
+
indexes.join("_")
|
730
|
+
end
|
718
731
|
end
|
719
732
|
end
|
data/lib/mongo/db.rb
CHANGED
@@ -156,7 +156,6 @@ module Mongo
|
|
156
156
|
warn "[DEPRECATED] Disabling the 'save_auth' option no longer has " +
|
157
157
|
"any effect. Please see the API documentation for more details " +
|
158
158
|
"on this change." unless save_auth.nil?
|
159
|
-
|
160
159
|
@client.add_auth(self.name, username, password, source, mechanism, extra)
|
161
160
|
true
|
162
161
|
end
|
@@ -220,19 +219,25 @@ module Mongo
|
|
220
219
|
def add_user(username, password=nil, read_only=false, opts={})
|
221
220
|
begin
|
222
221
|
user_info = command(:usersInfo => username)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
222
|
+
if user_info.key?('users') && !user_info['users'].empty?
|
223
|
+
create_or_update_user(:updateUser, username, password, read_only, opts)
|
224
|
+
else
|
225
|
+
create_or_update_user(:createUser, username, password, read_only, opts)
|
226
|
+
end
|
227
|
+
# MongoDB >= 2.5.3 requires the use of commands to manage users.
|
228
|
+
# "Command not found" error didn't return an error code (59) before
|
229
|
+
# MongoDB 2.4.7 so we assume that a nil error code means the usersInfo
|
230
|
+
# command doesn't exist and we should fall back to the legacy add user code.
|
227
231
|
rescue OperationFailure => ex
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
232
|
+
if Mongo::ErrorCode::COMMAND_NOT_FOUND_CODES.include?(ex.error_code)
|
233
|
+
legacy_add_user(username, password, read_only, opts)
|
234
|
+
elsif ex.error_code == Mongo::ErrorCode::UNAUTHORIZED
|
235
|
+
# In MongoDB > 2.7 the localhost exception was narrowed, and the usersInfo
|
236
|
+
# command is no longer allowed. In this case, add the first user.
|
237
|
+
create_or_update_user(:createUser, username, password, read_only, opts)
|
238
|
+
else
|
239
|
+
raise ex
|
240
|
+
end
|
236
241
|
end
|
237
242
|
end
|
238
243
|
|
data/lib/mongo/functional.rb
CHANGED
@@ -166,12 +166,12 @@ module Mongo
|
|
166
166
|
# @param db_name [String] The database name.
|
167
167
|
# @param opts [Hash] Hash of optional settings and configuration values.
|
168
168
|
#
|
169
|
-
# @option opts [Socket] socket
|
169
|
+
# @option opts [Socket] socket Socket instance to use.
|
170
170
|
#
|
171
171
|
# @raise [MongoDBError] Raised if the logout operation fails.
|
172
172
|
# @return [Boolean] The result of the logout operation.
|
173
173
|
def issue_logout(db_name, opts={})
|
174
|
-
doc =
|
174
|
+
doc = auth_command({:logout => 1}, opts[:socket], db_name).first
|
175
175
|
unless Support.ok?(doc)
|
176
176
|
raise MongoDBError, "Error logging out on DB #{db_name}."
|
177
177
|
end
|
@@ -185,7 +185,7 @@ module Mongo
|
|
185
185
|
# @param auth [Hash] The authentication credentials to be used.
|
186
186
|
# @param opts [Hash] Hash of optional settings and configuration values.
|
187
187
|
#
|
188
|
-
# @option opts [Socket] socket
|
188
|
+
# @option opts [Socket] socket Socket instance to use.
|
189
189
|
#
|
190
190
|
# @raise [AuthenticationError] Raised if the authentication fails.
|
191
191
|
# @return [Boolean] Result of the authentication operation.
|
@@ -217,14 +217,14 @@ module Mongo
|
|
217
217
|
# @param auth [Hash] The authentication credentials to be used.
|
218
218
|
# @param opts [Hash] Hash of optional settings and configuration values.
|
219
219
|
#
|
220
|
-
# @option opts [Socket] socket
|
220
|
+
# @option opts [Socket] socket Socket instance to use.
|
221
221
|
#
|
222
222
|
# @return [Boolean] Result of the authentication operation.
|
223
223
|
#
|
224
224
|
# @private
|
225
225
|
def issue_cr(auth, opts={})
|
226
|
-
|
227
|
-
nonce
|
226
|
+
db_name = auth[:source]
|
227
|
+
nonce = get_nonce(auth[:source], opts)
|
228
228
|
|
229
229
|
# build auth command document
|
230
230
|
cmd = BSON::OrderedHash.new
|
@@ -234,9 +234,7 @@ module Mongo
|
|
234
234
|
cmd['key'] = Authentication.auth_key(auth[:username],
|
235
235
|
auth[:password],
|
236
236
|
nonce)
|
237
|
-
|
238
|
-
database.command(cmd, :check_response => false,
|
239
|
-
:socket => opts[:socket])
|
237
|
+
auth_command(cmd, opts[:socket], db_name).first
|
240
238
|
end
|
241
239
|
|
242
240
|
# Handles issuing authentication commands for the MONGODB-X509 auth mechanism.
|
@@ -246,15 +244,14 @@ module Mongo
|
|
246
244
|
#
|
247
245
|
# @private
|
248
246
|
def issue_x509(auth, opts={})
|
249
|
-
|
247
|
+
db_name = '$external'
|
250
248
|
|
251
249
|
cmd = BSON::OrderedHash.new
|
252
250
|
cmd[:authenticate] = 1
|
253
251
|
cmd[:mechanism] = auth[:mechanism]
|
254
252
|
cmd[:user] = auth[:username]
|
255
253
|
|
256
|
-
|
257
|
-
:socket => opts[:socket])
|
254
|
+
auth_command(cmd, opts[:socket], db_name).first
|
258
255
|
end
|
259
256
|
|
260
257
|
# Handles issuing authentication commands for the PLAIN auth mechanism.
|
@@ -262,14 +259,14 @@ module Mongo
|
|
262
259
|
# @param auth [Hash] The authentication credentials to be used.
|
263
260
|
# @param opts [Hash] Hash of optional settings and configuration values.
|
264
261
|
#
|
265
|
-
# @option opts [Socket] socket
|
262
|
+
# @option opts [Socket] socket Socket instance to use.
|
266
263
|
#
|
267
264
|
# @return [Boolean] Result of the authentication operation.
|
268
265
|
#
|
269
266
|
# @private
|
270
267
|
def issue_plain(auth, opts={})
|
271
|
-
|
272
|
-
payload
|
268
|
+
db_name = auth[:source]
|
269
|
+
payload = "\x00#{auth[:username]}\x00#{auth[:password]}"
|
273
270
|
|
274
271
|
cmd = BSON::OrderedHash.new
|
275
272
|
cmd[:saslStart] = 1
|
@@ -277,8 +274,7 @@ module Mongo
|
|
277
274
|
cmd[:payload] = BSON::Binary.new(payload)
|
278
275
|
cmd[:autoAuthorize] = 1
|
279
276
|
|
280
|
-
|
281
|
-
:socket => opts[:socket])
|
277
|
+
auth_command(cmd, opts[:socket], db_name).first
|
282
278
|
end
|
283
279
|
|
284
280
|
# Handles issuing authentication commands for the GSSAPI auth mechanism.
|
@@ -288,10 +284,7 @@ module Mongo
|
|
288
284
|
#
|
289
285
|
# @private
|
290
286
|
def issue_gssapi(auth, opts={})
|
291
|
-
raise
|
292
|
-
"The #{auth[:mechanism]} authentication mechanism is only supported " +
|
293
|
-
"for JRuby." unless RUBY_PLATFORM =~ /java/
|
294
|
-
Mongo::Sasl::GSSAPI.authenticate(auth[:username], self, opts[:socket], auth[:extra] || {})
|
287
|
+
raise "In order to use Kerberos, please add the mongo-kerberos gem to your dependencies"
|
295
288
|
end
|
296
289
|
|
297
290
|
# Helper to fetch a nonce value from a given database instance.
|
@@ -299,20 +292,37 @@ module Mongo
|
|
299
292
|
# @param database [Mongo::DB] The DB instance to use for issue the nonce command.
|
300
293
|
# @param opts [Hash] Hash of optional settings and configuration values.
|
301
294
|
#
|
302
|
-
# @option opts [Socket] socket
|
295
|
+
# @option opts [Socket] socket Socket instance to use.
|
303
296
|
#
|
304
297
|
# @raise [MongoDBError] Raised if there is an error executing the command.
|
305
298
|
# @return [String] Returns the nonce value.
|
306
299
|
#
|
307
300
|
# @private
|
308
|
-
def get_nonce(
|
309
|
-
|
310
|
-
|
301
|
+
def get_nonce(db_name, opts={})
|
302
|
+
cmd = BSON::OrderedHash.new
|
303
|
+
cmd[:getnonce] = 1
|
304
|
+
doc = auth_command(cmd, opts[:socket], db_name).first
|
305
|
+
|
311
306
|
unless Support.ok?(doc)
|
312
307
|
raise MongoDBError, "Error retrieving nonce: #{doc}"
|
313
308
|
end
|
314
309
|
doc['nonce']
|
315
310
|
end
|
316
311
|
|
312
|
+
def auth_command(selector, socket, db_name)
|
313
|
+
begin
|
314
|
+
message = build_command_message(db_name, selector)
|
315
|
+
request_id = add_message_headers(message, Mongo::Constants::OP_QUERY)
|
316
|
+
packed_message = message.to_s
|
317
|
+
|
318
|
+
send_message_on_socket(packed_message, socket)
|
319
|
+
receive(socket, request_id).shift
|
320
|
+
rescue OperationFailure => ex
|
321
|
+
return ex.result
|
322
|
+
rescue ConnectionFailure, OperationTimeout => ex
|
323
|
+
socket.close
|
324
|
+
raise ex
|
325
|
+
end
|
326
|
+
end
|
317
327
|
end
|
318
328
|
end
|