mongodb-mongo 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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