mongodb-mongo 0.1.4 → 0.2.0

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.
data/lib/mongo/db.rb CHANGED
@@ -15,6 +15,7 @@
15
15
  # ++
16
16
 
17
17
  require 'socket'
18
+ require 'md5'
18
19
  require 'mutex_m'
19
20
  require 'mongo/collection'
20
21
  require 'mongo/message'
@@ -32,6 +33,7 @@ module XGen
32
33
  SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"
33
34
  SYSTEM_INDEX_COLLECTION = "system.indexes"
34
35
  SYSTEM_PROFILE_COLLECTION = "system.profile"
36
+ SYSTEM_USER_COLLECTION = "system.users"
35
37
  SYSTEM_COMMAND_COLLECTION = "$cmd"
36
38
 
37
39
  # Strict mode enforces collection existence checks. When +true+,
@@ -94,7 +96,7 @@ module XGen
94
96
  # fails, it keeps trying to connect to the remaining nodes until it
95
97
  # sucessfully connects.
96
98
  def initialize(db_name, nodes, options={})
97
- raise "Invalid DB name" if !db_name || (db_name && db_name.length > 0 && db_name.include?("."))
99
+ raise "Invalid DB name \"#{db_name}\" (must be non-nil, non-zero-length, and can not contain \".\")" if !db_name || (db_name && db_name.length > 0 && db_name.include?("."))
98
100
  @name, @nodes = db_name, nodes
99
101
  @strict = options[:strict]
100
102
  @pk_factory = options[:pk]
@@ -119,6 +121,33 @@ module XGen
119
121
  raise "error: failed to connect to any given host:port" unless @socket
120
122
  end
121
123
 
124
+ # Add a new user to the database.
125
+ def add_user(username, password)
126
+ coll = collection(SYSTEM_USER_COLLECTION)
127
+ coll.insert(:user => username, :pwd => hash_password(password))
128
+ end
129
+
130
+ def delete_user(username)
131
+ coll = collection(SYSTEM_USER_COLLECTION)
132
+ coll.remove(:user => username)
133
+ end
134
+
135
+ # Returns true if +username+ has +password+ in
136
+ # +SYSTEM_USER_COLLECTION+. +name+ is username, +password+ is
137
+ # plaintext password.
138
+ def authenticate(username, password)
139
+ doc = db_command(:getnonce => 1)
140
+ raise "error retrieving nonce: #{doc}" unless ok?(doc)
141
+ nonce = doc['nonce']
142
+
143
+ auth = OrderedHash.new
144
+ auth['authenticate'] = 1
145
+ auth['user'] = username
146
+ auth['nonce'] = nonce
147
+ auth['key'] = MD5.md5("#{nonce}#{username}#{hash_password(password)}").to_s
148
+ ok?(db_command(auth))
149
+ end
150
+
122
151
  # Returns an array of collection names. Each name is of the form
123
152
  # "database_name.collection_name".
124
153
  def collection_names
@@ -203,7 +232,7 @@ module XGen
203
232
  def master
204
233
  doc = db_command(:ismaster => 1)
205
234
  is_master = doc['ismaster']
206
- raise "Error retrieving master database" unless ok?(doc) && is_master.kind_of?(Numeric)
235
+ raise "Error retrieving master database: #{doc.inspect}" unless ok?(doc) && is_master.kind_of?(Numeric)
207
236
  case is_master.to_i
208
237
  when 1
209
238
  "#@host:#@port"
@@ -393,6 +422,12 @@ module XGen
393
422
  query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q).next_object
394
423
  end
395
424
 
425
+ private
426
+
427
+ def hash_password(plaintext)
428
+ MD5.new("mongo#{plaintext}").to_s
429
+ end
430
+
396
431
  end
397
432
  end
398
433
  end
data/lib/mongo/mongo.rb CHANGED
@@ -99,10 +99,10 @@ module XGen
99
99
  begin
100
100
  db = db(db_name)
101
101
  doc = db.db_command(cmd)
102
- raise "error retrieving database info" unless db.ok?(doc)
102
+ raise "error retrieving database info: #{doc.inspect}" unless db.ok?(doc)
103
103
  doc
104
104
  ensure
105
- db.close
105
+ db.close if db
106
106
  end
107
107
  end
108
108
 
@@ -63,6 +63,24 @@ class OrderedHash < Hash
63
63
  str << '}'
64
64
  end
65
65
 
66
+ def delete(key, &block)
67
+ @ordered_keys.delete(key)
68
+ super
69
+ end
70
+
71
+ def delete_if(&block)
72
+ self.each { |k,v|
73
+ if yield k, v
74
+ delete(k)
75
+ end
76
+ }
77
+ end
78
+
79
+ def clear
80
+ super
81
+ @ordered_keys = []
82
+ end
83
+
66
84
  end # Ruby before 1.9
67
85
 
68
86
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'mongo'
3
- s.version = '0.1.4'
3
+ s.version = '0.2.0'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = 'Simple pure-Ruby driver for the 10gen Mongo DB'
6
6
  s.description = 'A pure-Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
data/tests/test_db.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'md5'
2
3
  require 'mongo'
3
4
  require 'test/unit'
4
5
 
@@ -18,6 +19,8 @@ class DBTest < Test::Unit::TestCase
18
19
  @host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
19
20
  @port = ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT
20
21
  @db = Mongo.new(@host, @port).db('ruby-mongo-test')
22
+ @spongebob = 'spongebob'
23
+ @spongebob_password = 'squarepants'
21
24
  end
22
25
 
23
26
  def teardown
@@ -82,4 +85,46 @@ class DBTest < Test::Unit::TestCase
82
85
  end
83
86
  end
84
87
 
88
+ def test_add_user
89
+ coll = @db.collection('system.users')
90
+ coll.clear
91
+ begin
92
+ assert_equal 0, coll.count
93
+ @db.add_user(@spongebob, @spongebob_password)
94
+ assert_equal 1, coll.count
95
+ doc = coll.find({}, :limit => 1).next_object
96
+ assert_equal @spongebob, doc['user']
97
+ assert_equal MD5.new("mongo#{@spongebob_password}").to_s, doc['pwd']
98
+ ensure
99
+ coll.clear
100
+ end
101
+ end
102
+
103
+ def test_delete_user
104
+ coll = @db.collection('system.users')
105
+ coll.clear
106
+ begin
107
+ assert_equal 0, coll.count
108
+ @db.add_user(@spongebob, @spongebob_password)
109
+ assert_equal 1, coll.count
110
+ @db.delete_user(@spongebob)
111
+ assert_equal 0, coll.count
112
+ ensure
113
+ coll.clear
114
+ end
115
+ end
116
+
117
+ def test_authenticate
118
+ coll = @db.collection('system.users')
119
+ coll.clear
120
+ begin
121
+ @db.add_user(@spongebob, @spongebob_password)
122
+ assert !@db.authenticate('nobody', 'nopassword')
123
+ assert !@db.authenticate(@spongebob, 'squareliederhosen')
124
+ assert @db.authenticate(@spongebob, @spongebob_password)
125
+ ensure
126
+ coll.clear
127
+ end
128
+ end
129
+
85
130
  end
@@ -82,4 +82,21 @@ class OrderedHashTest < Test::Unit::TestCase
82
82
  assert_equal '{"c"=>1, "a"=>2, "z"=>3}', @oh.inspect
83
83
  end
84
84
 
85
+ def test_clear
86
+ @oh.clear
87
+ assert @oh.keys.empty?
88
+ end
89
+
90
+ def test_delete
91
+ assert @oh.keys.include?('z')
92
+ @oh.delete('z')
93
+ assert !@oh.keys.include?('z')
94
+ end
95
+
96
+ def test_delete_if
97
+ assert @oh.keys.include?('z')
98
+ @oh.delete_if { |k,v| k == 'z' }
99
+ assert !@oh.keys.include?('z')
100
+ end
101
+
85
102
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongodb-mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Menard