Skip to content

Instantly share code, notes, and snippets.

@DimaSamodurov
Created February 3, 2016 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DimaSamodurov/f0c0bbc91a07e8b3d71d to your computer and use it in GitHub Desktop.
Save DimaSamodurov/f0c0bbc91a07e8b3d71d to your computer and use it in GitHub Desktop.
Testing LDAP with a shim.
require 'spec_helper'
describe 'update distribution list', ldap: true do
it 'updates data in LDAP' do
n = 4
# Do add 4 DL entries
expect(TEST_LDAP_SERVER.store.count).to eql n
end
end
require 'ldap/server'
module LDAP
# Subclass the Operation class, overriding the methods to do what we need
class HashOperation < LDAP::Server::Operation
def initialize(connection, messageID, hash)
super(connection, messageID)
@hash = hash # an object reference to our directory data
end
def search(basedn, scope, deref, filter)
basedn.downcase!
case scope
when LDAP::Server::BaseObject
# client asked for single object by DN
obj = @hash[basedn]
raise LDAP::ResultError::NoSuchObject unless obj
send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
when LDAP::Server::WholeSubtree
@hash.each do |dn, av|
next unless dn.index(basedn, -basedn.length) # under basedn?
next unless LDAP::Server::Filter.run(filter, av) # attribute filter?
send_SearchResultEntry(dn, av)
end
else
raise LDAP::ResultError::UnwillingToPerform, "OneLevel not implemented"
end
end
def add(dn, av)
dn.downcase!
raise LDAP::ResultError::EntryAlreadyExists if @hash[dn]
@hash[dn] = av
end
def del(dn)
dn.downcase!
raise LDAP::ResultError::NoSuchObject unless @hash.has_key?(dn)
@hash.delete(dn)
end
def modify(dn, ops)
entry = @hash[dn.downcase]
raise LDAP::ResultError::NoSuchObject unless entry
ops.each do |attr, vals|
op = vals.shift
case op
when :add
entry[attr] ||= []
entry[attr] += vals
entry[attr].uniq!
when :delete
if vals == []
entry.delete(attr)
else
vals.each { |v| entry[attr].delete(v) }
end
when :replace
entry[attr] = vals
end
entry.delete(attr) if entry[attr] == []
end
end
end
end
require 'local_ldap'
TEST_LDAP_SERVER = LocalLdap.new
RSpec.configure do |c|
ldap_server = nil
c.before :each, ldap: true do |ex|
ldap_server ||= TEST_LDAP_SERVER.tap &:run_tcpserver
ldap_server.store.clear
end
c.after :suite do
ldap_server.stop if ldap_server
end
end
require 'spec_helper'
require 'ldap/server'
require 'ldap/hash_operation'
describe 'LDAP::Server' do
# This is the shared object which carries our actual directory entries.
# It's just a hash of {dn=>entry}, where each entry is {attr=>[val,val,...]}
directory = {}
server = LDAP::Server.new(
:port => 1897,
:nodelay => true,
:listen => 10,
:operation_class => LDAP::HashOperation,
:operation_args => [directory]
)
before do
server.run_tcpserver
end
after do
server.stop
end
it 'starts local ldap server and listens to a TCP port' do
sleep 1
expect { s = TCPSocket.new('localhost', 1897) ; s.close if s }.to_not raise_exception
end
end
require 'ldap/server'
require 'ldap/hash_operation'
class LocalLdap < LDAP::Server
DEFAULT_OPTIONS = {
:port => 3897,
:nodelay => true,
:listen => 10,
:operation_class => LDAP::HashOperation
}
attr_reader :store
def initialize(custom_options = {}, data_store = {})
options = DEFAULT_OPTIONS.merge custom_options
@store = data_store
options[:operation_args] = [data_store]
super options
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment