lib/fakeldap.rb in fakeldap-0.0.1 vs lib/fakeldap.rb in fakeldap-0.1
- old
+ new
@@ -1,38 +1,121 @@
-$:.unshift(File.expand_path('../../vendor/ruby-ldapserver/lib', __FILE__))
require 'ldap/server'
module FakeLDAP
class Server < LDAP::Server
+
def initialize(options={})
@users = {}
+ @groups = {}
super(default_options.merge(options))
end
- def add_user(user, pass)
- @users[user] = pass
+ def add_user(user, pass, mail = nil)
+ @users[user] = [pass, mail]
end
+ def add_to_group(dn, member)
+ # Member array keyed on dn
+ @groups[dn] = [] unless @groups[dn]
+ @groups[dn] << member unless @groups[dn].include?(member)
+ end
+
+ def modify_entry(dn, key, action, value)
+ e = @users[dn]
+ # Didn't find user => maybe it's a group
+ e = @groups[dn] unless e && e[0]
+ if e
+ # FIXME: Annoying! Proper hash, not just array. Or hide in private method.
+ case key
+ when 'password'
+ e[0] = value
+ when 'mail'
+ e[1] = value
+ when 'member'
+ case action
+ when :add
+ e << value unless e.include?(value)
+ when :delete
+ e.delete(value)
+ end
+ end
+ end
+ end
+
+ def delete_entry(dn)
+ @users.delete(dn[0]) || @groups.delete(dn[0])
+ end
+
def valid_credentials?(user, pass)
- @users.has_key?(user) && @users[user] == pass
+ @users.has_key?(user) && @users[user][0] == pass
end
def find_users(basedn, filter)
+ result = []
basedn_regex = /#{Regexp.escape(basedn)}$/
filter_regex = /^#{filter[1]}=#{filter[3]}$/
- @users.keys.select { |dn|
- dn =~ basedn_regex && dn.split(",").grep(filter_regex).any?
- }
+ case filter[1]
+ when 'objectClass'
+ result = @users.keys if filter[3] == 'inetOrgPerson'
+ when 'cn'
+ @users.keys.select { |dn|
+ dn =~ basedn_regex && dn.split(",").grep(filter_regex).any?
+ }
+ when 'mail'
+ @users.keys.each do |dn|
+ # Keyed on full cn=...,dn...
+ if @users[dn][1] == filter[3]
+ result << dn
+ end
+ end
+ result
+ else
+ result
+ end
end
+ def user_attributes(dn)
+ # Create attribute hash here
+ if @users[dn]
+ {'cn' => ["#{dn}"], 'regular_password' => ["#{ @users[dn][0]}"], 'mail' => ["#{ @users[dn][1]}"], 'disclaimer' => 'Test data - not for operational use'}
+ else
+ {}
+ end
+ end
+
+ def find_groups(basedn, filter)
+ # Expected result - array of strings
+ result = []
+ group = "#{basedn}"
+ case filter[1]
+ when 'objectClass'
+ result = @groups.keys if filter[3] == 'groupOfNames'
+ when 'cn'
+ result = @groups[group] || []
+ when 'member'
+ result = [filter[3]] if @groups[group] && @groups[group].include?(filter[3])
+ result = @groups.keys if filter[3] == 'groupOfNames'
+ end
+ result
+ end
+
+ def group_attributes(cn)
+ if @groups[cn]
+ { 'cn' => ["#{cn}"], 'member' => @groups["#{cn}"] }
+ else
+ {}
+ end
+ end
+
def default_options
{
:operation_class => ::FakeLDAP::Operation,
:operation_args => [self]
}
end
+
end
class Operation < LDAP::Server::Operation
def initialize(connection, messageID, server)
super(connection, messageID)
@@ -55,12 +138,52 @@
unless filter.first == :eq
raise LDAP::ResultError::UnwillingToPerform,
"Only equality matches are supported"
end
- @server.find_users(basedn, filter).each do |dn|
- send_SearchResultEntry(dn, {})
+ users = @server.find_users(basedn, filter)
+ groups = @server.find_groups(basedn, filter)
+ if users
+ users.each do |dn|
+ attributes = @server.user_attributes("#{dn}") || {}
+ send_SearchResultEntry(dn, attributes)
+ end
end
+ if groups
+ groups.each do |dn|
+ attributes = @server.group_attributes("#{dn}") || {}
+ send_SearchResultEntry(dn, attributes)
+ end
+ end
end
+
+ def add(dn, attr)
+ # Barring rocket-science. Always, only one single add
+ case attr['objectclass'][0]
+ when 'inetOrgPerson'
+ @server.add_user(dn, attr[:userPassword], attr[:mail])
+ when 'groupofnames'
+ @server.add_to_group(dn, attr['member'][0])
+ end
+ end
+
+ def modify(*args)
+ # A hash able to contain an array of arrays... LDAP nuttiness!
+ dn = args[0]
+ key = args[1].keys.first
+ action = args[1][key][0]
+ value = args[1][key][1]
+ # Barring rocket-science. Always, only one single action.
+ @server.modify_entry(dn, key, action, value)
+ end
+
+ # Some silly clients call delete del...
+ def del(*args)
+ delete(args)
+ end
+
+ def delete(*args)
+ dn = args[0]
+ @server.delete_entry(dn)
+ end
end
end
-