Ruby on Rails
ActiveLDAP (Version #50)

Ruby/ActiveLdap provides an object oriented interface to LDAP. This library was inspired by ActiveRecord (both the concept and the library). It maps LDAP entries to Ruby objects with LDAP attribute accessors exposed as methods dynamically assigned based on your LDAP schema and each object’s objectClasses.

http://raa.ruby-lang.org/project/ruby-activeldap/
http://projects.dataspill.org/pages/projects/ruby-activeldap

Here’s a basic overview of what I did to get ActiveLdap? to work with a simple ‘scaffold’ type rails application.

Let’s say you have a ‘Contact’ model. Change it to look like the following:


class Contact < ActiveLdap::Base
   ldap_mapping
end

All we’ve done here is change the parent class of the model from ‘ActiveRecord’ to ‘ActiveLdap’ and added a call to ldap_mapping. See the ActiveLdap documentation for arguments and usage of ldap_mapping.

If you want to use LDAP exclusively for your models, you need to edit the file config/environment.rb to set things up for LDAP instead of a SQL database.

First, comment out the following two lines:


#ActiveRecord::Base.configurations =     File.open("#{RAILS_ROOT}/config/database.yml") { |f| YAML::load(f) }
#ActiveRecord::Base.establish_connection

This keeps ActiveRecord from loading a database config and connecting to the database. Replace these calls with the following:


ActiveLdap::Base.connect()

Obviously, there’s some upfront work involved in getting your LDAP configuration tweaked so that the connect() will work.

Now, in your controller’s list method, you can do something like the following:


@contacts = Contact.find_all(:attribute => 'cn', :value => '*', :objects => true)


@contacts will now contain an array of objects representing all of the entries in your directory whose ‘cn’, or commonName, attribute matches the ‘star’ wildcard. This object contains an ‘attributes’ array with the names of all the attributes of your LDAP objects. You’ve also got dynamically created accessor methods for each of these attributes that you can use to fetch values. This is what that call to ldap_mapping was for in your model class.

Using the new config setup in Rails 0.14.2

With rails 0.14.2, there’s a new setup for loading configuration details. If you don’t want to mess with it, you can just say no when the rails command asks if you want to overwrite your config/environment.rb and config/environment/ files, and leave things as detailed above. It’s all or nothing though: you can’t, say, use the new environment/development.rb and stick with the old environment.rb. I attempted to do this, and experienced much breakage, and then couldn’t roll back to the old development.rb because of a borked svn server, and so was forced to forge ahead into the brave new world of Rails configuration.

It turns out, though, that modifying the new environment file is very easy, and it will be much cleaner as a result.

So, here’s how it works: first, look for this line in the block that gets passed to Rails::Initializer.run:


#  config.frameworks -= [ :action_web_service, :action_mailer]

Uncomment it, and add active_record to the array:


  config.frameworks -= [ :action_web_service, :action_mailer, :active_record]

(If you are actually using action_web_service or action_mailer in your app, then remove those from the array.)

This has the effect of preventing active_record from loading and attempting to establish a database connection.

Now simply go to the bottom of the file and make it look like this:


  # Include your application configuration below
  require 'activeldap'
  ActiveLdap::Base.connect() 

Adjust your connection parameters to taste, and away you go…

Q: Anyone having problems with the connection to ldap becoming stale (getting ‘no message’ exceptions from a .find) on long-lived (between apache restarts)? Using Apache with fastCGI. – Bishop

A: Reconnects and binding with new credentials is fully supported in release 0.7.1 – wad

Q: How do you only disable one class from being associated with a database? Other classes should still use ActiveRecord with database access..

A: Skip the part in this guide about stopping activerecord in environment.rb and just inherit from ActiveLdap for the models that should use LDAP, and ActiveRecord for models that should use the database.

Using ActiveLdap with Apple’s OpenDirectory

Apple’s OpenDirectory has some attributes whose names contain ’-’ characters which are not permitted in method names. When ActiveLdap maps the attributes to methods it does not attempt to change the characters to correct the incompatibility.

To fix the problem, I added the following to my base LDAP class:


    def define_attribute_methods(attr)

      if @attr_methods.has_key? attr
        return
      end
      aliases = Base.schema.attribute_aliases(attr)
      aliases.each do |ali|

      @attr_methods[ali.gsub(/-/,'_')] = attr
      end
    end

    def make_subtypes(attr, value)

      return [attr.gsub(/-/,'_'), value] unless attr.match(/;/)

      ret_attr, *subtypes = attr.split(/;/)
      return [ret_attr.gsub(/-/,'_'), [make_subtypes_helper(subtypes, value)]]
    end

-John

2006-07-11 What about a rails scaffold generator?

2007-05-10 parasew: changed the wording from “ActiveLDAP” to “ActiveLdap”, since it was changed by the ActiveLdap Developers

Ruby/ActiveLdap provides an object oriented interface to LDAP. This library was inspired by ActiveRecord (both the concept and the library). It maps LDAP entries to Ruby objects with LDAP attribute accessors exposed as methods dynamically assigned based on your LDAP schema and each object’s objectClasses.

http://raa.ruby-lang.org/project/ruby-activeldap/
http://projects.dataspill.org/pages/projects/ruby-activeldap

Here’s a basic overview of what I did to get ActiveLdap? to work with a simple ‘scaffold’ type rails application.

Let’s say you have a ‘Contact’ model. Change it to look like the following:


class Contact < ActiveLdap::Base
   ldap_mapping
end

All we’ve done here is change the parent class of the model from ‘ActiveRecord’ to ‘ActiveLdap’ and added a call to ldap_mapping. See the ActiveLdap documentation for arguments and usage of ldap_mapping.

If you want to use LDAP exclusively for your models, you need to edit the file config/environment.rb to set things up for LDAP instead of a SQL database.

First, comment out the following two lines:


#ActiveRecord::Base.configurations =     File.open("#{RAILS_ROOT}/config/database.yml") { |f| YAML::load(f) }
#ActiveRecord::Base.establish_connection

This keeps ActiveRecord from loading a database config and connecting to the database. Replace these calls with the following:


ActiveLdap::Base.connect()

Obviously, there’s some upfront work involved in getting your LDAP configuration tweaked so that the connect() will work.

Now, in your controller’s list method, you can do something like the following:


@contacts = Contact.find_all(:attribute => 'cn', :value => '*', :objects => true)


@contacts will now contain an array of objects representing all of the entries in your directory whose ‘cn’, or commonName, attribute matches the ‘star’ wildcard. This object contains an ‘attributes’ array with the names of all the attributes of your LDAP objects. You’ve also got dynamically created accessor methods for each of these attributes that you can use to fetch values. This is what that call to ldap_mapping was for in your model class.

Using the new config setup in Rails 0.14.2

With rails 0.14.2, there’s a new setup for loading configuration details. If you don’t want to mess with it, you can just say no when the rails command asks if you want to overwrite your config/environment.rb and config/environment/ files, and leave things as detailed above. It’s all or nothing though: you can’t, say, use the new environment/development.rb and stick with the old environment.rb. I attempted to do this, and experienced much breakage, and then couldn’t roll back to the old development.rb because of a borked svn server, and so was forced to forge ahead into the brave new world of Rails configuration.

It turns out, though, that modifying the new environment file is very easy, and it will be much cleaner as a result.

So, here’s how it works: first, look for this line in the block that gets passed to Rails::Initializer.run:


#  config.frameworks -= [ :action_web_service, :action_mailer]

Uncomment it, and add active_record to the array:


  config.frameworks -= [ :action_web_service, :action_mailer, :active_record]

(If you are actually using action_web_service or action_mailer in your app, then remove those from the array.)

This has the effect of preventing active_record from loading and attempting to establish a database connection.

Now simply go to the bottom of the file and make it look like this:


  # Include your application configuration below
  require 'activeldap'
  ActiveLdap::Base.connect() 

Adjust your connection parameters to taste, and away you go…

Q: Anyone having problems with the connection to ldap becoming stale (getting ‘no message’ exceptions from a .find) on long-lived (between apache restarts)? Using Apache with fastCGI. – Bishop

A: Reconnects and binding with new credentials is fully supported in release 0.7.1 – wad

Q: How do you only disable one class from being associated with a database? Other classes should still use ActiveRecord with database access..

A: Skip the part in this guide about stopping activerecord in environment.rb and just inherit from ActiveLdap for the models that should use LDAP, and ActiveRecord for models that should use the database.

Using ActiveLdap with Apple’s OpenDirectory

Apple’s OpenDirectory has some attributes whose names contain ’-’ characters which are not permitted in method names. When ActiveLdap maps the attributes to methods it does not attempt to change the characters to correct the incompatibility.

To fix the problem, I added the following to my base LDAP class:


    def define_attribute_methods(attr)

      if @attr_methods.has_key? attr
        return
      end
      aliases = Base.schema.attribute_aliases(attr)
      aliases.each do |ali|

      @attr_methods[ali.gsub(/-/,'_')] = attr
      end
    end

    def make_subtypes(attr, value)

      return [attr.gsub(/-/,'_'), value] unless attr.match(/;/)

      ret_attr, *subtypes = attr.split(/;/)
      return [ret_attr.gsub(/-/,'_'), [make_subtypes_helper(subtypes, value)]]
    end

-John

2006-07-11 What about a rails scaffold generator?

2007-05-10 parasew: changed the wording from “ActiveLDAP” to “ActiveLdap”, since it was changed by the ActiveLdap Developers