avdt_ldap 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/avdt_ldap/avdt_ldap.rb +164 -0
- data/lib/avdt_ldap/configuration.rb +7 -0
- data/lib/avdt_ldap/hash.rb +20 -0
- data/lib/avdt_ldap.rb +4 -0
- metadata +66 -0
@@ -0,0 +1,164 @@
|
|
1
|
+
# AvdtLdap
|
2
|
+
|
3
|
+
# This gem supports LDAP authentication both on sigle and multiple servers
|
4
|
+
# with a minimal configuration.
|
5
|
+
# It requires 'net/ldap' gem.
|
6
|
+
#
|
7
|
+
# USAGE
|
8
|
+
# Single directory authentication:
|
9
|
+
# Autentication attempt will be made on environment-specific directory (i.e "development")
|
10
|
+
#
|
11
|
+
# AvdtLdap.new.valid?(login, password)
|
12
|
+
# => true (false)
|
13
|
+
#
|
14
|
+
# Multiple directories authentication:
|
15
|
+
# Here we have authentication attemps made on 2 directories: the "foobar" and
|
16
|
+
# the default (i.e environment-specific one)
|
17
|
+
#
|
18
|
+
# a = AvdtLdap.new(:directories => [:foobar], :include_default => true)
|
19
|
+
# a.valid?(login,password)
|
20
|
+
# => true (false)
|
21
|
+
#
|
22
|
+
# User's attributes access:
|
23
|
+
# If you have to access (read) user's attributes from the directory you can
|
24
|
+
# use the handy methods provided by the gem. Let's suppose we need two attributes,
|
25
|
+
# the user's name and surname ("givenName" and "sn" attributes on the directory).
|
26
|
+
# Simply access attributes as in the example below:
|
27
|
+
#
|
28
|
+
# a = AvdtLdap.new.valid?(login, password)
|
29
|
+
# name = a.givenname
|
30
|
+
# surname = a.cn
|
31
|
+
#
|
32
|
+
# As you can see methods names reflects attribute's name (but always in downcase).
|
33
|
+
# You can also access the whole attributes hash by calling:
|
34
|
+
|
35
|
+
# a.user_attributes
|
36
|
+
#
|
37
|
+
# On which directory is located the user ?
|
38
|
+
# You can know it by calling the +user_location+ method on your AvdtLdap object:
|
39
|
+
#
|
40
|
+
# location = a.user_location
|
41
|
+
|
42
|
+
class AvdtLdap
|
43
|
+
|
44
|
+
# Used to simplify configuration from rails initializers.
|
45
|
+
# Works with the methods configuration and configure defined below.
|
46
|
+
class << self
|
47
|
+
attr_accessor :configuration
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :directories, :include_default, :user_attributes, :user_location
|
51
|
+
|
52
|
+
# Loads ldap configuration file and sets up the object's parameters
|
53
|
+
def initialize(args = {})
|
54
|
+
if File.exist?(AvdtLdap.configuration.ldap_config_file)
|
55
|
+
@LDAP = YAML.load_file(AvdtLdap.configuration.ldap_config_file).symbolize_keys!
|
56
|
+
else
|
57
|
+
raise "AvdtLdap: File #{AvdtLdap.configuration.ldap_config_file} not found, maybe you forgot to define it ?"
|
58
|
+
end
|
59
|
+
@directories = args[:directories] || []
|
60
|
+
@directories << Rails.env.to_sym if ((@directories.any? and args[:include_default]) or !@directories.any?)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks for user's existance on specified directories. Just pass "login" and
|
64
|
+
# "password" parameters to chech if a user resides on one of the directories.
|
65
|
+
# After this method calling, if the user is authenticated, his (directory)
|
66
|
+
# attributes are availaible.
|
67
|
+
def valid? login, password
|
68
|
+
@directories.each do |ldap|
|
69
|
+
ldap = ldap.to_sym
|
70
|
+
unless @LDAP[ldap].nil?
|
71
|
+
conn = connection(ldap)
|
72
|
+
conn.authenticate("#{attribute(ldap)}=#{login.to_s},#{base(ldap)}", password.to_s)
|
73
|
+
begin
|
74
|
+
# if bind => OK
|
75
|
+
if conn.bind
|
76
|
+
logger.info("Authenticated #{login.to_s} by #{host(ldap)}") if logger
|
77
|
+
@user_attributes = conn.search(:base => base(ldap),:filter => Net::LDAP::Filter.eq(attribute(ldap),login.to_s)).first.each do |k,v|
|
78
|
+
class_eval "attr_reader :#{k}"
|
79
|
+
self.instance_variable_set "@#{k}".to_sym, v
|
80
|
+
end
|
81
|
+
@user_location = ldap
|
82
|
+
return true
|
83
|
+
else
|
84
|
+
logger.info("Error attempting to authenticate #{login.to_s} by #{host(ldap)}: #{conn.get_operation_result.code} #{conn.get_operation_result.message}") if logger
|
85
|
+
end
|
86
|
+
rescue Net::LDAP::LdapError => error
|
87
|
+
logger.info("Error attempting to authenticate #{login.to_s} by #{host(ldap)}: #{error.message}") if logger
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
else
|
91
|
+
logger.info "ERROR ! \"#{ldap}\" directory data are missing in ldap.yml" if logger
|
92
|
+
raise Net::LDAP::LdapError, "\"#{ldap}\" directory data are missing in ldap.yml"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
# Adds configuration ability to the gem
|
99
|
+
def self.configuration
|
100
|
+
@configuration ||= Configuration.new
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.configure
|
104
|
+
yield(configuration)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
# Given a directory name returns a connection to that server using parameters
|
110
|
+
# specified in ldap.yml
|
111
|
+
def connection(which_ldap)
|
112
|
+
load_ldap_library
|
113
|
+
if @ldap_lib == "net/ldap"
|
114
|
+
Net::LDAP.new(:host => host(which_ldap), :port => port(which_ldap), :encryption => (:simple_tls if ssl?(which_ldap)))
|
115
|
+
else
|
116
|
+
(ssl?(which_ldap) ? LDAP::SSLConn : LDAP::Conn).new(host(which_ldap),port(which_ldap))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Given a directory return it's host name
|
121
|
+
def host(which_ldap)
|
122
|
+
@LDAP[which_ldap][:host] || "127.0.0.1"
|
123
|
+
end
|
124
|
+
|
125
|
+
# Given a directory returns it's host port
|
126
|
+
def port(which_ldap)
|
127
|
+
ssl?(which_ldap) ? (@LDAP[which_ldap][:port] || 636) : (@LDAP[which_ldap][:port] || 389)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Given a directory returns it's attribute (example: uid)
|
131
|
+
def attribute(which_ldap)
|
132
|
+
@LDAP[which_ldap][:attribute] || "uid"
|
133
|
+
end
|
134
|
+
|
135
|
+
# Given a directory returns it's base path (example ou=People,dc=foo,dc=bar)
|
136
|
+
def base(which_ldap)
|
137
|
+
@LDAP[which_ldap][:base] || "%s"
|
138
|
+
end
|
139
|
+
|
140
|
+
# Given a directory returns if connection should use ssl
|
141
|
+
def ssl?(which_ldap)
|
142
|
+
@LDAP[which_ldap][:ssl] ? true : false
|
143
|
+
end
|
144
|
+
|
145
|
+
# Loads the right ldap library
|
146
|
+
def load_ldap_library
|
147
|
+
return if @ldap_library_loaded
|
148
|
+
begin
|
149
|
+
require "ldap"
|
150
|
+
require "ldap/control"
|
151
|
+
@ldap_lib = "ldap/control"
|
152
|
+
rescue LoadError
|
153
|
+
require "net/ldap"
|
154
|
+
@ldap_lib = "net/ldap"
|
155
|
+
end
|
156
|
+
@ldap_library_loaded = true
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns Rails Default logger
|
160
|
+
def logger
|
161
|
+
Rails.logger
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Transforms all the hash keys from strings to symbols.
|
4
|
+
# Example:
|
5
|
+
# {"one" => "two", "three" => "four"}.symbolize_keys
|
6
|
+
# => {:one=>"two", :three=>"four"}
|
7
|
+
#
|
8
|
+
def symbolize_keys!
|
9
|
+
t = self.dup
|
10
|
+
self.clear
|
11
|
+
t.each_pair do |k,v|
|
12
|
+
self[k.to_sym] = v
|
13
|
+
if v.kind_of?(Hash)
|
14
|
+
v.symbolize_keys!
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
data/lib/avdt_ldap.rb
ADDED
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: avdt_ldap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.7
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alessandro Verlato
|
9
|
+
- Davide Targa
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2011-06-21 00:00:00.000000000 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: net-ldap
|
18
|
+
requirement: &79290600 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *79290600
|
27
|
+
description: This gem can manage user authentication on multiple LDAP directories
|
28
|
+
that can reside either on same server or not.
|
29
|
+
email:
|
30
|
+
- averlato@gmail.com
|
31
|
+
- davide.targa@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- lib/avdt_ldap/hash.rb
|
37
|
+
- lib/avdt_ldap/avdt_ldap.rb
|
38
|
+
- lib/avdt_ldap/configuration.rb
|
39
|
+
- lib/avdt_ldap.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://rubygems.org/gems/avdt_ldap
|
42
|
+
licenses: []
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.6.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Simple LDAP authentication library for user authentication on multiple LDAP
|
65
|
+
directories
|
66
|
+
test_files: []
|