mongo 1.3.0 → 1.12.5
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +122 -271
- data/Rakefile +25 -209
- data/VERSION +1 -0
- data/bin/mongo_console +31 -9
- data/lib/mongo/bulk_write_collection_view.rb +387 -0
- data/lib/mongo/collection.rb +576 -269
- data/lib/mongo/collection_writer.rb +364 -0
- data/lib/mongo/connection/node.rb +249 -0
- data/lib/mongo/connection/pool.rb +340 -0
- data/lib/mongo/connection/pool_manager.rb +320 -0
- data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
- data/lib/mongo/connection/socket/socket_util.rb +37 -0
- data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
- data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
- data/lib/mongo/connection/socket/unix_socket.rb +39 -0
- data/lib/mongo/connection/socket.rb +18 -0
- data/lib/mongo/connection.rb +7 -875
- data/lib/mongo/cursor.rb +403 -117
- data/lib/mongo/db.rb +444 -243
- data/lib/mongo/exception.rb +145 -0
- data/lib/mongo/functional/authentication.rb +455 -0
- data/lib/mongo/functional/logging.rb +85 -0
- data/lib/mongo/functional/read_preference.rb +183 -0
- data/lib/mongo/functional/scram.rb +556 -0
- data/lib/mongo/functional/uri_parser.rb +409 -0
- data/lib/mongo/functional/write_concern.rb +66 -0
- data/lib/mongo/functional.rb +20 -0
- data/lib/mongo/gridfs/grid.rb +30 -24
- data/lib/mongo/gridfs/grid_ext.rb +6 -10
- data/lib/mongo/gridfs/grid_file_system.rb +38 -20
- data/lib/mongo/gridfs/grid_io.rb +84 -75
- data/lib/mongo/gridfs.rb +18 -0
- data/lib/mongo/legacy.rb +140 -0
- data/lib/mongo/mongo_client.rb +697 -0
- data/lib/mongo/mongo_replica_set_client.rb +535 -0
- data/lib/mongo/mongo_sharded_client.rb +159 -0
- data/lib/mongo/networking.rb +372 -0
- data/lib/mongo/{util → utils}/conversions.rb +29 -8
- data/lib/mongo/{util → utils}/core_ext.rb +28 -18
- data/lib/mongo/{util → utils}/server_version.rb +4 -6
- data/lib/mongo/{util → utils}/support.rb +29 -31
- data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
- data/lib/mongo/utils.rb +19 -0
- data/lib/mongo.rb +51 -50
- data/mongo.gemspec +29 -32
- data/test/functional/authentication_test.rb +39 -0
- data/test/functional/bulk_api_stress_test.rb +133 -0
- data/test/functional/bulk_write_collection_view_test.rb +1198 -0
- data/test/functional/client_test.rb +627 -0
- data/test/functional/collection_test.rb +2175 -0
- data/test/functional/collection_writer_test.rb +83 -0
- data/test/{conversions_test.rb → functional/conversions_test.rb} +47 -3
- data/test/functional/cursor_fail_test.rb +57 -0
- data/test/functional/cursor_message_test.rb +56 -0
- data/test/functional/cursor_test.rb +683 -0
- data/test/functional/db_api_test.rb +835 -0
- data/test/functional/db_connection_test.rb +25 -0
- data/test/functional/db_test.rb +348 -0
- data/test/functional/grid_file_system_test.rb +285 -0
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +72 -11
- data/test/{grid_test.rb → functional/grid_test.rb} +88 -15
- data/test/functional/pool_test.rb +136 -0
- data/test/functional/safe_test.rb +98 -0
- data/test/functional/ssl_test.rb +29 -0
- data/test/functional/support_test.rb +62 -0
- data/test/functional/timeout_test.rb +60 -0
- data/test/functional/uri_test.rb +446 -0
- data/test/functional/write_concern_test.rb +118 -0
- data/test/helpers/general.rb +50 -0
- data/test/helpers/test_unit.rb +476 -0
- data/test/replica_set/authentication_test.rb +37 -0
- data/test/replica_set/basic_test.rb +189 -0
- data/test/replica_set/client_test.rb +393 -0
- data/test/replica_set/connection_test.rb +138 -0
- data/test/replica_set/count_test.rb +66 -0
- data/test/replica_set/cursor_test.rb +220 -0
- data/test/replica_set/insert_test.rb +157 -0
- data/test/replica_set/max_values_test.rb +151 -0
- data/test/replica_set/pinning_test.rb +105 -0
- data/test/replica_set/query_test.rb +73 -0
- data/test/replica_set/read_preference_test.rb +219 -0
- data/test/replica_set/refresh_test.rb +211 -0
- data/test/replica_set/replication_ack_test.rb +95 -0
- data/test/replica_set/ssl_test.rb +32 -0
- data/test/sharded_cluster/basic_test.rb +203 -0
- data/test/shared/authentication/basic_auth_shared.rb +260 -0
- data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
- data/test/shared/authentication/gssapi_shared.rb +176 -0
- data/test/shared/authentication/sasl_plain_shared.rb +96 -0
- data/test/shared/authentication/scram_shared.rb +92 -0
- data/test/shared/ssl_shared.rb +235 -0
- data/test/test_helper.rb +53 -94
- data/test/threading/basic_test.rb +120 -0
- data/test/tools/mongo_config.rb +708 -0
- data/test/tools/mongo_config_test.rb +160 -0
- data/test/unit/client_test.rb +381 -0
- data/test/unit/collection_test.rb +89 -53
- data/test/unit/connection_test.rb +282 -32
- data/test/unit/cursor_test.rb +206 -8
- data/test/unit/db_test.rb +55 -13
- data/test/unit/grid_test.rb +43 -16
- data/test/unit/mongo_sharded_client_test.rb +48 -0
- data/test/unit/node_test.rb +93 -0
- data/test/unit/pool_manager_test.rb +111 -0
- data/test/unit/read_pref_test.rb +406 -0
- data/test/unit/read_test.rb +159 -0
- data/test/unit/safe_test.rb +69 -36
- data/test/unit/sharding_pool_manager_test.rb +84 -0
- data/test/unit/write_concern_test.rb +175 -0
- data.tar.gz.sig +3 -0
- metadata +227 -216
- metadata.gz.sig +0 -0
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GridFS.md +0 -158
- data/docs/HISTORY.md +0 -244
- data/docs/RELEASES.md +0 -33
- data/docs/REPLICA_SETS.md +0 -72
- data/docs/TUTORIAL.md +0 -247
- data/docs/WRITE_CONCERN.md +0 -28
- data/lib/mongo/exceptions.rb +0 -71
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/repl_set_connection.rb +0 -342
- data/lib/mongo/test.rb +0 -20
- data/lib/mongo/util/pool.rb +0 -177
- data/lib/mongo/util/uri_parser.rb +0 -185
- data/test/async/collection_test.rb +0 -224
- data/test/async/connection_test.rb +0 -24
- data/test/async/cursor_test.rb +0 -162
- data/test/async/worker_pool_test.rb +0 -99
- data/test/auxillary/1.4_features.rb +0 -166
- data/test/auxillary/authentication_test.rb +0 -68
- data/test/auxillary/autoreconnect_test.rb +0 -41
- data/test/auxillary/fork_test.rb +0 -30
- data/test/auxillary/repl_set_auth_test.rb +0 -58
- data/test/auxillary/slave_connection_test.rb +0 -36
- data/test/auxillary/threaded_authentication_test.rb +0 -101
- data/test/bson/binary_test.rb +0 -15
- data/test/bson/bson_test.rb +0 -649
- data/test/bson/byte_buffer_test.rb +0 -208
- data/test/bson/hash_with_indifferent_access_test.rb +0 -38
- data/test/bson/json_test.rb +0 -17
- data/test/bson/object_id_test.rb +0 -154
- data/test/bson/ordered_hash_test.rb +0 -204
- data/test/bson/timestamp_test.rb +0 -24
- data/test/collection_test.rb +0 -910
- data/test/connection_test.rb +0 -309
- data/test/cursor_fail_test.rb +0 -75
- data/test/cursor_message_test.rb +0 -43
- data/test/cursor_test.rb +0 -483
- data/test/db_api_test.rb +0 -726
- data/test/db_connection_test.rb +0 -15
- data/test/db_test.rb +0 -287
- data/test/grid_file_system_test.rb +0 -243
- data/test/load/resque/load.rb +0 -21
- data/test/load/resque/processor.rb +0 -26
- data/test/load/thin/load.rb +0 -24
- data/test/load/unicorn/load.rb +0 -23
- data/test/load/unicorn/unicorn.rb +0 -29
- data/test/replica_sets/connect_test.rb +0 -94
- data/test/replica_sets/connection_string_test.rb +0 -32
- data/test/replica_sets/count_test.rb +0 -35
- data/test/replica_sets/insert_test.rb +0 -53
- data/test/replica_sets/pooled_insert_test.rb +0 -55
- data/test/replica_sets/query_secondaries.rb +0 -96
- data/test/replica_sets/query_test.rb +0 -51
- data/test/replica_sets/replication_ack_test.rb +0 -66
- data/test/replica_sets/rs_test_helper.rb +0 -27
- data/test/safe_test.rb +0 -68
- data/test/support/hash_with_indifferent_access.rb +0 -186
- data/test/support/keys.rb +0 -45
- data/test/support_test.rb +0 -18
- data/test/threading/threading_with_large_pool_test.rb +0 -90
- data/test/threading_test.rb +0 -87
- data/test/tools/auth_repl_set_manager.rb +0 -14
- data/test/tools/load.rb +0 -58
- data/test/tools/repl_set_manager.rb +0 -266
- data/test/tools/sharding_manager.rb +0 -202
- data/test/tools/test.rb +0 -4
- data/test/unit/pool_test.rb +0 -9
- data/test/unit/repl_set_connection_test.rb +0 -59
- data/test/uri_test.rb +0 -91
@@ -0,0 +1,176 @@
|
|
1
|
+
# Copyright (C) 2009-2013 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 GSSAPITests
|
16
|
+
|
17
|
+
# Tests for the GSSAPI Authentication Mechanism.
|
18
|
+
#
|
19
|
+
# Note: These tests will be skipped automatically unless the test environment
|
20
|
+
# has been configured.
|
21
|
+
#
|
22
|
+
# In order to run these tests, you must be using JRuby and must set the following
|
23
|
+
# environment variables. The realm and KDC are required so that the corresponding
|
24
|
+
# system properties can be set:
|
25
|
+
#
|
26
|
+
# export MONGODB_GSSAPI_HOST='server.domain.com'
|
27
|
+
# export MONGODB_GSSAPI_USER='applicationuser@example.com'
|
28
|
+
# export MONGODB_GSSAPI_REALM='applicationuser@example.com'
|
29
|
+
# export MONGODB_GSSAPI_KDC='SERVER.DOMAIN.COM'
|
30
|
+
#
|
31
|
+
# You must use kinit when on MRI.
|
32
|
+
# You have the option of providing a config file that references a keytab file on JRuby:
|
33
|
+
#
|
34
|
+
# export JAAS_LOGIN_CONFIG_FILE='file:///path/to/config/file'
|
35
|
+
#
|
36
|
+
MONGODB_GSSAPI_HOST = ENV['MONGODB_GSSAPI_HOST']
|
37
|
+
MONGODB_GSSAPI_USER = ENV['MONGODB_GSSAPI_USER']
|
38
|
+
MONGODB_GSSAPI_REALM = ENV['MONGODB_GSSAPI_REALM']
|
39
|
+
MONGODB_GSSAPI_KDC = ENV['MONGODB_GSSAPI_KDC']
|
40
|
+
MONGODB_GSSAPI_PORT = ENV['MONGODB_GSSAPI_PORT'] || '27017'
|
41
|
+
MONGODB_GSSAPI_DB = ENV['MONGODB_GSSAPI_DB']
|
42
|
+
JAAS_LOGIN_CONFIG_FILE = ENV['JAAS_LOGIN_CONFIG_FILE'] # only JRuby
|
43
|
+
|
44
|
+
if ENV.key?('MONGODB_GSSAPI_HOST') && ENV.key?('MONGODB_GSSAPI_USER') &&
|
45
|
+
ENV.key?('MONGODB_GSSAPI_REALM') && ENV.key?('MONGODB_GSSAPI_KDC') &&
|
46
|
+
ENV.key?('MONGODB_GSSAPI_DB')
|
47
|
+
def test_gssapi_authenticate
|
48
|
+
client = Mongo::MongoClient.new(MONGODB_GSSAPI_HOST, MONGODB_GSSAPI_PORT)
|
49
|
+
if client['admin'].command(:isMaster => 1)['setName']
|
50
|
+
client = Mongo::MongoReplicaSetClient.new(["#{MONGODB_GSSAPI_HOST}:#{MONGODB_GSSAPI_PORT}"])
|
51
|
+
end
|
52
|
+
|
53
|
+
set_system_properties
|
54
|
+
db = client[MONGODB_GSSAPI_DB]
|
55
|
+
db.authenticate(MONGODB_GSSAPI_USER, nil, nil, nil, 'GSSAPI')
|
56
|
+
assert db.command(:dbstats => 1)
|
57
|
+
|
58
|
+
threads = []
|
59
|
+
4.times do
|
60
|
+
threads << Thread.new do
|
61
|
+
assert db.command(:dbstats => 1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
threads.each(&:join)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_gssapi_authenticate_uri
|
68
|
+
require 'cgi'
|
69
|
+
set_system_properties
|
70
|
+
username = CGI::escape(ENV['MONGODB_GSSAPI_USER'])
|
71
|
+
uri = "mongodb://#{username}@#{ENV['MONGODB_GSSAPI_HOST']}:#{ENV['MONGODB_GSSAPI_PORT']}/?" +
|
72
|
+
"authMechanism=GSSAPI"
|
73
|
+
client = @client.class.from_uri(uri)
|
74
|
+
assert client[MONGODB_GSSAPI_DB].command(:dbstats => 1)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_wrong_service_name_fails
|
78
|
+
extra_opts = { :service_name => 'example' }
|
79
|
+
client = Mongo::MongoClient.new(MONGODB_GSSAPI_HOST, MONGODB_GSSAPI_PORT)
|
80
|
+
if client['admin'].command(:isMaster => 1)['setName']
|
81
|
+
client = Mongo::MongoReplicaSetClient.new(["#{MONGODB_GSSAPI_HOST}:#{MONGODB_GSSAPI_PORT}"])
|
82
|
+
end
|
83
|
+
|
84
|
+
set_system_properties
|
85
|
+
assert_raise_error Mongo::AuthenticationError do
|
86
|
+
client[MONGODB_GSSAPI_DB].authenticate(MONGODB_GSSAPI_USER, nil, nil, nil, 'GSSAPI', extra_opts)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_wrong_service_name_fails_uri
|
91
|
+
set_system_properties
|
92
|
+
|
93
|
+
require 'cgi'
|
94
|
+
username = CGI::escape(ENV['MONGODB_GSSAPI_USER'])
|
95
|
+
uri = "mongodb://#{username}@#{ENV['MONGODB_GSSAPI_HOST']}:#{ENV['MONGODB_GSSAPI_PORT']}/?" +
|
96
|
+
"authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:example"
|
97
|
+
client = @client.class.from_uri(uri)
|
98
|
+
assert_raise_error Mongo::AuthenticationError do
|
99
|
+
client[MONGODB_GSSAPI_DB].command(:dbstats => 1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_extra_opts
|
104
|
+
extra_opts = { :service_name => 'example', :canonicalize_host_name => true,
|
105
|
+
:service_realm => 'dumdum' }
|
106
|
+
client = Mongo::MongoClient.new(TEST_HOST, MONGODB_GSSAPI_PORT)
|
107
|
+
set_system_properties
|
108
|
+
|
109
|
+
Mongo::Sasl::GSSAPI.expects(:authenticate).with do |username, client, socket, opts|
|
110
|
+
assert_equal opts[:service_name], extra_opts[:service_name]
|
111
|
+
assert_equal opts[:canonicalize_host_name], extra_opts[:canonicalize_host_name]
|
112
|
+
assert_equal opts[:service_realm], extra_opts[:service_realm]
|
113
|
+
[ username, client, socket, opts ]
|
114
|
+
end.returns('ok' => true )
|
115
|
+
client[MONGODB_GSSAPI_DB].authenticate(MONGODB_GSSAPI_USER, nil, nil, nil, 'GSSAPI', extra_opts)
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_extra_opts_uri
|
119
|
+
extra_opts = { :service_name => 'example', :canonicalize_host_name => true,
|
120
|
+
:service_realm => 'dumdum' }
|
121
|
+
set_system_properties
|
122
|
+
|
123
|
+
Mongo::Sasl::GSSAPI.expects(:authenticate).with do |username, client, socket, opts|
|
124
|
+
assert_equal opts[:service_name], extra_opts[:service_name]
|
125
|
+
assert_equal opts[:canonicalize_host_name], extra_opts[:canonicalize_host_name]
|
126
|
+
assert_equal opts[:service_realm], extra_opts[:service_realm]
|
127
|
+
[ username, client, socket, opts ]
|
128
|
+
end.returns('ok' => true)
|
129
|
+
|
130
|
+
require 'cgi'
|
131
|
+
username = CGI::escape(ENV['MONGODB_GSSAPI_USER'])
|
132
|
+
uri = "mongodb://#{username}@#{ENV['MONGODB_GSSAPI_HOST']}:#{ENV['MONGODB_GSSAPI_PORT']}/?" +
|
133
|
+
"authMechanism=GSSAPI&authmechanismproperties=SERVICE_NAME:example," +
|
134
|
+
"CANONICALIZE_HOST_NAME:true,SERVICE_REALM:dumdum"
|
135
|
+
client = @client.class.from_uri(uri)
|
136
|
+
client.expects(:receive_message).returns([[{ 'ok' => 1 }], 1, 1])
|
137
|
+
client[MONGODB_GSSAPI_DB].command(:dbstats => 1)
|
138
|
+
end
|
139
|
+
|
140
|
+
# In order to run this test, you must set the following environment variable:
|
141
|
+
#
|
142
|
+
# export MONGODB_GSSAPI_HOST_IP='---.---.---.---'
|
143
|
+
#
|
144
|
+
if ENV.key?('MONGODB_GSSAPI_HOST_IP')
|
145
|
+
def test_canonicalize_host_name
|
146
|
+
extra_opts = { :canonicalize_host_name => true }
|
147
|
+
set_system_properties
|
148
|
+
client = Mongo::MongoClient.new(ENV['MONGODB_GSSAPI_HOST_IP'], MONGODB_GSSAPI_PORT)
|
149
|
+
|
150
|
+
db = client[MONGODB_GSSAPI_DB]
|
151
|
+
db.authenticate(MONGODB_GSSAPI_USER, nil, nil, nil, 'GSSAPI', extra_opts)
|
152
|
+
assert db.command(:dbstats => 1)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_invalid_extra_options
|
157
|
+
extra_opts = { :invalid => true, :option => true }
|
158
|
+
client = Mongo::MongoClient.new(MONGODB_GSSAPI_HOST)
|
159
|
+
|
160
|
+
assert_raise Mongo::MongoArgumentError do
|
161
|
+
client[MONGODB_GSSAPI_DB].authenticate(MONGODB_GSSAPI_USER, nil, nil, nil, 'GSSAPI', extra_opts)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
def set_system_properties
|
167
|
+
if RUBY_PLATFORM =~ /java/
|
168
|
+
java.lang.System.set_property 'javax.security.auth.useSubjectCredsOnly', 'false'
|
169
|
+
java.lang.System.set_property "java.security.krb5.realm", MONGODB_GSSAPI_REALM
|
170
|
+
java.lang.System.set_property "java.security.krb5.kdc", MONGODB_GSSAPI_KDC
|
171
|
+
java.lang.System.set_property "java.security.auth.login.config", JAAS_LOGIN_CONFIG_FILE if JAAS_LOGIN_CONFIG_FILE
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Copyright (C) 2009-2013 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 SASLPlainTests
|
16
|
+
|
17
|
+
# Tests for the PLAIN (LDAP) Authentication Mechanism.
|
18
|
+
#
|
19
|
+
# Note: These tests will be skipped automatically unless the test environment
|
20
|
+
# has been configured.
|
21
|
+
#
|
22
|
+
# In order to run these tests, set the following environment variables:
|
23
|
+
#
|
24
|
+
# export MONGODB_SASL_HOST='server.domain.com'
|
25
|
+
# export MONGODB_SASL_USER='application%2Fuser%40example.com'
|
26
|
+
# export MONGODB_SASL_PASS='password'
|
27
|
+
#
|
28
|
+
# # optional (defaults to '$external')
|
29
|
+
# export MONGODB_SASL_SOURCE='source_database'
|
30
|
+
#
|
31
|
+
if ENV.key?('MONGODB_SASL_HOST') && ENV.key?('MONGODB_SASL_USER') && ENV.key?('MONGODB_SASL_PASS')
|
32
|
+
|
33
|
+
def test_plain_authenticate
|
34
|
+
replica_set = @client.class.name == 'Mongo::MongoReplicaSetClient'
|
35
|
+
|
36
|
+
# TODO: Remove this once we have a replica set configured for SASL in CI
|
37
|
+
return if ENV.key?('CI') && replica_set
|
38
|
+
|
39
|
+
host = replica_set ? [ENV['MONGODB_SASL_HOST']] : ENV['MONGODB_SASL_HOST']
|
40
|
+
client = @client.class.new(host)
|
41
|
+
source = ENV['MONGODB_SASL_SOURCE'] || '$external'
|
42
|
+
db = client['test']
|
43
|
+
|
44
|
+
# should successfully authenticate
|
45
|
+
assert db.authenticate(ENV['MONGODB_SASL_USER'], ENV['MONGODB_SASL_PASS'], true, source, 'PLAIN')
|
46
|
+
assert client[source].logout
|
47
|
+
|
48
|
+
# should raise on missing password
|
49
|
+
ex = assert_raise Mongo::MongoArgumentError do
|
50
|
+
db.authenticate(ENV['MONGODB_SASL_USER'], nil, true, source, 'PLAIN')
|
51
|
+
end
|
52
|
+
assert_match /username and password are required/, ex.message
|
53
|
+
|
54
|
+
# should raise on invalid password
|
55
|
+
assert_raise Mongo::AuthenticationError do
|
56
|
+
db.authenticate(ENV['MONGODB_SASL_USER'], 'foo', true, source, 'PLAIN')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_plain_authenticate_from_uri
|
61
|
+
source = ENV['MONGODB_SASL_SOURCE'] || '$external'
|
62
|
+
|
63
|
+
uri = "mongodb://#{ENV['MONGODB_SASL_USER']}:#{ENV['MONGODB_SASL_PASS']}@" +
|
64
|
+
"#{ENV['MONGODB_SASL_HOST']}/some_db?authSource=#{source}" +
|
65
|
+
"&authMechanism=PLAIN"
|
66
|
+
|
67
|
+
client = @client.class.from_uri(uri)
|
68
|
+
db = client['test']
|
69
|
+
|
70
|
+
# should be able to checkout a socket (authentication gets applied)
|
71
|
+
assert socket = client.checkout_reader(:mode => :primary)
|
72
|
+
client[source].logout(:socket => socket)
|
73
|
+
client.checkin(socket)
|
74
|
+
|
75
|
+
uri = "mongodb://#{ENV['MONGODB_SASL_USER']}@#{ENV['MONGODB_SASL_HOST']}/" +
|
76
|
+
"some_db?authSource=#{source}&authMechanism=PLAIN"
|
77
|
+
|
78
|
+
# should raise for missing password
|
79
|
+
ex = assert_raise Mongo::MongoArgumentError do
|
80
|
+
client = @client.class.from_uri(uri)
|
81
|
+
end
|
82
|
+
assert_match /username and password are required/, ex.message
|
83
|
+
|
84
|
+
uri = "mongodb://#{ENV['MONGODB_SASL_USER']}:foo@#{ENV['MONGODB_SASL_HOST']}/" +
|
85
|
+
"some_db?authSource=#{source}&authMechanism=PLAIN"
|
86
|
+
|
87
|
+
# should raise for invalid password
|
88
|
+
client = @client.class.from_uri(uri)
|
89
|
+
assert_raise Mongo::AuthenticationError do
|
90
|
+
client.checkout_reader(:mode => :primary)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Copyright (C) 2014 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 SCRAMTests
|
16
|
+
|
17
|
+
def setup_conversation
|
18
|
+
SecureRandom.expects(:base64).returns('NDA2NzU3MDY3MDYwMTgy')
|
19
|
+
@password = Digest::MD5.hexdigest("user:mongo:pencil")
|
20
|
+
@scram = Mongo::Authentication::SCRAM.new({ :username => 'user' }, @password)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_scram_authenticate
|
24
|
+
if @version.to_s > '2.7'
|
25
|
+
@client.clear_auths
|
26
|
+
assert @db.authenticate(TEST_USER, TEST_USER_PWD, nil, 'admin', 'SCRAM-SHA-1')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_scram_conversation_start
|
31
|
+
setup_conversation
|
32
|
+
command = @scram.start
|
33
|
+
assert_equal 1, command['saslStart']
|
34
|
+
assert_equal 'SCRAM-SHA-1', command['mechanism']
|
35
|
+
assert_equal 'n,,n=user,r=NDA2NzU3MDY3MDYwMTgy', command['payload'].to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_scram_conversation_continue
|
39
|
+
setup_conversation
|
40
|
+
payload = BSON::Binary.new(
|
41
|
+
'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
|
42
|
+
)
|
43
|
+
reply = { 'conversationId' => 1, 'done' => false, 'payload' => payload, 'ok' => 1.0 }
|
44
|
+
command = @scram.continue(reply)
|
45
|
+
assert_equal 1, command['saslContinue']
|
46
|
+
assert_equal 1, command['conversationId']
|
47
|
+
assert_equal(
|
48
|
+
'c=biws,r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,p=qYUYNy6SQ9Jucq9rFA9nVgXQdbM=',
|
49
|
+
command['payload'].to_s
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_scram_conversation_continue_with_invalid_nonce
|
54
|
+
setup_conversation
|
55
|
+
payload = BSON::Binary.new(
|
56
|
+
'r=NDA2NzU4MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
|
57
|
+
)
|
58
|
+
reply = { 'conversationId' => 1, 'done' => false, 'payload' => payload, 'ok' => 1.0 }
|
59
|
+
assert_raise_error Mongo::InvalidNonce do
|
60
|
+
@scram.continue(reply)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_scram_conversation_finalize
|
65
|
+
setup_conversation
|
66
|
+
continue_payload = BSON::Binary.new(
|
67
|
+
'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
|
68
|
+
)
|
69
|
+
continue_reply = { 'conversationId' => 1, 'done' => false, 'payload' => continue_payload, 'ok' => 1.0 }
|
70
|
+
@scram.continue(continue_reply)
|
71
|
+
payload = BSON::Binary.new('v=gwo9E8+uifshm7ixj441GvIfuUY=')
|
72
|
+
reply = { 'conversationId' => 1, 'done' => false, 'payload' => payload, 'ok' => 1.0 }
|
73
|
+
command = @scram.finalize(reply)
|
74
|
+
assert_equal 1, command['saslContinue']
|
75
|
+
assert_equal 1, command['conversationId']
|
76
|
+
assert_equal '', command['payload'].to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_scram_conversation_finalize_with_invalid_server_signature
|
80
|
+
setup_conversation
|
81
|
+
continue_payload = BSON::Binary.new(
|
82
|
+
'r=NDA2NzU3MDY3MDYwMTgyt7/+IWaw1HaZZ5NmPJUTWapLpH2Gg+d8,s=AVvQXzAbxweH2RYDICaplw==,i=10000'
|
83
|
+
)
|
84
|
+
continue_reply = { 'conversationId' => 1, 'done' => false, 'payload' => continue_payload, 'ok' => 1.0 }
|
85
|
+
@scram.continue(continue_reply)
|
86
|
+
payload = BSON::Binary.new('v=LQ+8yhQeVL2a3Dh+TDJ7xHz4Srk=')
|
87
|
+
reply = { 'conversationId' => 1, 'done' => false, 'payload' => payload, 'ok' => 1.0 }
|
88
|
+
assert_raise_error Mongo::InvalidSignature do
|
89
|
+
@scram.finalize(reply)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
# Copyright (C) 2009-2013 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 SSLTests
|
16
|
+
include Mongo
|
17
|
+
|
18
|
+
MONGODB_X509_USERNAME = 'CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US'
|
19
|
+
CERT_PATH = "#{Dir.pwd}/test/fixtures/certificates/"
|
20
|
+
CLIENT_CERT = "#{CERT_PATH}client.pem"
|
21
|
+
CLIENT_CERT_PASS = "#{CERT_PATH}password_protected.pem"
|
22
|
+
CA_CERT = "#{CERT_PATH}ca.pem"
|
23
|
+
PASS_PHRASE = ENV['SSL_KEY_PASS_PHRASE']
|
24
|
+
|
25
|
+
def create_client(*args)
|
26
|
+
if @client_class == MongoClient
|
27
|
+
@client_class.new(*args[0], args[1])
|
28
|
+
else
|
29
|
+
@client_class.new(args[0], args[1])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Requires MongoDB not built with SSL
|
34
|
+
#
|
35
|
+
def test_ssl_not_configured
|
36
|
+
assert_raise Mongo::ConnectionTimeoutError do
|
37
|
+
create_client(['localhost', 27017], :connect_timeout => 2, :ssl => true)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# This test doesn't connect, no server config required
|
42
|
+
def test_ssl_configuration
|
43
|
+
# raises when ssl=false and ssl opts specified
|
44
|
+
assert_raise MongoArgumentError do
|
45
|
+
create_client(@connect_info, :connect => false,
|
46
|
+
:ssl => false,
|
47
|
+
:ssl_cert => CLIENT_CERT)
|
48
|
+
end
|
49
|
+
|
50
|
+
# raises when ssl=nil and ssl opts specified
|
51
|
+
assert_raise MongoArgumentError do
|
52
|
+
create_client(@connect_info, :connect => false,
|
53
|
+
:ssl_key => CLIENT_CERT)
|
54
|
+
end
|
55
|
+
|
56
|
+
# raises when verify=true and no ca_cert
|
57
|
+
assert_raise MongoArgumentError do
|
58
|
+
create_client(@connect_info, :connect => false,
|
59
|
+
:ssl => true,
|
60
|
+
:ssl_key => CLIENT_CERT,
|
61
|
+
:ssl_cert => CLIENT_CERT,
|
62
|
+
:ssl_verify => true)
|
63
|
+
end
|
64
|
+
|
65
|
+
# raises when key passphrase is given without key file
|
66
|
+
assert_raise MongoArgumentError do
|
67
|
+
create_client(@connect_info, :connect => false,
|
68
|
+
:ssl => true,
|
69
|
+
:ssl_key_pass_phrase => PASS_PHRASE)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Requires MongoDB built with SSL and the following options:
|
74
|
+
#
|
75
|
+
# mongod --dbpath /path/to/data/directory --sslOnNormalPorts \
|
76
|
+
# --sslPEMKeyFile /path/to/server.pem \
|
77
|
+
# --sslCAFile /path/to/ca.pem \
|
78
|
+
# --sslCRLFile /path/to/crl.pem \
|
79
|
+
# --sslWeakCertificateValidation
|
80
|
+
#
|
81
|
+
# Make sure you have 'server' as an alias for localhost in /etc/hosts
|
82
|
+
#
|
83
|
+
def test_ssl_basic
|
84
|
+
client = create_client(@connect_info, :connect => false, :ssl => true)
|
85
|
+
assert client.connect
|
86
|
+
end
|
87
|
+
|
88
|
+
# Requires MongoDB built with SSL and the following options:
|
89
|
+
#
|
90
|
+
# mongod --dbpath /path/to/data/directory --sslOnNormalPorts \
|
91
|
+
# --sslPEMKeyFile /path/to/server.pem \
|
92
|
+
# --sslCAFile /path/to/ca.pem \
|
93
|
+
# --sslCRLFile /path/to/crl.pem
|
94
|
+
#
|
95
|
+
# Make sure you have 'server' as an alias for localhost in /etc/hosts
|
96
|
+
#
|
97
|
+
def test_ssl_with_cert
|
98
|
+
client = create_client(@connect_info, :connect => false,
|
99
|
+
:ssl => true,
|
100
|
+
:ssl_cert => CLIENT_CERT,
|
101
|
+
:ssl_key => CLIENT_CERT)
|
102
|
+
assert client.connect
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_ssl_with_peer_cert_validation
|
106
|
+
client = create_client(@connect_info, :connect => false,
|
107
|
+
:ssl => true,
|
108
|
+
:ssl_key => CLIENT_CERT,
|
109
|
+
:ssl_cert => CLIENT_CERT,
|
110
|
+
:ssl_verify => true,
|
111
|
+
:ssl_ca_cert => CA_CERT)
|
112
|
+
assert client.connect
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_ssl_peer_cert_validation_hostname_fail
|
116
|
+
client = create_client(@bad_connect_info, :connect => false,
|
117
|
+
:ssl => true,
|
118
|
+
:ssl_key => CLIENT_CERT,
|
119
|
+
:ssl_cert => CLIENT_CERT,
|
120
|
+
:ssl_verify => true,
|
121
|
+
:ssl_ca_cert => CA_CERT)
|
122
|
+
assert_raise ConnectionFailure do
|
123
|
+
client.connect
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Requires MongoDB built with SSL and the following options:
|
128
|
+
#
|
129
|
+
# mongod --dbpath /path/to/data/directory --sslOnNormalPorts \
|
130
|
+
# --sslPEMKeyFile /path/to/password_protected.pem \
|
131
|
+
# --sslCAFile /path/to/ca.pem \
|
132
|
+
# --sslCRLFile /path/to/crl.pem
|
133
|
+
#
|
134
|
+
# Make sure you have 'server' as an alias for localhost in /etc/hosts.
|
135
|
+
# If SSL_KEY_PASS_PHRASE is not set as an environment variable,
|
136
|
+
# you will be prompted to enter a passphrase at runtime.
|
137
|
+
#
|
138
|
+
def test_ssl_with_key_pass_phrase
|
139
|
+
client = create_client(@connect_info, :connect => false,
|
140
|
+
:ssl => true,
|
141
|
+
:ssl_cert => CLIENT_CERT_PASS,
|
142
|
+
:ssl_key => CLIENT_CERT_PASS,
|
143
|
+
:ssl_key_pass_phrase => PASS_PHRASE)
|
144
|
+
assert client.connect
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_ssl_with_key_pass_phrase_fail
|
148
|
+
client = create_client(@connect_info, :connect => false,
|
149
|
+
:ssl => true,
|
150
|
+
:ssl_cert => CLIENT_CERT_PASS,
|
151
|
+
:ssl_key => CLIENT_CERT_PASS,
|
152
|
+
:ssl_key_pass_phrase => "secret")
|
153
|
+
assert_raise OpenSSL::PKey::RSAError do
|
154
|
+
client.connect
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Requires mongod built with SSL and the following options:
|
159
|
+
#
|
160
|
+
# mongod --dbpath /path/to/data/directory --sslOnNormalPorts \
|
161
|
+
# --sslPEMKeyFile /path/to/server.pem \
|
162
|
+
# --sslCAFile /path/to/ca.pem \
|
163
|
+
# --sslCRLFile /path/to/crl_client_revoked.pem
|
164
|
+
#
|
165
|
+
# Make sure you have 'server' as an alias for localhost in /etc/hosts
|
166
|
+
#
|
167
|
+
def test_ssl_with_invalid_cert
|
168
|
+
assert_raise ConnectionFailure do
|
169
|
+
create_client(@connect_info, :ssl => true,
|
170
|
+
:ssl_key => CLIENT_CERT,
|
171
|
+
:ssl_cert => CLIENT_CERT,
|
172
|
+
:ssl_verify => true,
|
173
|
+
:ssl_ca_cert => CA_CERT)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# X509 Authentication Tests
|
178
|
+
#
|
179
|
+
# Requires MongoDB built with SSL and the following options:
|
180
|
+
#
|
181
|
+
# mongod --auth --dbpath /path/to/data/directory --sslOnNormalPorts \
|
182
|
+
# --sslPEMKeyFile /path/to/server.pem \
|
183
|
+
# --sslCAFile /path/to/ca.pem \
|
184
|
+
# --sslCRLFile /path/to/crl.pem
|
185
|
+
#
|
186
|
+
# Note that the cert requires username:
|
187
|
+
# 'CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US'
|
188
|
+
#
|
189
|
+
def test_x509_authentication
|
190
|
+
mechanism = 'MONGODB-X509'
|
191
|
+
|
192
|
+
client = create_client(@connect_info, :ssl => true,
|
193
|
+
:ssl_cert => CLIENT_CERT,
|
194
|
+
:ssl_key => CLIENT_CERT)
|
195
|
+
|
196
|
+
return unless client.server_version > '2.5.2'
|
197
|
+
|
198
|
+
db = client.db('$external')
|
199
|
+
|
200
|
+
# add user for test (enable auth)
|
201
|
+
roles = [{:role => 'readWriteAnyDatabase', :db => 'admin'},
|
202
|
+
{:role => 'userAdminAnyDatabase', :db => 'admin'}]
|
203
|
+
db.add_user(MONGODB_X509_USERNAME, nil, false, :roles => roles)
|
204
|
+
|
205
|
+
assert db.authenticate(MONGODB_X509_USERNAME, nil, nil, nil, mechanism)
|
206
|
+
assert db.collection_names
|
207
|
+
|
208
|
+
assert db.logout
|
209
|
+
assert_raise Mongo::OperationFailure do
|
210
|
+
db.collection_names
|
211
|
+
end
|
212
|
+
|
213
|
+
# username and valid certificate don't match
|
214
|
+
assert_raise Mongo::AuthenticationError do
|
215
|
+
db.authenticate('test', nil, nil, nil, mechanism)
|
216
|
+
end
|
217
|
+
|
218
|
+
# username required
|
219
|
+
assert_raise Mongo::AuthenticationError do
|
220
|
+
db.authenticate(nil, nil, nil, nil, mechanism)
|
221
|
+
end
|
222
|
+
|
223
|
+
assert MongoClient.from_uri(
|
224
|
+
"mongodb://#{MONGODB_X509_USERNAME}@#{@uri_info}/?ssl=true;authMechanism=#{mechanism}",
|
225
|
+
:ssl_cert => CLIENT_CERT,
|
226
|
+
:ssl_key => CLIENT_CERT)
|
227
|
+
assert db.authenticate(MONGODB_X509_USERNAME, nil, nil, nil, mechanism)
|
228
|
+
assert db.collection_names
|
229
|
+
|
230
|
+
# clean up and remove all users
|
231
|
+
db.command(:dropAllUsersFromDatabase => 1)
|
232
|
+
db.logout
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|