require File.expand_path( File.dirname(__FILE__) + '/../test_helper') require 'tempfile' module Tracks class Config def self.salt "change-me" end def self.auth_schemes ['database','ldap'] end end end class LdapAuthTest < ActionController::IntegrationTest fixtures :users RUN_LDAP_TESTS = ENV['RUN_TRACKS_LDAP_TESTS'] || false SLAPD_BIN = "/usr/libexec/slapd" #You may need to adjust this SLAPD_SCHEMA_DIR = "/etc/openldap/schema/" #You may need to adjust this SLAPD_TEST_PORT = 10389 OUTPUT_DEBUG_INFO = false begin require 'net/ldap' #requires ruby-net-ldap gem be installed require 'simple_ldap_authenticator' end if RUN_LDAP_TESTS SimpleLdapAuthenticator.ldap_library = 'net/ldap' SimpleLdapAuthenticator.servers = %w'localhost' SimpleLdapAuthenticator.use_ssl = false SimpleLdapAuthenticator.login_format = 'cn=%s,dc=lukemelia,dc=com' SimpleLdapAuthenticator.port = 10389 SimpleLdapAuthenticator.logger = RAILS_DEFAULT_LOGGER def setup assert_equal "test", ENV['RAILS_ENV'] assert_equal "change-me", Tracks::Config.salt if RUN_LDAP_TESTS setup_ldap_server_conf start_ldap_server end end def teardown stop_ldap_server if RUN_LDAP_TESTS end def test_authenticate_against_ldap add_ldap_user_to_ldap_repository assert SimpleLdapAuthenticator.valid?('john', 'deere') user = User.authenticate('john', 'deere') assert_not_nil(user) assert_equal user.login, 'john' end private :test_authenticate_against_ldap unless RUN_LDAP_TESTS def setup_ldap_server_conf @slapd_conf = create_slapd_conf() open(@slapd_conf.path) { |f| f.read } unless File.exist?(SLAPD_BIN) assert false, "slapd could not be found at #{SLAPD_BIN}. Adjust the path in #{__FILE__}" end end def start_ldap_server t = Thread.new(@slapd_conf.path) do |slapd_conf_path| puts "starting slapd..." if OUTPUT_DEBUG_INFO run_cmd %Q{/usr/libexec/slapd -f #{slapd_conf_path} -h "ldap://127.0.0.1:10389/" -d0} end sleep(2) run_cmd %Q{ldapsearch -H "ldap://127.0.0.1:10389/" -x -b '' -s base '(objectclass=*)' namingContexts} end def add_ldap_user_to_ldap_repository ldif_file = create_ldif() run_cmd %Q{ldapadd -H "ldap://127.0.0.1:10389/" -f #{ldif_file.path} -cxv -D "cn=Manager,dc=lukemelia,dc=com" -w secret} puts `cat #{ldif_file.path}` if OUTPUT_DEBUG_INFO end def stop_ldap_server pid = open(get_pid_file_path(@slapd_conf)) { |f| f.read } run_cmd "kill -TERM #{pid}" end def create_slapd_conf slapd_conf = Tempfile.new("slapd.conf") slapd_conf.path data_dir = slapd_conf.path + '-data' pid_file = get_pid_file_path(slapd_conf) Dir.mkdir(data_dir) encrypted_password = `slappasswd -s secret` open(slapd_conf.path, 'w') do |f| f.puts %Q{include #{SLAPD_SCHEMA_DIR}core.schema pidfile #{pid_file} database ldbm suffix "dc=lukemelia,dc=com" rootdn "cn=Manager,dc=lukemelia,dc=com" rootpw #{encrypted_password} directory #{data_dir} access to * by self write by users read by anonymous auth } end puts `cat #{slapd_conf.path}` if OUTPUT_DEBUG_INFO slapd_conf end def create_ldif ldif_file = Tempfile.new("ldap_user.ldif") encrypted_password = `slappasswd -s deere` open(ldif_file.path, 'w') do |f| f.puts %Q{dn: dc=lukemelia,dc=com objectclass: dcObject objectclass: organization o: Luke Melia DotCom dc: lukemelia dn: cn=john,dc=lukemelia,dc=com cn: john sn: john objectclass: person userPassword: #{encrypted_password} } end ldif_file end def run_cmd(cmd) puts cmd if OUTPUT_DEBUG_INFO cmd_out = `#{cmd}` puts cmd_out if OUTPUT_DEBUG_INFO end def get_pid_file_path(tempfile) tempfile.path + '.pid' end end