ruby-activeldap 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/test/test_adapter.rb +17 -0
  2. data/test/test_associations.rb +19 -0
  3. data/test/test_attributes.rb +2 -1
  4. data/test/test_base.rb +28 -1
  5. data/test/test_base_per_instance.rb +2 -1
  6. data/test/test_callback.rb +2 -2
  7. data/test/test_connection.rb +2 -1
  8. data/test/test_connection_per_dn.rb +81 -0
  9. data/test/test_dn.rb +3 -2
  10. data/test/test_find.rb +35 -1
  11. data/test/test_object_class.rb +12 -1
  12. data/test/test_reflection.rb +16 -10
  13. data/test/test_schema.rb +141 -2
  14. data/test/test_user.rb +14 -4
  15. metadata +7 -104
  16. data/CHANGES +0 -397
  17. data/COPYING +0 -340
  18. data/LICENSE +0 -58
  19. data/Manifest.txt +0 -99
  20. data/README +0 -85
  21. data/Rakefile +0 -70
  22. data/TODO +0 -23
  23. data/benchmark/bench-al.rb +0 -152
  24. data/examples/config.yaml.example +0 -5
  25. data/examples/example.der +0 -0
  26. data/examples/example.jpg +0 -0
  27. data/examples/groupadd +0 -41
  28. data/examples/groupdel +0 -35
  29. data/examples/groupls +0 -49
  30. data/examples/groupmod +0 -42
  31. data/examples/lpasswd +0 -55
  32. data/examples/objects/group.rb +0 -13
  33. data/examples/objects/ou.rb +0 -4
  34. data/examples/objects/user.rb +0 -20
  35. data/examples/ouadd +0 -38
  36. data/examples/useradd +0 -45
  37. data/examples/useradd-binary +0 -50
  38. data/examples/userdel +0 -34
  39. data/examples/userls +0 -50
  40. data/examples/usermod +0 -42
  41. data/examples/usermod-binary-add +0 -47
  42. data/examples/usermod-binary-add-time +0 -51
  43. data/examples/usermod-binary-del +0 -48
  44. data/examples/usermod-lang-add +0 -43
  45. data/lib/active_ldap.rb +0 -964
  46. data/lib/active_ldap/adapter/base.rb +0 -461
  47. data/lib/active_ldap/adapter/ldap.rb +0 -232
  48. data/lib/active_ldap/adapter/ldap_ext.rb +0 -69
  49. data/lib/active_ldap/adapter/net_ldap.rb +0 -288
  50. data/lib/active_ldap/adapter/net_ldap_ext.rb +0 -29
  51. data/lib/active_ldap/association/belongs_to.rb +0 -40
  52. data/lib/active_ldap/association/belongs_to_many.rb +0 -39
  53. data/lib/active_ldap/association/collection.rb +0 -80
  54. data/lib/active_ldap/association/has_many.rb +0 -40
  55. data/lib/active_ldap/association/has_many_wrap.rb +0 -55
  56. data/lib/active_ldap/association/proxy.rb +0 -89
  57. data/lib/active_ldap/associations.rb +0 -162
  58. data/lib/active_ldap/attributes.rb +0 -203
  59. data/lib/active_ldap/base.rb +0 -1510
  60. data/lib/active_ldap/callbacks.rb +0 -19
  61. data/lib/active_ldap/command.rb +0 -46
  62. data/lib/active_ldap/configuration.rb +0 -106
  63. data/lib/active_ldap/connection.rb +0 -142
  64. data/lib/active_ldap/distinguished_name.rb +0 -246
  65. data/lib/active_ldap/ldap_error.rb +0 -74
  66. data/lib/active_ldap/object_class.rb +0 -74
  67. data/lib/active_ldap/schema.rb +0 -299
  68. data/lib/active_ldap/timeout.rb +0 -75
  69. data/lib/active_ldap/timeout_stub.rb +0 -17
  70. data/lib/active_ldap/user_password.rb +0 -92
  71. data/lib/active_ldap/validations.rb +0 -76
  72. data/rails/plugin/active_ldap/README +0 -54
  73. data/rails/plugin/active_ldap/generators/scaffold_al/scaffold_al_generator.rb +0 -7
  74. data/rails/plugin/active_ldap/generators/scaffold_al/templates/ldap.yml +0 -21
  75. data/rails/plugin/active_ldap/init.rb +0 -12
  76. data/test/TODO +0 -2
  77. data/test/al-test-utils.rb +0 -381
  78. data/test/command.rb +0 -62
  79. data/test/config.yaml.sample +0 -6
  80. data/test/run-test.rb +0 -29
  81. data/test/test-unit-ext.rb +0 -2
  82. data/test/test-unit-ext/always-show-result.rb +0 -28
  83. data/test/test-unit-ext/priority.rb +0 -163
@@ -1,232 +0,0 @@
1
- require 'active_ldap/adapter/base'
2
-
3
- module ActiveLdap
4
- module Adapter
5
- class Base
6
- class << self
7
- def ldap_connection(options)
8
- unless defined?(::LDAP)
9
- require 'active_ldap/adapter/ldap_ext'
10
- end
11
- Ldap.new(options)
12
- end
13
- end
14
- end
15
-
16
- class Ldap < Base
17
- module Method
18
- class SSL
19
- def connect(host, port)
20
- LDAP::SSLConn.new(host, port, false)
21
- end
22
- end
23
-
24
- class TLS
25
- def connect(host, port)
26
- LDAP::SSLConn.new(host, port, true)
27
- end
28
- end
29
-
30
- class Plain
31
- def connect(host, port)
32
- LDAP::Conn.new(host, port)
33
- end
34
- end
35
- end
36
-
37
- def connect(options={})
38
- super do |host, port, method|
39
- method.connect(host, port)
40
- end
41
- end
42
-
43
- def unbind(options={})
44
- return unless bound?
45
- operation(options) do
46
- execute(:unbind)
47
- end
48
- end
49
-
50
- def bind(options={})
51
- super do
52
- @connection.error_message
53
- end
54
- end
55
-
56
- def bind_as_anonymous(options={})
57
- super do
58
- execute(:bind)
59
- true
60
- end
61
- end
62
-
63
- def bound?
64
- connecting? and @connection.bound?
65
- end
66
-
67
- def search(options={}, &block)
68
- super(options) do |base, scope, filter, attrs, limit, callback|
69
- begin
70
- i = 0
71
- execute(:search, base, scope, filter, attrs) do |entry|
72
- i += 1
73
- attributes = {}
74
- entry.attrs.each do |attr|
75
- attributes[attr] = entry.vals(attr)
76
- end
77
- callback.call([entry.dn, attributes], block)
78
- break if limit and limit >= i
79
- end
80
- rescue RuntimeError
81
- if $!.message == "no result returned by search"
82
- @logger.debug {"No matches for #{filter} and attrs " +
83
- "#{attrs.inspect}"}
84
- else
85
- raise
86
- end
87
- end
88
- end
89
- end
90
-
91
- def to_ldif(dn, attributes)
92
- ldif = LDAP::LDIF.to_ldif("dn", [dn.dup])
93
- attributes.sort_by do |key, value|
94
- key
95
- end.each do |key, values|
96
- ldif << LDAP::LDIF.to_ldif(key, values)
97
- end
98
- ldif
99
- end
100
-
101
- def load(ldifs, options={})
102
- super do |ldif|
103
- LDAP::LDIF.parse_entry(ldif).send(@connection)
104
- end
105
- end
106
-
107
- def delete(targets, options={})
108
- super do |target|
109
- execute(:delete, target)
110
- end
111
- end
112
-
113
- def add(dn, entries, options={})
114
- super do |dn, entries|
115
- execute(:add, dn, parse_entries(entries))
116
- end
117
- end
118
-
119
- def modify(dn, entries, options={})
120
- super do |dn, entries|
121
- execute(:modify, dn, parse_entries(entries))
122
- end
123
- end
124
-
125
- private
126
- def prepare_connection(options={})
127
- operation(options) do
128
- @connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
129
- end
130
- end
131
-
132
- def root_dse(attributes, options={})
133
- sec = options[:sec] || 0
134
- usec = options[:usec] || 0
135
- @connection.root_dse(attributes, sec, usec)
136
- end
137
-
138
- def execute(method, *args, &block)
139
- begin
140
- @connection.send(method, *args, &block)
141
- rescue LDAP::ResultError
142
- @connection.assert_error_code
143
- raise $!.message
144
- end
145
- end
146
-
147
- def with_timeout(try_reconnect=true, options={}, &block)
148
- begin
149
- super
150
- rescue LDAP::ServerDown => e
151
- @logger.error {"LDAP server is down: #{e.message}"}
152
- retry if try_reconnect and reconnect(options)
153
- raise ConnectionError.new(e.message)
154
- end
155
- end
156
-
157
- def ensure_method(method)
158
- Method.constants.each do |name|
159
- if method.to_s.downcase == name.downcase
160
- return Method.const_get(name).new
161
- end
162
- end
163
-
164
- available_methods = Method.constants.collect do |name|
165
- name.downcase.to_sym.inspect
166
- end.join(", ")
167
- raise ConfigurationError,
168
- "#{method.inspect} is not one of the available connect " +
169
- "methods #{available_methods}"
170
- end
171
-
172
- def ensure_scope(scope)
173
- scope_map = {
174
- :base => LDAP::LDAP_SCOPE_BASE,
175
- :sub => LDAP::LDAP_SCOPE_SUBTREE,
176
- :one => LDAP::LDAP_SCOPE_ONELEVEL,
177
- }
178
- value = scope_map[scope || :sub]
179
- if value.nil?
180
- available_scopes = scope_map.keys.inspect
181
- raise ArgumentError, "#{scope.inspect} is not one of the available " +
182
- "LDAP scope #{available_scopes}"
183
- end
184
- value
185
- end
186
-
187
- def sasl_bind(bind_dn, options={})
188
- super do |bind_dn, mechanism, quiet|
189
- begin
190
- sasl_quiet = @connection.sasl_quiet
191
- @connection.sasl_quiet = quiet unless quiet.nil?
192
- args = [bind_dn, mechanism]
193
- if need_credential_sasl_mechanism?(mechanism)
194
- args << password(bind_dn, options)
195
- end
196
- execute(:sasl_bind, *args)
197
- ensure
198
- @connection.sasl_quiet = sasl_quiet
199
- end
200
- end
201
- end
202
-
203
- def simple_bind(bind_dn, options={})
204
- super do |bind_dn, passwd|
205
- execute(:bind, bind_dn, passwd)
206
- end
207
- end
208
-
209
- def parse_entries(entries)
210
- result = []
211
- entries.each do |type, key, attributes|
212
- mod_type = ensure_mod_type(type)
213
- binary = schema.binary?(key)
214
- mod_type |= LDAP::LDAP_MOD_BVALUES if binary
215
- attributes.each do |name, values|
216
- result << LDAP.mod(mod_type, name, values)
217
- end
218
- end
219
- result
220
- end
221
-
222
- def ensure_mod_type(type)
223
- case type
224
- when :replace, :add
225
- LDAP.const_get("LDAP_MOD_#{type.to_s.upcase}")
226
- else
227
- raise ArgumentError, "unknown type: #{type}"
228
- end
229
- end
230
- end
231
- end
232
- end
@@ -1,69 +0,0 @@
1
- require_library_or_gem 'ldap'
2
- require 'ldap/ldif'
3
- require 'ldap/schema'
4
-
5
- module LDAP
6
- class Mod
7
- unless instance_method(:to_s).arity.zero?
8
- alias_method :original_to_s, :to_s
9
- def to_s
10
- inspect
11
- end
12
- end
13
-
14
- alias_method :_initialize, :initialize
15
- def initialize(op, type, vals)
16
- if (LDAP::VERSION.split(/\./).collect {|x| x.to_i} <=> [0, 9, 7]) <= 0
17
- @op, @type, @vals = op, type, vals # to protect from GC
18
- end
19
- _initialize(op, type, vals)
20
- end
21
- end
22
-
23
- IMPLEMENT_SPECIFIC_ERRORS = {}
24
- {
25
- 0x51 => "SERVER_DOWN",
26
- 0x52 => "LOCAL_ERROR",
27
- 0x53 => "ENCODING_ERROR",
28
- 0x54 => "DECODING_ERROR",
29
- 0x55 => "TIMEOUT",
30
- 0x56 => "AUTH_UNKNOWN",
31
- 0x57 => "FILTER_ERROR",
32
- 0x58 => "USER_CANCELLED",
33
- 0x59 => "PARAM_ERROR",
34
- 0x5a => "NO_MEMORY",
35
-
36
- 0x5b => "CONNECT_ERROR",
37
- 0x5c => "NOT_SUPPORTED",
38
- 0x5d => "CONTROL_NOT_FOUND",
39
- 0x5e => "NO_RESULTS_RETURNED",
40
- 0x5f => "MORE_RESULTS_TO_RETURN",
41
- 0x60 => "CLIENT_LOOP",
42
- 0x61 => "REFERRAL_LIMIT_EXCEEDED",
43
- }.each do |code, name|
44
- IMPLEMENT_SPECIFIC_ERRORS[code] =
45
- ActiveLdap::LdapError.define(code, name, self)
46
- end
47
-
48
- class Conn
49
- def failed?
50
- not err.zero?
51
- end
52
-
53
- def error_message
54
- if failed?
55
- LDAP.err2string(err)
56
- else
57
- nil
58
- end
59
- end
60
-
61
- def assert_error_code
62
- return unless failed?
63
- klass = ActiveLdap::LdapError::ERRORS[err]
64
- klass ||= IMPLEMENT_SPECIFIC_ERRORS[err]
65
- klass ||= ActiveLdap::LdapError
66
- raise klass, LDAP.err2string(err)
67
- end
68
- end
69
- end
@@ -1,288 +0,0 @@
1
- require 'digest/md5'
2
-
3
- require 'active_ldap/adapter/base'
4
-
5
- module ActiveLdap
6
- module Adapter
7
- class Base
8
- class << self
9
- def net_ldap_connection(options)
10
- unless defined?(::Net::LDAP)
11
- require 'active_ldap/adapter/net_ldap_ext'
12
- end
13
- NetLdap.new(options)
14
- end
15
- end
16
- end
17
-
18
- class NetLdap < Base
19
- METHOD = {
20
- :ssl => :simple_tls,
21
- :tls => :start_tls,
22
- :plain => nil,
23
- }
24
-
25
- def connect(options={})
26
- @bound = false
27
- super do |host, port, method|
28
- config = {
29
- :host => host,
30
- :port => port,
31
- }
32
- config[:encryption] = {:method => method} if method
33
- Net::LDAP::Connection.new(config)
34
- end
35
- end
36
-
37
- def unbind(options={})
38
- @bound = false
39
- end
40
-
41
- def bind(options={})
42
- @bound = false
43
- begin
44
- super
45
- rescue Net::LDAP::LdapError
46
- raise AuthenticationError, $!.message
47
- end
48
- end
49
-
50
- def bind_as_anonymous(options={})
51
- super do
52
- @bound = false
53
- execute(:bind, :method => :anonymous)
54
- @bound = true
55
- end
56
- end
57
-
58
- def bound?
59
- connecting? and @bound
60
- end
61
-
62
- def search(options={}, &block)
63
- super(options) do |base, scope, filter, attrs, limit, callback|
64
- args = {
65
- :base => base,
66
- :scope => scope,
67
- :filter => filter,
68
- :attributes => attrs,
69
- :size => limit,
70
- }
71
- execute(:search, args) do |entry|
72
- attributes = {}
73
- entry.original_attribute_names.each do |name|
74
- attributes[name] = entry[name]
75
- end
76
- callback.call([entry.dn, attributes], block)
77
- end
78
- end
79
- end
80
-
81
- def to_ldif(dn, attributes)
82
- entry = Net::LDAP::Entry.new(dn.dup)
83
- attributes.each do |key, values|
84
- entry[key] = values.flatten
85
- end
86
- entry.to_ldif
87
- end
88
-
89
- def load(ldifs, options={})
90
- super do |ldif|
91
- entry = Net::LDAP::Entry.from_single_ldif_string(ldif)
92
- attributes = {}
93
- entry.each do |name, values|
94
- attributes[name] = values
95
- end
96
- attributes.delete(:dn)
97
- execute(:add,
98
- :dn => entry.dn,
99
- :attributes => attributes)
100
- end
101
- end
102
-
103
- def delete(targets, options={})
104
- super do |target|
105
- execute(:delete, :dn => target)
106
- end
107
- end
108
-
109
- def add(dn, entries, options={})
110
- super do |dn, entries|
111
- attributes = {}
112
- entries.each do |type, key, attrs|
113
- attrs.each do |name, values|
114
- attributes[name] = values
115
- end
116
- end
117
- execute(:add, :dn => dn, :attributes => attributes)
118
- end
119
- end
120
-
121
- def modify(dn, entries, options={})
122
- super do |dn, entries|
123
- execute(:modify,
124
- :dn => dn,
125
- :operations => parse_entries(entries))
126
- end
127
- end
128
-
129
- private
130
- def execute(method, *args, &block)
131
- result = @connection.send(method, *args, &block)
132
- message = nil
133
- if result.is_a?(Hash)
134
- message = result[:errorMessage]
135
- result = result[:resultCode]
136
- end
137
- unless result.zero?
138
- klass = LdapError::ERRORS[result]
139
- klass ||= LdapError
140
- raise klass,
141
- [Net::LDAP.result2string(result), message].compact.join(": ")
142
- end
143
- end
144
-
145
- def root_dse(attrs, options={})
146
- search(:base => "",
147
- :scope => :base,
148
- :attributes => attrs).collect do |dn, attributes|
149
- attributes
150
- end
151
- end
152
-
153
- def ensure_method(method)
154
- method ||= "plain"
155
- normalized_method = method.to_s.downcase.to_sym
156
- return METHOD[normalized_method] if METHOD.has_key?(normalized_method)
157
-
158
- available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ")
159
- raise ConfigurationError,
160
- "#{method.inspect} is not one of the available connect " +
161
- "methods #{available_methods}"
162
- end
163
-
164
- def ensure_scope(scope)
165
- scope_map = {
166
- :base => Net::LDAP::SearchScope_BaseObject,
167
- :sub => Net::LDAP::SearchScope_WholeSubtree,
168
- :one => Net::LDAP::SearchScope_SingleLevel,
169
- }
170
- value = scope_map[scope || :sub]
171
- if value.nil?
172
- available_scopes = scope_map.keys.inspect
173
- raise ArgumentError, "#{scope.inspect} is not one of the available " +
174
- "LDAP scope #{available_scopes}"
175
- end
176
- value
177
- end
178
-
179
- def sasl_bind(bind_dn, options={})
180
- super do |bind_dn, mechanism, quiet|
181
- normalized_mechanism = mechanism.downcase.gsub(/-/, '_')
182
- sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}"
183
- next unless respond_to?(sasl_bind_setup, true)
184
- initial_credential, challenge_response =
185
- send(sasl_bind_setup, bind_dn, options)
186
- args = {
187
- :method => :sasl,
188
- :initial_credential => initial_credential,
189
- :mechanism => mechanism,
190
- :challenge_response => challenge_response,
191
- }
192
- @bound = false
193
- execute(:bind, args)
194
- @bound = true
195
- end
196
- end
197
-
198
- def sasl_bind_setup_digest_md5(bind_dn, options)
199
- initial_credential = ""
200
- nonce_count = 1
201
- challenge_response = Proc.new do |cred|
202
- params = parse_sasl_digest_md5_credential(cred)
203
- qops = params["qop"].split(/,/)
204
- return "unsupported qops: #{qops.inspect}" unless qops.include?("auth")
205
- qop = "auth"
206
- server = @connection.instance_variable_get("@conn").addr[2]
207
- realm = params['realm']
208
- uri = "ldap/#{server}"
209
- nc = "%08x" % nonce_count
210
- nonce = params["nonce"]
211
- cnonce = generate_client_nonce
212
- requests = {
213
- :username => bind_dn.inspect,
214
- :realm => realm.inspect,
215
- :nonce => nonce.inspect,
216
- :cnonce => cnonce.inspect,
217
- :nc => nc,
218
- :qop => qop,
219
- :maxbuf => "65536",
220
- "digest-uri" => uri.inspect,
221
- }
222
- a1 = "#{bind_dn}:#{realm}:#{password(cred, options)}"
223
- a1 = "#{Digest::MD5.digest(a1)}:#{nonce}:#{cnonce}"
224
- ha1 = Digest::MD5.hexdigest(a1)
225
- a2 = "AUTHENTICATE:#{uri}"
226
- ha2 = Digest::MD5.hexdigest(a2)
227
- response = "#{ha1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{ha2}"
228
- requests["response"] = Digest::MD5.hexdigest(response)
229
- nonce_count += 1
230
- requests.collect do |key, value|
231
- "#{key}=#{value}"
232
- end.join(",")
233
- end
234
- [initial_credential, challenge_response]
235
- end
236
-
237
- def parse_sasl_digest_md5_credential(cred)
238
- params = {}
239
- cred.scan(/(\w+)=(\"?)(.+?)\2(?:,|$)/) do |name, sep, value|
240
- params[name] = value
241
- end
242
- params
243
- end
244
-
245
- CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
246
- def generate_client_nonce(size=32)
247
- nonce = ""
248
- size.times do |i|
249
- nonce << CHARS[rand(CHARS.size)]
250
- end
251
- nonce
252
- end
253
-
254
- def simple_bind(bind_dn, options={})
255
- super do |bind_dn, passwd|
256
- args = {
257
- :method => :simple,
258
- :username => bind_dn,
259
- :password => passwd,
260
- }
261
- @bound = false
262
- execute(:bind, args)
263
- @bound = true
264
- end
265
- end
266
-
267
- def parse_entries(entries)
268
- result = []
269
- entries.each do |type, key, attributes|
270
- mod_type = ensure_mod_type(type)
271
- attributes.each do |name, values|
272
- result << [mod_type, name, values]
273
- end
274
- end
275
- result
276
- end
277
-
278
- def ensure_mod_type(type)
279
- case type
280
- when :replace, :add
281
- type
282
- else
283
- raise ArgumentError, "unknown type: #{type}"
284
- end
285
- end
286
- end
287
- end
288
- end