Skip to content
Browse files

Initial commit

  • Loading branch information...
0 parents commit dd8ac9fad8205dde1b7596a15d49f9724e7246de @binarylogic committed
Showing with 254 additions and 0 deletions.
  1. +8 −0 .gitignore
  2. +3 −0 CHANGELOG.rdoc
  3. +1 −0 README.rdoc
  4. +21 −0 Rakefile
  5. +6 −0 lib/authlogic_ldap.rb
  6. +51 −0 lib/authlogic_ldap/acts_as_authentic.rb
  7. +113 −0 lib/authlogic_ldap/session.rb
  8. +51 −0 lib/authlogic_ldap/version.rb
8 .gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+.swp
+*.log
+*.sqlite3
+pkg/*
+coverage/*
+doc/*
+benchmarks/*
3 CHANGELOG.rdoc
@@ -0,0 +1,3 @@
+== 0.0.9
+
+* Initial release
1 README.rdoc
@@ -0,0 +1 @@
+*This gem is still under development and is not completed yet, but when it's done it will be a plugin for Authlogic to allow for LDAP authentication.**
21 Rakefile
@@ -0,0 +1,21 @@
+ENV['RDOCOPT'] = "-S -f html -T hanna"
+
+require "rubygems"
+require "hoe"
+require File.dirname(__FILE__) << "/lib/authlogic_ldap/version"
+
+Hoe.new("Authlogic LDAP", AuthlogicLdap::Version::STRING) do |p|
+ p.name = "authlogic-ldap"
+ p.rubyforge_name = "authlogic-ldap"
+ p.author = "Ben Johnson of Binary Logic"
+ p.email = 'bjohnson@binarylogic.com'
+ p.summary = "Extension of the Authlogic library to add LDAP support."
+ p.description = "Extension of the Authlogic library to add LDAP support."
+ p.url = "http://github.com/binarylogic/authlogic_ldap"
+ p.history_file = "CHANGELOG.rdoc"
+ p.readme_file = "README.rdoc"
+ p.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc"]
+ p.remote_rdoc_dir = ''
+ p.test_globs = ["test/*/test_*.rb", "test/*_test.rb", "test/*/*_test.rb"]
+ p.extra_deps = %w(authlogic ruby-net-ldap)
+end
6 lib/authlogic_ldap.rb
@@ -0,0 +1,6 @@
+require "authlogic_ldap/version"
+require "authlogic_ldap/acts_as_authentic"
+require "authlogic_ldap/session"
+
+ActiveRecord::Base.send(:include, AuthlogicLdap::ActsAsAuthentic)
+Authlogic::Session::Base.send(:include, AuthlogicLdap::Session)
51 lib/authlogic_ldap/acts_as_authentic.rb
@@ -0,0 +1,51 @@
+module AuthlogicLdap
+ module ActsAsAuthentic
+ def self.included(klass)
+ klass.class_eval do
+ extend Config
+ add_acts_as_authentic_module(Methods, :prepend)
+ end
+ end
+
+ module Config
+ # Whether or not to validate the ldap_login field. If set to false ALL ldap validation will need to be
+ # handled by you.
+ #
+ # * <tt>Default:</tt> true
+ # * <tt>Accepts:</tt> Boolean
+ def validate_ldap_login(value = nil)
+ config(:validate_ldap_login, value, true)
+ end
+ alias_method :validate_ldap_login=, :validate_ldap_login
+ end
+
+ module Methods
+ def self.included(klass)
+ klass.class_eval do
+ attr_accessor :ldap_password
+
+ if validate_ldap_login
+ validates_uniqueness_of :ldap_login, :scope => validations_scope, :if => :using_ldap?
+ validates_presence_of :ldap_password, :if => :validate_ldap?
+ validate :validate_ldap, :if => :validate_ldap?
+ end
+ end
+ end
+
+ private
+ def validate_ldap
+ return if errors.count > 0
+
+ ldap = Net::LDAP.new
+ ldap.host = session_class.ldap_host
+ ldap.port = session_class.ldap_port
+ ldap.auth ldap_login, ldap_password
+ errors.add_to_base(ldap.get_operation_result.message) if !ldap.bind
+ end
+
+ def validate_ldap?
+ ldap_login_changed? && !ldap_login.blank?
+ end
+ end
+ end
+end
113 lib/authlogic_ldap/session.rb
@@ -0,0 +1,113 @@
+module AuthlogicLdap
+ module Session
+ # Add a simple openid_identifier attribute and some validations for the field.
+ def self.included(klass)
+ klass.class_eval do
+ extend Config
+ include Methods
+ end
+ end
+
+ module Config
+ # The host of your LDAP server.
+ #
+ # * <tt>Default:</tt> nil
+ # * <tt>Accepts:</tt> String
+ def ldap_host(value = nil)
+ config(:ldap_host, value)
+ end
+ alias_method :ldap_host=, :ldap_host
+
+ # The port of your LDAP server.
+ #
+ # * <tt>Default:</tt> 389
+ # * <tt>Accepts:</tt> Fixnum, integer
+ def ldap_port(value = nil)
+ config(:ldap_port, value, 389)
+ end
+ alias_method :ldap_port=, :ldap_port
+
+ # Once LDAP authentication has succeeded we need to find the user in the database. By default this just calls the
+ # find_by_ldap_login method provided by ActiveRecord. If you have a more advanced set up and need to find users
+ # differently specify your own method and define your logic in there.
+ #
+ # For example, if you allow users to store multiple ldap logins with their account, you might do something like:
+ #
+ # class User < ActiveRecord::Base
+ # def self.find_by_ldap_login(login)
+ # first(:conditions => ["#{LdapLogin.table_name}.login = ?", login], :join => :ldap_logins)
+ # end
+ # end
+ #
+ # * <tt>Default:</tt> :find_by_ldap_login
+ # * <tt>Accepts:</tt> Symbol
+ def find_by_ldap_login_method(value = nil)
+ config(:find_by_ldap_login_method, value, :find_by_ldap_login)
+ end
+ alias_method :find_by_ldap_login_method=, :find_by_ldap_login_method
+ end
+
+ module Methods
+ def self.included(klass)
+ klass.class_eval do
+ attr_accessor :ldap_login
+ attr_accessor :ldap_password
+ validate :validate_by_ldap, :if => :authenticating_with_ldap?
+ end
+ end
+
+ # Hooks into credentials to print out meaningful credentials for LDAP authentication.
+ def credentials
+ if authenticating_with_ldap?
+ details = {}
+ details[:ldap_login] = send(login_field)
+ details[:ldap_password] = "<protected>"
+ details
+ else
+ super
+ end
+ end
+
+ # Hooks into credentials so that you can pass an :ldap_login and :ldap_password key.
+ def credentials=(value)
+ super
+ values = value.is_a?(Array) ? value : [value]
+ hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
+ if !hash.nil?
+ self.ldap_login = hash[:ldap_login] if hash.key?(:ldap_login)
+ self.ldap_password = hash[:ldap_password] if hash.key?(:ldap_password)
+ end
+ end
+
+ private
+ def authenticating_with_ldap?
+ !ldap_host.blank? && (!ldap_login.blank? || !ldap_password.blank?)
+ end
+
+ def validate_by_ldap
+ errors.add(:ldap_login, I18n.t('error_messages.ldap_login_blank', :default => "can not be blank")) if ldap_login.blank?
+ errors.add(:ldap_password, I18n.t('error_messages.ldap_password_blank', :default => "can not be blank")) if ldap_password.blank?
+ return if errors.count > 0
+
+ ldap = Net::LDAP.new
+ ldap.host = ldap_host
+ ldap.port = ldap_port
+ ldap.auth ldap_login, ldap_password
+ if ldap.bind
+ self.attempted_record = search_for_record(find_by_ldap_login_method, ldap_login)
+ errors.add(:ldap_login, I18n.t('error_messages.ldap_login_not_found', :default => "does not exist")) if attempted_record.blank?
+ else
+ errors.add_to_base(ldap.get_operation_result.message)
+ end
+ end
+
+ def ldap_host
+ self.class.ldap_host
+ end
+
+ def ldap_port
+ self.class.ldap_port
+ end
+ end
+ end
+end
51 lib/authlogic_ldap/version.rb
@@ -0,0 +1,51 @@
+module AuthlogicLdap
+ # A class for describing the current version of a library. The version
+ # consists of three parts: the +major+ number, the +minor+ number, and the
+ # +tiny+ (or +patch+) number.
+ class Version
+ include Comparable
+
+ # A convenience method for instantiating a new Version instance with the
+ # given +major+, +minor+, and +tiny+ components.
+ def self.[](major, minor, tiny)
+ new(major, minor, tiny)
+ end
+
+ attr_reader :major, :minor, :tiny
+
+ # Create a new Version object with the given components.
+ def initialize(major, minor, tiny)
+ @major, @minor, @tiny = major, minor, tiny
+ end
+
+ # Compare this version to the given +version+ object.
+ def <=>(version)
+ to_i <=> version.to_i
+ end
+
+ # Converts this version object to a string, where each of the three
+ # version components are joined by the '.' character. E.g., 2.0.0.
+ def to_s
+ @to_s ||= [@major, @minor, @tiny].join(".")
+ end
+
+ # Converts this version to a canonical integer that may be compared
+ # against other version objects.
+ def to_i
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
+ end
+
+ def to_a
+ [@major, @minor, @tiny]
+ end
+
+ MAJOR = 0
+ MINOR = 0
+ TINY = 9
+
+ # The current version as a Version instance
+ CURRENT = new(MAJOR, MINOR, TINY)
+ # The current version as a String
+ STRING = CURRENT.to_s
+ end
+end

0 comments on commit dd8ac9f

Please sign in to comment.
Something went wrong with that request. Please try again.