Skip to content

Commit 285e632

Browse files
committed
Merge pull request #701 from estolfo/client-opts
Validate client options. Related to MONGOID-4157
2 parents 5d0d10e + 79dff9f commit 285e632

File tree

3 files changed

+95
-8
lines changed

3 files changed

+95
-8
lines changed

lib/mongo/client.rb

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,48 @@ module Mongo
2020
# @since 2.0.0
2121
class Client
2222
extend Forwardable
23+
include Loggable
2324

2425
# The options that do not affect the behaviour of a cluster and its
2526
# subcomponents.
2627
#
2728
# @since 2.1.0
2829
CRUD_OPTIONS = [ :database, :read, :write ].freeze
2930

31+
# Valid client options.
32+
#
33+
# @since 2.1.2
34+
VALID_OPTIONS = [
35+
:auth_mech,
36+
:auth_source,
37+
:connect,
38+
:database,
39+
:auth_mech_properties,
40+
:heartbeat_frequency,
41+
:local_threshold,
42+
:server_selection_timeout,
43+
:password,
44+
:max_pool_size,
45+
:min_pool_size,
46+
:wait_queue_timeout,
47+
:connect_timeout,
48+
:read,
49+
:roles,
50+
:replica_set,
51+
:ssl,
52+
:ssl_cert,
53+
:ssl_key,
54+
:ssl_key_pass_phrase,
55+
:ssl_verify,
56+
:ssl_ca_cert,
57+
:socket_timeout,
58+
:user,
59+
:write,
60+
:monitoring,
61+
:logger,
62+
:truncate_logs
63+
].freeze
64+
3065
# @return [ Mongo::Cluster ] cluster The cluster of servers for the client.
3166
attr_reader :cluster
3267

@@ -160,9 +195,9 @@ def hash
160195
def initialize(addresses_or_uri, options = Options::Redacted.new)
161196
@monitoring = Monitoring.new(options)
162197
if addresses_or_uri.is_a?(::String)
163-
create_from_uri(addresses_or_uri, options)
198+
create_from_uri(addresses_or_uri, validate_options(options))
164199
else
165-
create_from_addresses(addresses_or_uri, options)
200+
create_from_addresses(addresses_or_uri, validate_options(options))
166201
end
167202
yield(self) if block_given?
168203
end
@@ -221,7 +256,7 @@ def use(name)
221256
# @since 2.0.0
222257
def with(new_options = Options::Redacted.new)
223258
clone.tap do |client|
224-
opts = Options::Redacted.new(new_options) || Options::Redacted.new
259+
opts = validate_options(new_options)
225260
client.options.update(opts)
226261
Database.create(client)
227262
# We can't use the same cluster if some options that would affect it
@@ -296,14 +331,14 @@ def list_databases
296331
private
297332

298333
def create_from_addresses(addresses, opts = Options::Redacted.new)
299-
@options = Options::Redacted.new(Database::DEFAULT_OPTIONS.merge(opts)).freeze
334+
@options = Database::DEFAULT_OPTIONS.merge(opts).freeze
300335
@cluster = Cluster.new(addresses, @monitoring, options)
301336
@database = Database.new(self, options[:database], options)
302337
end
303338

304339
def create_from_uri(connection_string, opts = Options::Redacted.new)
305340
uri = URI.new(connection_string, opts)
306-
@options = Options::Redacted.new(Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts))).freeze
341+
@options = Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts)).freeze
307342
@cluster = Cluster.new(uri.servers, @monitoring, options)
308343
@database = Database.new(self, options[:database], options)
309344
end
@@ -324,5 +359,17 @@ def cluster_modifying?(new_options)
324359
options[name] != value
325360
end
326361
end
362+
363+
def validate_options(opts = Options::Redacted.new)
364+
return Options::Redacted.new unless opts
365+
Options::Redacted.new(opts.select do |o|
366+
if VALID_OPTIONS.include?(o)
367+
true
368+
else
369+
log_warn("Unsupported client option '#{o}'. It will be ignored.")
370+
false
371+
end
372+
end)
373+
end
327374
end
328375
end

lib/mongo/loggable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def log_warn(message)
9393
#
9494
# @since 2.1.0
9595
def logger
96-
(options[:logger] || Logger.logger)
96+
((options && options[:logger]) || Logger.logger)
9797
end
9898

9999
private

spec/mongo/client_spec.rb

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@
166166
described_class.new(
167167
['127.0.0.1:27017'],
168168
:read => { :mode => :primary },
169-
:local_threshold_ms => 10,
169+
:local_threshold => 10,
170170
:server_selection_timeout => 10000,
171171
:database => TEST_DB
172172
)
173173
end
174174

175175
let(:options) do
176176
Mongo::Options::Redacted.new(:read => { :mode => :primary },
177-
:local_threshold_ms => 10,
177+
:local_threshold => 10,
178178
:server_selection_timeout => 10000,
179179
:database => TEST_DB)
180180
end
@@ -373,6 +373,26 @@
373373
expect(client.cluster.topology).to be_a(Mongo::Cluster::Topology::ReplicaSet)
374374
end
375375
end
376+
377+
context 'when an invalid option is provided' do
378+
379+
let(:client) do
380+
described_class.new(['127.0.0.1:27017'], :ssl => false, :invalid => :test)
381+
end
382+
383+
it 'does not set the option' do
384+
expect(client.options.keys).not_to include('invalid')
385+
end
386+
387+
it 'sets the valid options' do
388+
expect(client.options.keys).to include('ssl')
389+
end
390+
391+
it 'warns that an invalid option has been specified' do
392+
expect(Mongo::Logger.logger).to receive(:warn)
393+
expect(client.options.keys).not_to include('invalid')
394+
end
395+
end
376396
end
377397
end
378398

@@ -624,6 +644,26 @@
624644
end
625645
end
626646
end
647+
648+
context 'when an invalid option is provided' do
649+
650+
let(:new_client) do
651+
client.with(invalid: :option, ssl: false)
652+
end
653+
654+
it 'does not set the invalid option' do
655+
expect(new_client.options.keys).not_to include('invalid')
656+
end
657+
658+
it 'sets the valid options' do
659+
expect(new_client.options.keys).to include('ssl')
660+
end
661+
662+
it 'warns that an invalid option has been specified' do
663+
expect(Mongo::Logger.logger).to receive(:warn)
664+
expect(new_client.options.keys).not_to include('invalid')
665+
end
666+
end
627667
end
628668

629669
describe '#write_concern' do

0 commit comments

Comments
 (0)