dm-ldap-adapter 0.3.1 → 0.3.2
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/History.txt +16 -0
- data/Manifest.txt +5 -1
- data/Manifest.txt- +27 -0
- data/README.txt +11 -1
- data/example/posix.rb +4 -0
- data/lib/adapters/ldap_adapter.rb +17 -8
- data/lib/ldap/{ldap_facade.rb → net_ldap_facade.rb} +2 -1
- data/lib/ldap/ruby_ldap_facade.rb +274 -0
- data/lib/ldap/version.rb +1 -1
- data/net-ldap.txt +11 -0
- data/ruby-ldap.txt +11 -0
- data/spec/multi_value_attributes_spec.rb +1 -1
- metadata +8 -2
data/History.txt
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
version 0.3.2
|
2
|
+
=============
|
3
|
+
|
4
|
+
* lazy property are not loaded from ldap anymore
|
5
|
+
|
6
|
+
* new facade which uses ruby-ldap, since it has better support for ldap protocol and is about 30% faster with search queries
|
7
|
+
|
8
|
+
version 0.3.1
|
9
|
+
=============
|
10
|
+
|
11
|
+
* fixed LdapArray bug in collections
|
12
|
+
|
13
|
+
* default of LdapArray is now a new object for each resource instance
|
14
|
+
|
15
|
+
* allow Serial to be used in dn_prefix
|
16
|
+
|
1
17
|
version 0.3.0
|
2
18
|
=============
|
3
19
|
|
data/Manifest.txt
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
History.txt
|
2
2
|
MIT-LICENSE
|
3
3
|
Manifest.txt
|
4
|
+
Manifest.txt-
|
4
5
|
README-example.markdown
|
5
6
|
README.txt
|
6
7
|
Rakefile
|
@@ -13,9 +14,12 @@ lib/adapters/simple_adapter.rb
|
|
13
14
|
lib/dummy_ldap_resource.rb
|
14
15
|
lib/ldap/array.rb
|
15
16
|
lib/ldap/digest.rb
|
16
|
-
lib/ldap/
|
17
|
+
lib/ldap/net_ldap_facade.rb
|
18
|
+
lib/ldap/ruby_ldap_facade.rb
|
17
19
|
lib/ldap/version.rb
|
18
20
|
lib/ldap_resource.rb
|
21
|
+
net-ldap.txt
|
22
|
+
ruby-ldap.txt
|
19
23
|
spec/assiociations_ldap_adapter_spec.rb
|
20
24
|
spec/authentication_ldap_adapter_spec.rb
|
21
25
|
spec/ldap_adapter_spec.rb
|
data/Manifest.txt-
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
History.txt
|
2
|
+
MIT-LICENSE
|
3
|
+
Manifest.txt
|
4
|
+
README-example.markdown
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
example/identity_map.rb
|
8
|
+
example/posix.rb
|
9
|
+
ldap-commands.txt
|
10
|
+
lib/adapters/ldap_adapter.rb
|
11
|
+
lib/adapters/memory_adapter.rb
|
12
|
+
lib/adapters/simple_adapter.rb
|
13
|
+
lib/dummy_ldap_resource.rb
|
14
|
+
lib/ldap/array.rb
|
15
|
+
lib/ldap/digest.rb
|
16
|
+
lib/ldap/ldap_facade.rb
|
17
|
+
lib/ldap/version.rb
|
18
|
+
lib/ldap_resource.rb
|
19
|
+
spec/assiociations_ldap_adapter_spec.rb
|
20
|
+
spec/authentication_ldap_adapter_spec.rb
|
21
|
+
spec/ldap_adapter_spec.rb
|
22
|
+
spec/multi_repository_spec.rb
|
23
|
+
spec/multi_value_attributes_spec.rb
|
24
|
+
spec/spec.opts
|
25
|
+
spec/spec_helper.rb
|
26
|
+
test.db
|
27
|
+
test.ldif
|
data/README.txt
CHANGED
@@ -88,7 +88,17 @@ and
|
|
88
88
|
|
89
89
|
gives the same result when *all* names are `NULL` !!!
|
90
90
|
|
91
|
-
OR conditions
|
91
|
+
=== OR conditions
|
92
|
+
|
93
|
+
or-conditions can be done with :conditions option but only of the form "<property_name> <comparator> <value> [or <property_name> <comparator> <value>]*" where the comparator is one of "=", "like". it can be also combined with extra ANDs like this example
|
94
|
+
|
95
|
+
Contact.all(:name.like => "A%", :conditions => ["phone like '+49%' or mobile like '+49%'"])
|
96
|
+
|
97
|
+
=== using the ruby-ldap gem
|
98
|
+
|
99
|
+
just require the right facade before require the adapter:
|
100
|
+
|
101
|
+
require 'ldap/ruby_ldap_facade'
|
92
102
|
|
93
103
|
=== multiple repositories
|
94
104
|
|
data/example/posix.rb
CHANGED
@@ -19,6 +19,10 @@ dummy = true #uncomment this to use dummy, i.e. a database instead of ldap
|
|
19
19
|
dummy = false # uncomment this to use ldap
|
20
20
|
unless dummy
|
21
21
|
require 'ldap_resource'
|
22
|
+
|
23
|
+
# comment this out if you want to use "net/ldap"
|
24
|
+
require 'ldap/ruby_ldap_facade'
|
25
|
+
|
22
26
|
require 'adapters/ldap_adapter'
|
23
27
|
|
24
28
|
DataMapper.setup(:default, {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'adapters/simple_adapter'
|
2
2
|
# load the ldap facade only if NOT loaded before
|
3
|
-
require 'ldap/
|
3
|
+
require 'ldap/net_ldap_facade' unless Object.const_defined?('Ldap') and Ldap.const_defined?('LdapFacade')
|
4
4
|
|
5
5
|
module Ldap
|
6
6
|
|
@@ -131,10 +131,15 @@ module DataMapper
|
|
131
131
|
key_properties(resource).field)
|
132
132
|
resource_dup.send("#{key_properties(resource).name}=".to_sym, id)
|
133
133
|
props[key_properties(resource).field.to_sym] = "#{id}"
|
134
|
-
key_value =
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
key_value = begin
|
135
|
+
ldap.create_object(resource.model.dn_prefix(resource_dup),
|
136
|
+
resource.model.treebase,
|
137
|
+
key_properties(resource).field,
|
138
|
+
props, resource.model.multivalue_field)
|
139
|
+
rescue => e
|
140
|
+
raise e unless resource.model.multivalue_field
|
141
|
+
# TODO something with creating these multivalue objects
|
142
|
+
end
|
138
143
|
logger.debug { "resource #{resource.inspect} key value: #{key_value.inspect}" + ", multivalue_field: " + resource.model.multivalue_field.to_s }
|
139
144
|
if key_value and !key.nil?
|
140
145
|
key.set!(resource, key_value.to_i)
|
@@ -225,9 +230,11 @@ module DataMapper
|
|
225
230
|
# the found resource or nil
|
226
231
|
# @see SimpleAdapter#read_resource
|
227
232
|
def read_resource(query)
|
233
|
+
field_names = query.fields.collect {|f| f.field }
|
228
234
|
result = ldap.read_objects(query.model.treebase,
|
229
235
|
query.model.key.collect { |k| k.field},
|
230
|
-
to_ldap_conditions(query)
|
236
|
+
to_ldap_conditions(query),
|
237
|
+
field_names)
|
231
238
|
if query.model.multivalue_field
|
232
239
|
resource = result.detect do |item|
|
233
240
|
# run over all values of the multivalue field
|
@@ -265,14 +272,16 @@ module DataMapper
|
|
265
272
|
# the array of found resources
|
266
273
|
# @see SimpleAdapter#read_resources
|
267
274
|
def read_resources(query)
|
275
|
+
field_names = query.fields.collect {|f| f.field }
|
268
276
|
result = ldap.read_objects(query.model.treebase,
|
269
277
|
query.model.key.collect { |k| k.field },
|
270
|
-
to_ldap_conditions(query)
|
278
|
+
to_ldap_conditions(query),
|
279
|
+
field_names)
|
271
280
|
if query.model.multivalue_field
|
272
281
|
props_result = []
|
273
282
|
result.each do |props|
|
274
283
|
# run over all values of the multivalue field
|
275
|
-
props[query.model.multivalue_field].each do |value|
|
284
|
+
(props[query.model.multivalue_field] || []).each do |value|
|
276
285
|
values = query.fields.collect do |f|
|
277
286
|
if query.model.multivalue_field == f.field.to_sym
|
278
287
|
value
|
@@ -63,7 +63,7 @@ module Ldap
|
|
63
63
|
# @param key_fields Array of fields which carries the integer unique id(s) of the entity
|
64
64
|
# @param Array of conditions for the search
|
65
65
|
# @return Array of Hashes with a name/values pair for each attribute
|
66
|
-
def read_objects(treebase, key_fields, conditions)
|
66
|
+
def read_objects(treebase, key_fields, conditions, field_names)
|
67
67
|
filters = []
|
68
68
|
conditions.each do |cond|
|
69
69
|
c = cond[2]
|
@@ -146,6 +146,7 @@ module Ldap
|
|
146
146
|
logger.debug { "search filter: (#{filter.to_s})" }
|
147
147
|
result = []
|
148
148
|
@ldap.search( :base => "#{treebase},#{@ldap.base}",
|
149
|
+
:attributes => field_names,
|
149
150
|
:filter => filter ) do |res|
|
150
151
|
map = to_map(res)
|
151
152
|
#puts map[key_field.to_sym]
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'ldap'
|
2
|
+
require 'net/ldap'
|
3
|
+
require 'slf4r'
|
4
|
+
|
5
|
+
module Ldap
|
6
|
+
class Connection < LDAP::Conn
|
7
|
+
|
8
|
+
attr_reader :base, :host, :port
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
super(config[:host], config[:port])
|
12
|
+
@base = config[:base]
|
13
|
+
@port = config[:port]
|
14
|
+
@host = config[:host]
|
15
|
+
set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class LdapFacade
|
21
|
+
|
22
|
+
# @param config Hash for the ldap connection
|
23
|
+
def self.open(config)
|
24
|
+
ldap2 = Connection.new(config)
|
25
|
+
ldap2.bind(config[:auth][:username], config[:auth][:password]) do |ldap|
|
26
|
+
yield ldap
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
include ::Slf4r::Logger
|
31
|
+
|
32
|
+
# @param config Hash for the ldap connection
|
33
|
+
def initialize(config)
|
34
|
+
if config.is_a? Hash
|
35
|
+
@ldap2 = Connection.new(config)
|
36
|
+
@ldap2.bind(config[:auth][:username], config[:auth][:password])
|
37
|
+
else
|
38
|
+
@ldap2 = config
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def retrieve_next_id(treebase, key_field)
|
43
|
+
max = 0
|
44
|
+
@ldap2.search("#{treebase},#{@ldap2.base}",
|
45
|
+
LDAP::LDAP_SCOPE_SUBTREE,
|
46
|
+
"(objectclass=*)",
|
47
|
+
[key_field]) do |entry|
|
48
|
+
n = (entry.vals(key_field) || [0]).first.to_i
|
49
|
+
max = n if max < n
|
50
|
+
end
|
51
|
+
max + 1
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param dn_prefix String the prefix of the dn
|
55
|
+
# @param treebase the treebase of the dn or any search
|
56
|
+
# @param key_field field which carries the integer unique id of the entity
|
57
|
+
# @param props Hash of the ldap attributes of the new ldap object
|
58
|
+
# @return nil in case of an error or the new id of the created object
|
59
|
+
def create_object(dn_prefix, treebase, key_field, props, silence = false)
|
60
|
+
base = "#{treebase},#{@ldap2.base}"
|
61
|
+
mods = props.collect do |k,v|
|
62
|
+
LDAP.mod(LDAP::LDAP_MOD_ADD, k.to_s, v.is_a?(Array) ? v : [v.to_s] )
|
63
|
+
end
|
64
|
+
if @ldap2.add( dn(dn_prefix, treebase), mods)
|
65
|
+
# :attributes => props) and @ldap.get_operation_result.code.to_s == "0"
|
66
|
+
props[key_field.downcase.to_sym]
|
67
|
+
else
|
68
|
+
unless silence
|
69
|
+
msg = ldap_error("create",
|
70
|
+
dn(dn_prefix, treebase)) + "\n\t#{props.inspect}"
|
71
|
+
# TODO maybe raise always an error
|
72
|
+
if @ldap2.get_operation_result.code.to_s == "68"
|
73
|
+
raise ::DataMapper::PersistenceError.new(msg)
|
74
|
+
else
|
75
|
+
logger.warn(msg)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param treebase the treebase of the search
|
83
|
+
# @param key_fields Array of fields which carries the integer unique id(s) of the entity
|
84
|
+
# @param Array of conditions for the search
|
85
|
+
# @return Array of Hashes with a name/values pair for each attribute
|
86
|
+
def read_objects(treebase, key_fields, conditions, field_names)
|
87
|
+
filters = []
|
88
|
+
conditions.each do |cond|
|
89
|
+
c = cond[2]
|
90
|
+
case cond[0]
|
91
|
+
when :or_operator
|
92
|
+
f = nil
|
93
|
+
cond[1].each do |cc|
|
94
|
+
ff = case cc[0]
|
95
|
+
when :eql
|
96
|
+
Net::LDAP::Filter.eq( cc[1].to_s, cc[2].to_s )
|
97
|
+
when :gte
|
98
|
+
f = Net::LDAP::Filter.ge( cc[1].to_s, cc[2].to_s )
|
99
|
+
when :lte
|
100
|
+
f = Net::LDAP::Filter.le( cc[1].to_s, cc[2].to_s )
|
101
|
+
when :like
|
102
|
+
f = Net::LDAP::Filter.eq( cc[1].to_s, cc[2].to_s.gsub(/%/, "*").gsub(/_/, "*").gsub(/\*\*/, "*") )
|
103
|
+
else
|
104
|
+
logger.error(cc[0].to_s + " needs coding")
|
105
|
+
end
|
106
|
+
if f
|
107
|
+
f = f | ff
|
108
|
+
else
|
109
|
+
f = ff
|
110
|
+
end
|
111
|
+
end
|
112
|
+
when :eql
|
113
|
+
if c.nil?
|
114
|
+
f = ~ Net::LDAP::Filter.pres( cond[1].to_s )
|
115
|
+
elsif c.class == Array
|
116
|
+
f = nil
|
117
|
+
c.each do |cc|
|
118
|
+
if f
|
119
|
+
f = f | Net::LDAP::Filter.eq( cond[1].to_s, cc.to_s )
|
120
|
+
else
|
121
|
+
f = Net::LDAP::Filter.eq( cond[1].to_s, cc.to_s )
|
122
|
+
end
|
123
|
+
end
|
124
|
+
#elsif c.class == Range
|
125
|
+
# p c
|
126
|
+
# f = Net::LDAP::Filter.ge( cond[1].to_s, c.begin.to_s ) & Net::LDAP::Filter.le( cond[1].to_s, c.end.to_s )
|
127
|
+
else
|
128
|
+
f = Net::LDAP::Filter.eq( cond[1].to_s, c.to_s )
|
129
|
+
end
|
130
|
+
when :gte
|
131
|
+
f = Net::LDAP::Filter.ge( cond[1].to_s, c.to_s )
|
132
|
+
when :lte
|
133
|
+
f = Net::LDAP::Filter.le( cond[1].to_s, c.to_s )
|
134
|
+
when :not
|
135
|
+
if c.nil?
|
136
|
+
f = Net::LDAP::Filter.pres( cond[1].to_s )
|
137
|
+
elsif c.class == Array
|
138
|
+
f = nil
|
139
|
+
c.each do |cc|
|
140
|
+
if f
|
141
|
+
f = f | Net::LDAP::Filter.eq( cond[1].to_s, cc.to_s )
|
142
|
+
else
|
143
|
+
f = Net::LDAP::Filter.eq( cond[1].to_s, cc.to_s )
|
144
|
+
end
|
145
|
+
end
|
146
|
+
f = ~ f
|
147
|
+
else
|
148
|
+
f = ~ Net::LDAP::Filter.eq( cond[1].to_s, c.to_s )
|
149
|
+
end
|
150
|
+
when :like
|
151
|
+
f = Net::LDAP::Filter.eq( cond[1].to_s, c.to_s.gsub(/%/, "*").gsub(/_/, "*").gsub(/\*\*/, "*") )
|
152
|
+
else
|
153
|
+
logger.error(cond[0].to_s + " needs coding")
|
154
|
+
end
|
155
|
+
filters << f if f
|
156
|
+
end
|
157
|
+
|
158
|
+
filter = nil
|
159
|
+
filters.each do |f|
|
160
|
+
if filter.nil?
|
161
|
+
filter = f
|
162
|
+
else
|
163
|
+
filter = filter & f
|
164
|
+
end
|
165
|
+
end
|
166
|
+
logger.debug { "search filter: (#{filter.to_s})" }
|
167
|
+
result = []
|
168
|
+
begin
|
169
|
+
@ldap2.search("#{treebase},#{@ldap2.base}",
|
170
|
+
LDAP::LDAP_SCOPE_SUBTREE,
|
171
|
+
filter.to_s == "" ? "(objectclass=*)" : filter.to_s.gsub(/\(\(/, "(").gsub(/\)\)/, ")"),
|
172
|
+
field_names) do |res|
|
173
|
+
|
174
|
+
map = to_map(res)
|
175
|
+
#puts map[key_field.to_sym]
|
176
|
+
# TODO maybe make filter which removes this unless
|
177
|
+
# TODO move this into the ldap_Adapter to make it more general, so that
|
178
|
+
# all field with Integer gets converted, etc
|
179
|
+
result << map if key_fields.select do |key_field|
|
180
|
+
if map.member? key_field.to_sym
|
181
|
+
# convert field to integer
|
182
|
+
map[key_field.to_sym] = [map[key_field.to_sym].collect { |k| k.to_i != 0 ? k.to_s : k }].flatten
|
183
|
+
true
|
184
|
+
end
|
185
|
+
end.size > 0 # i.e. there was at least one key_field in the map
|
186
|
+
end
|
187
|
+
rescue RuntimeError => e
|
188
|
+
raise e unless e.message == "no result returned by search"
|
189
|
+
end
|
190
|
+
result
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
# @param dn_prefix String the prefix of the dn
|
195
|
+
# @param treebase the treebase of the dn or any search
|
196
|
+
# @param actions the add/replace/delete actions on the attributes
|
197
|
+
# @return nil in case of an error or true
|
198
|
+
def update_object(dn_prefix, treebase, actions)
|
199
|
+
mods = actions.collect do |act|
|
200
|
+
mod_op = case act[0]
|
201
|
+
when :add
|
202
|
+
LDAP::LDAP_MOD_ADD
|
203
|
+
when :replace
|
204
|
+
LDAP::LDAP_MOD_REPLACE
|
205
|
+
when :delete
|
206
|
+
LDAP::LDAP_MOD_DELETE
|
207
|
+
end
|
208
|
+
LDAP.mod(mod_op, act[1].to_s, act[2] == [] ? [] : [act[2].to_s])
|
209
|
+
end
|
210
|
+
if @ldap2.modify( dn(dn_prefix, treebase),
|
211
|
+
mods )
|
212
|
+
true
|
213
|
+
else
|
214
|
+
logger.warn(ldap_error("update",
|
215
|
+
dn(dn_prefix, treebase) + "\n\t#{actions.inspect}"))
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# @param dn_prefix String the prefix of the dn
|
221
|
+
# @param treebase the treebase of the dn or any search
|
222
|
+
# @return nil in case of an error or true
|
223
|
+
def delete_object(dn_prefix, treebase)
|
224
|
+
if @ldap2.delete( dn(dn_prefix, treebase) )
|
225
|
+
true
|
226
|
+
else
|
227
|
+
logger.warn(ldap_error("delete",
|
228
|
+
dn(dn_prefix, treebase)))
|
229
|
+
|
230
|
+
nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
# @param dn String for identifying the ldap object
|
236
|
+
# @param password String to be used for authenticate to the dn
|
237
|
+
def authenticate(dn, password)
|
238
|
+
Net::LDAP.new( { :host => @ldap2.host,
|
239
|
+
:port => @ldap2.port,
|
240
|
+
:auth => {
|
241
|
+
:method => :simple,
|
242
|
+
:username => dn,
|
243
|
+
:password => password
|
244
|
+
},
|
245
|
+
:base => @ldap2.base
|
246
|
+
} ).bind
|
247
|
+
end
|
248
|
+
|
249
|
+
# helper to concat the dn from the various parts
|
250
|
+
# @param dn_prefix String the prefix of the dn
|
251
|
+
# @param treebase the treebase of the dn or any search
|
252
|
+
# @return the complete dn String
|
253
|
+
def dn(dn_prefix, treebase)
|
254
|
+
"#{dn_prefix},#{treebase},#{@ldap2.base}"
|
255
|
+
end
|
256
|
+
|
257
|
+
private
|
258
|
+
|
259
|
+
# helper to extract the Hash from the ldap search result
|
260
|
+
# @param Entry from the ldap_search
|
261
|
+
# @return Hash with name/value pairs of the entry
|
262
|
+
def to_map(entry)
|
263
|
+
map = {}
|
264
|
+
LDAP::entry2hash(entry).each do |k,v|
|
265
|
+
map[k.downcase.to_sym] = v
|
266
|
+
end
|
267
|
+
map
|
268
|
+
end
|
269
|
+
|
270
|
+
def ldap_error(method, dn)
|
271
|
+
"#{method} error: (#{@ldap2.get_operation_result.code}) #{@ldap2.get_operation_result.message}\n\tDN: #{dn}"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
data/lib/ldap/version.rb
CHANGED
data/net-ldap.txt
ADDED
data/ruby-ldap.txt
ADDED
@@ -6,7 +6,7 @@ class Contact
|
|
6
6
|
|
7
7
|
property :id, Serial, :field => "uidnumber"
|
8
8
|
property :login, String, :field => "uid", :unique_index => true
|
9
|
-
property :hashed_password, String, :field => "userpassword", :access => :private
|
9
|
+
property :hashed_password, String, :field => "userpassword", :access => :private, :lazy => true
|
10
10
|
property :name, String, :field => "cn"
|
11
11
|
property :mail, LdapArray
|
12
12
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-ldap-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mkristian
|
@@ -64,10 +64,13 @@ extra_rdoc_files:
|
|
64
64
|
- Manifest.txt
|
65
65
|
- README.txt
|
66
66
|
- ldap-commands.txt
|
67
|
+
- net-ldap.txt
|
68
|
+
- ruby-ldap.txt
|
67
69
|
files:
|
68
70
|
- History.txt
|
69
71
|
- MIT-LICENSE
|
70
72
|
- Manifest.txt
|
73
|
+
- Manifest.txt-
|
71
74
|
- README-example.markdown
|
72
75
|
- README.txt
|
73
76
|
- Rakefile
|
@@ -80,9 +83,12 @@ files:
|
|
80
83
|
- lib/dummy_ldap_resource.rb
|
81
84
|
- lib/ldap/array.rb
|
82
85
|
- lib/ldap/digest.rb
|
83
|
-
- lib/ldap/
|
86
|
+
- lib/ldap/net_ldap_facade.rb
|
87
|
+
- lib/ldap/ruby_ldap_facade.rb
|
84
88
|
- lib/ldap/version.rb
|
85
89
|
- lib/ldap_resource.rb
|
90
|
+
- net-ldap.txt
|
91
|
+
- ruby-ldap.txt
|
86
92
|
- spec/assiociations_ldap_adapter_spec.rb
|
87
93
|
- spec/authentication_ldap_adapter_spec.rb
|
88
94
|
- spec/ldap_adapter_spec.rb
|