Hooking in an LDAP Test Server to Cucumber Tests

I managed to get a custom Devise strategy with LDAP working, but had no clear way of automating tests. I wanted to validate if I still had to keep the password fresh in the database, and needed to be able to write scenarios around that in case someone attempted to refactor out the code.

After trying to incorporate the spec strategy used in the development devise_ldap_authenticatable and failing, I found a ruby wrapper of ApacheDS called ladle that looked like it would serve my purposes.

I included in gem in my test group in my Gemfile:

  gem 'ladle'

At the top of my features/env.rb file for configuring cucumber, I turned off admin binding (wanted the connection as simple as possible):

::Devise.ldap_use_admin_to_bind = false

I then created an @ldap tag for my LDAP-dependent features than would start and stop the LDAP server in those instances. (Again, in my features/env.rb... probably need to clean that up.)

Around('@ldap') do |scenario, block|
  $ladle ||= Ladle::Server.new(
    :ldif => "spec/ldap/test_users.ldif",
    :domain => "dc=example,dc=org",
    :quiet => true
  )
  $ladle.start
  block.call
  $ladle.stop
end

I then created an the spec/ldap/test_users.ldif (from following the example in the ladle project).

version: 1
 
dn: ou=people,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: people
 
dn: uid=eadmin,ou=people,dc=example,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Example Admin
sn: Admin
givenName: Example
mail: eadmin@example.com
uid: eadmin
# Password is "b44b44bl@cksh33p!"
userpassword: {SHA}Aedq5WHQSxglvJSfpX0kgdGRdHk=

I generated the password with:

  slappasswd -h {SHA} -s b44b44bl@cksh33p!

One stupid mistake that I did in the process was kicking off two Ladle servers (with slightly different parameters). In one iteration, I couldn't bind to the user. Another, the server using the test file failed to start. Be aware that Ladle will run happily with default parameters, but that they won't be much use to you.

If you want to test your configuration file:

require 'net/ldap'
require 'ladle'
 
$ladle ||= Ladle::Server.new(
  :ldif => "spec/ldap/test_users.ldif",
  :domain => "dc=example,dc=org",
  :quiet => true
)
$ladle.start
 
ldap = Net::LDAP.new(host: 'localhost',
    :port => 3897,
)
filter = Net::LDAP::Filter.eq('mail', 'eadmin@example.com') # or ('uid', 'eadmin') 
 
ldap.search(:base => 'ou=people,dc=example,dc=org', :filter => filter) do |entry|
  ldap.auth(entry.dn, 'b44b44bl@cksh33p!') # or whatever your password is
 
  entry.each do |attribute, values|
    puts "   #{attribute}:"
    values.each do |value|
      puts "      --->#{value}"
    end
  end
end