Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
binarylogic committed Apr 7, 2009
0 parents commit dd8ac9f
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
.swp
*.log
*.sqlite3
pkg/*
coverage/*
doc/*
benchmarks/*
3 changes: 3 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
== 0.0.9

* Initial release
1 change: 1 addition & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -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 changes: 6 additions & 0 deletions lib/authlogic_ldap.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 51 additions & 0 deletions lib/authlogic_ldap/acts_as_authentic.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 113 additions & 0 deletions lib/authlogic_ldap/session.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 51 additions & 0 deletions lib/authlogic_ldap/version.rb
Original file line number Diff line number Diff line change
@@ -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.