treequel 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +163 -76
- data/History.rdoc +11 -0
- data/README.rdoc +14 -16
- data/Rakefile +6 -1
- data/bin/treequel +4 -10
- data/bin/treewhat +2 -4
- data/lib/treequel/branch.rb +49 -163
- data/lib/treequel/branchcollection.rb +11 -16
- data/lib/treequel/branchset.rb +24 -17
- data/lib/treequel/control.rb +8 -6
- data/lib/treequel/controls/contentsync.rb +2 -2
- data/lib/treequel/controls/pagedresults.rb +1 -10
- data/lib/treequel/directory.rb +36 -78
- data/lib/treequel/exceptions.rb +1 -2
- data/lib/treequel/filter.rb +3 -8
- data/lib/treequel/mixins.rb +2 -7
- data/lib/treequel/model/errors.rb +1 -4
- data/lib/treequel/model/objectclass.rb +14 -26
- data/lib/treequel/model.rb +18 -64
- data/lib/treequel/monkeypatches.rb +2 -3
- data/lib/treequel/schema/attributetype.rb +0 -5
- data/lib/treequel/schema/objectclass.rb +9 -27
- data/lib/treequel/schema.rb +1 -18
- data/lib/treequel/utils.rb +0 -3
- data/lib/treequel.rb +48 -75
- data/spec/treequel/branchset_spec.rb +24 -0
- data/spec/treequel/monkeypatches_spec.rb +9 -9
- data.tar.gz.sig +0 -0
- metadata +27 -27
- metadata.gz.sig +1 -3
data/lib/treequel/branchset.rb
CHANGED
@@ -185,10 +185,8 @@ class Treequel::Branchset
|
|
185
185
|
|
186
186
|
|
187
187
|
### If given another Branchset or a BranchCollection, return a BranchCollection that includes
|
188
|
-
### them both. If given anything else, execute the search and return
|
189
|
-
###
|
190
|
-
### with
|
191
|
-
### @return [Treequel::BranchCollection, Array<Treequel::Branch>]
|
188
|
+
### them both. If given anything else, execute the search and return the results plus
|
189
|
+
### +other+ in an Array.
|
192
190
|
def +( other )
|
193
191
|
if other.is_a?( Treequel::BranchCollection ) || other.is_a?( Treequel::Branchset )
|
194
192
|
return Treequel::BranchCollection.new( self, other )
|
@@ -199,8 +197,6 @@ class Treequel::Branchset
|
|
199
197
|
|
200
198
|
|
201
199
|
### Return the results of executing the search without the +other_object+.
|
202
|
-
### @param [#dn] other_object the object to omit from the results; must respond_to #dn.
|
203
|
-
### @return [Array<Treequel::Branch>]
|
204
200
|
def -( other_object )
|
205
201
|
other_dn = other_object.dn
|
206
202
|
return self.reject {|branch| branch.dn.downcase == other_dn.downcase }
|
@@ -224,17 +220,24 @@ class Treequel::Branchset
|
|
224
220
|
end
|
225
221
|
|
226
222
|
|
227
|
-
### Fetch the first
|
228
|
-
### the object that is set as the +branch+ (e.g., Treequel::Branch).
|
229
|
-
|
230
|
-
|
223
|
+
### Fetch the first +n+ entries which matches the current criteria and return them as
|
224
|
+
### instances of the object that is set as the +branch+ (e.g., Treequel::Branch). If +n+ is
|
225
|
+
### +nil+, returns just the first object in the Array.
|
226
|
+
def first( n=nil )
|
227
|
+
results = self.branch.search( self.scope, self.filter,
|
231
228
|
:selectattrs => self.select,
|
232
229
|
:timeout => self.timeout,
|
233
230
|
# :sortby => self.order,
|
234
231
|
:client_controls => self.get_client_controls,
|
235
232
|
:server_controls => self.get_server_controls,
|
236
|
-
:limit => 1
|
237
|
-
)
|
233
|
+
:limit => n || 1
|
234
|
+
)
|
235
|
+
|
236
|
+
if n
|
237
|
+
return results.first( n )
|
238
|
+
else
|
239
|
+
return results.first
|
240
|
+
end
|
238
241
|
end
|
239
242
|
|
240
243
|
|
@@ -307,10 +310,7 @@ class Treequel::Branchset
|
|
307
310
|
end
|
308
311
|
|
309
312
|
|
310
|
-
### Add an alternate filter to an existing filter by ORing
|
311
|
-
### @param filterspec the filter spec to OR with the existing filter
|
312
|
-
### @raises [Treequel::InvalidOperation] if there is no existing filter
|
313
|
-
### @see Treequel::Filter.new for specifics on what +filterspec+ can be
|
313
|
+
### Add an alternate filter to an existing filter by ORing it with +filterspec+.
|
314
314
|
def or( *filterspec )
|
315
315
|
opts = self.options
|
316
316
|
existing_filter = self.filter
|
@@ -324,6 +324,14 @@ class Treequel::Branchset
|
|
324
324
|
end
|
325
325
|
|
326
326
|
|
327
|
+
### Add a clause made from a negated +filterspec+ to an existing filter.
|
328
|
+
def not( *filterspec )
|
329
|
+
self.log.debug "cloning %p with negated filterspec: %p" % [ self, filterspec ]
|
330
|
+
notfilter = Treequel::Filter.new( :not, *filterspec )
|
331
|
+
return self.clone( :filter => self.filter + notfilter )
|
332
|
+
end
|
333
|
+
|
334
|
+
|
327
335
|
### If called with no argument, returns the current scope of the Branchset. If
|
328
336
|
### called with an argument (which should be one of the keys of
|
329
337
|
### Treequel::Constants::SCOPE), returns a clone of the receiving Branchset
|
@@ -427,7 +435,6 @@ class Treequel::Branchset
|
|
427
435
|
|
428
436
|
### Return a clone of the receiving Branchset that will perform its search from
|
429
437
|
### +other_dn+ instead of its own.
|
430
|
-
### @param [String, #dn] other_dn the new base DN of the search
|
431
438
|
def from( other_dn )
|
432
439
|
newset = self.clone
|
433
440
|
other_dn = other_dn.dn if other_dn.respond_to?( :dn )
|
data/lib/treequel/control.rb
CHANGED
@@ -8,13 +8,15 @@ require 'treequel'
|
|
8
8
|
|
9
9
|
# Virtual interface methods for Control modules.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
11
|
+
# == Subclassing
|
12
|
+
# To make a concrete derivative, include this module in a module that
|
13
|
+
# implements either #get_client_controls or #get_server_controls and #each.
|
14
|
+
# Your implementation of #each should +super+ with a block that does the
|
15
|
+
# necessary extraction of the result controls and yields back to the original
|
16
|
+
# block.
|
16
17
|
#
|
17
|
-
#
|
18
|
+
# == Examples
|
19
|
+
#
|
18
20
|
# module Treequel::MyControl
|
19
21
|
# include Treequel::Control
|
20
22
|
#
|
@@ -34,8 +34,8 @@ require 'treequel/constants'
|
|
34
34
|
# #
|
35
35
|
# end
|
36
36
|
#
|
37
|
-
#
|
38
|
-
#
|
37
|
+
# See http://deveiate.org/projects/Treequel/ticket/6 Ticket: Add support for
|
38
|
+
# the RFC4533 Content Sync operation.
|
39
39
|
#
|
40
40
|
module Treequel::ContentSyncControl
|
41
41
|
include Treequel::Control,
|
@@ -63,10 +63,7 @@ module Treequel::PagedResultsControl
|
|
63
63
|
attr_accessor :paged_results_cookie
|
64
64
|
|
65
65
|
|
66
|
-
### Clone the Branchset with a paged results control
|
67
|
-
### @param [Fixnum] setsize The size of each result set. If this is nil or 0, removes
|
68
|
-
### paging from the Branchset.
|
69
|
-
### @return [Treequel::Branchset] a clone of the receiver with paging set to +setsize+
|
66
|
+
### Clone the Branchset with a paged results control with paging set to +setsize+.
|
70
67
|
def with_paged_results( setsize=DEFAULT_PAGE_SIZE )
|
71
68
|
self.log.warn "This control will likely not work in ruby-ldap versions " +
|
72
69
|
" <= 0.9.9. See http://code.google.com/p/ruby-activeldap/issues/" +
|
@@ -87,7 +84,6 @@ module Treequel::PagedResultsControl
|
|
87
84
|
|
88
85
|
|
89
86
|
### Clone the Branchset without paging and return it.
|
90
|
-
### @return [Treequel::Branchset] a clone of the receiver, stripped of its paging
|
91
87
|
def without_paging
|
92
88
|
copy = self.clone
|
93
89
|
copy.without_paging!
|
@@ -96,7 +92,6 @@ module Treequel::PagedResultsControl
|
|
96
92
|
|
97
93
|
|
98
94
|
### Remove any paging control associated with the receiving Branchset.
|
99
|
-
### @return [void]
|
100
95
|
def without_paging!
|
101
96
|
self.paged_results_cookie = nil
|
102
97
|
self.paged_results_setsize = nil
|
@@ -105,7 +100,6 @@ module Treequel::PagedResultsControl
|
|
105
100
|
|
106
101
|
### Returns +true+ if the first page of results has been fetched and there are
|
107
102
|
### more pages remaining.
|
108
|
-
### @return [Boolean]
|
109
103
|
def has_more_results?
|
110
104
|
return true unless self.done_paging?
|
111
105
|
end
|
@@ -113,7 +107,6 @@ module Treequel::PagedResultsControl
|
|
113
107
|
|
114
108
|
### Returns +true+ if results have yet to be fetched, or if they have all been
|
115
109
|
### fetched.
|
116
|
-
### @return [Boolean]
|
117
110
|
def done_paging?
|
118
111
|
return self.paged_results_cookie == ''
|
119
112
|
end
|
@@ -121,7 +114,6 @@ module Treequel::PagedResultsControl
|
|
121
114
|
|
122
115
|
### Override the Enumerable method to update the cookie value each time a page
|
123
116
|
### is fetched.
|
124
|
-
### @yieldparam [Treequel::Branch] branch the branch that's a result of the search.
|
125
117
|
def each( &block )
|
126
118
|
super do |branch|
|
127
119
|
if paged_control = branch.controls.find {|control| control.oid == OID }
|
@@ -145,7 +137,6 @@ module Treequel::PagedResultsControl
|
|
145
137
|
|
146
138
|
### Treequel::Control API -- Get the set of server controls currently configured for
|
147
139
|
### the receiver.
|
148
|
-
### @return [Array<LDAP::Control>] the configured controls
|
149
140
|
def get_server_controls
|
150
141
|
controls = super
|
151
142
|
if pagesize = self.paged_results_setsize && self.paged_results_setsize.nonzero?
|
data/lib/treequel/directory.rb
CHANGED
@@ -105,21 +105,20 @@ class Treequel::Directory
|
|
105
105
|
### Create a new Treequel::Directory with the given +options+. Options is a hash with one
|
106
106
|
### or more of the following key-value pairs:
|
107
107
|
###
|
108
|
-
###
|
109
|
-
###
|
110
|
-
###
|
111
|
-
###
|
112
|
-
###
|
113
|
-
###
|
114
|
-
###
|
115
|
-
### @option options [String] :base_dn (nil)
|
108
|
+
### [+:host+]
|
109
|
+
### The LDAP host to connect to (default: 'localhost').
|
110
|
+
### [+:port+]
|
111
|
+
### The port number to connect to (default: LDAP::LDAP_PORT).
|
112
|
+
### [+:connect_type+]
|
113
|
+
### The type of connection to establish; :tls, :ssl, or :plain. Defaults to +:tls+.
|
114
|
+
### [+:base_dn+]
|
116
115
|
### The base DN of the directory; defaults to the first naming context of
|
117
116
|
### the directory's root DSE.
|
118
|
-
###
|
117
|
+
### [+:bind_dn+]
|
119
118
|
### The DN of the user to bind as; if unset, binds anonymously.
|
120
|
-
###
|
119
|
+
### [+:pass+]
|
121
120
|
### The password to use when binding.
|
122
|
-
###
|
121
|
+
### [+:results_class+]
|
123
122
|
### The class to instantiate by default for entries fetched from the Directory.
|
124
123
|
def initialize( options={} )
|
125
124
|
options = DEFAULT_OPTIONS.merge( options )
|
@@ -171,31 +170,24 @@ class Treequel::Directory
|
|
171
170
|
|
172
171
|
|
173
172
|
# The host to connect to.
|
174
|
-
# @return [String]
|
175
173
|
attr_accessor :host
|
176
174
|
|
177
175
|
# The port to connect to.
|
178
|
-
# @return [Fixnum]
|
179
176
|
attr_accessor :port
|
180
177
|
|
181
178
|
# The type of connection to establish
|
182
|
-
# @return [Symbol]
|
183
179
|
attr_accessor :connect_type
|
184
180
|
|
185
181
|
# The Class to instantiate when wrapping results fetched from the Directory.
|
186
|
-
# @return [Class]
|
187
182
|
attr_accessor :results_class
|
188
183
|
|
189
184
|
# The base DN of the directory
|
190
|
-
# @return [String]
|
191
185
|
attr_accessor :base_dn
|
192
186
|
|
193
187
|
# The control modules that are registered with the directory
|
194
|
-
# @return [Array<Module>]
|
195
188
|
attr_reader :registered_controls
|
196
189
|
|
197
190
|
# The DN of the user the directory is bound as
|
198
|
-
# @return [String]
|
199
191
|
attr_reader :bound_user
|
200
192
|
|
201
193
|
|
@@ -206,14 +198,12 @@ class Treequel::Directory
|
|
206
198
|
|
207
199
|
|
208
200
|
### Fetch the Branch for the base node of the directory.
|
209
|
-
### @return [Treequel::Branch]
|
210
201
|
def base
|
211
202
|
return @base ||= self.results_class.new( self, self.base_dn )
|
212
203
|
end
|
213
204
|
|
214
205
|
|
215
206
|
### Returns a string that describes the directory
|
216
|
-
### @return [String]
|
217
207
|
def to_s
|
218
208
|
return "%s:%d (%s, %s, %s)" % [
|
219
209
|
self.host,
|
@@ -226,7 +216,6 @@ class Treequel::Directory
|
|
226
216
|
|
227
217
|
|
228
218
|
### Return a human-readable representation of the object suitable for debugging
|
229
|
-
### @return [String]
|
230
219
|
def inspect
|
231
220
|
return %{#<%s:0x%0x %s:%d (%s) base_dn=%p, bound as=%s, schema=%s>} % [
|
232
221
|
self.class.name,
|
@@ -243,7 +232,6 @@ class Treequel::Directory
|
|
243
232
|
|
244
233
|
### Return the LDAP::Conn object associated with this directory, creating it with the
|
245
234
|
### current options if necessary.
|
246
|
-
### @return [LDAP::Conn, LDAP::SSLConn]
|
247
235
|
def conn
|
248
236
|
return @conn ||= self.connect
|
249
237
|
end
|
@@ -252,15 +240,12 @@ class Treequel::Directory
|
|
252
240
|
### Returns +true+ if a connection has been established. This does not necessarily mean
|
253
241
|
### that the connection is still valid, it just means it successfully established one
|
254
242
|
### at some point.
|
255
|
-
### @return [Boolean]
|
256
243
|
def connected?
|
257
244
|
return @conn ? true : false
|
258
245
|
end
|
259
246
|
|
260
247
|
|
261
248
|
### Drop the existing connection and establish a new one.
|
262
|
-
### @return [Boolean] +true+ if the connection was re-established
|
263
|
-
### @raise [RuntimeError] if the re-connection failed
|
264
249
|
def reconnect
|
265
250
|
self.log.info "Reconnecting to %s..." % [ self.uri ]
|
266
251
|
@conn = self.connect
|
@@ -276,7 +261,6 @@ class Treequel::Directory
|
|
276
261
|
|
277
262
|
|
278
263
|
### Return the URI object that corresponds to the directory.
|
279
|
-
### @return [URI::LDAP]
|
280
264
|
def uri
|
281
265
|
uri_parts = {
|
282
266
|
:scheme => self.connect_type == :ssl ? 'ldaps' : 'ldap',
|
@@ -290,11 +274,6 @@ class Treequel::Directory
|
|
290
274
|
|
291
275
|
|
292
276
|
### Bind as the specified +user_dn+ and +password+.
|
293
|
-
###
|
294
|
-
### @param [String, #dn] user_dn the DN of the user to bind as
|
295
|
-
### @param [String] password the password to bind with
|
296
|
-
###
|
297
|
-
### @return [void]
|
298
277
|
def bind( user_dn, password )
|
299
278
|
user_dn = user_dn.dn if user_dn.respond_to?( :dn )
|
300
279
|
|
@@ -307,10 +286,6 @@ class Treequel::Directory
|
|
307
286
|
|
308
287
|
### Execute the provided +block+ after binding as +user_dn+ with the given +password+. After
|
309
288
|
### the block returns, the original binding (if any) will be restored.
|
310
|
-
###
|
311
|
-
### @param (see #bind)
|
312
|
-
###
|
313
|
-
### @return [void]
|
314
289
|
def bound_as( user_dn, password )
|
315
290
|
raise LocalJumpError, "no block given" unless block_given?
|
316
291
|
previous_bind_dn = @bound_user
|
@@ -324,7 +299,6 @@ class Treequel::Directory
|
|
324
299
|
|
325
300
|
|
326
301
|
### Returns +true+ if the directory's connection is already bound to the directory.
|
327
|
-
### @return [Boolean]
|
328
302
|
def bound?
|
329
303
|
return self.conn.bound?
|
330
304
|
end
|
@@ -332,7 +306,6 @@ class Treequel::Directory
|
|
332
306
|
|
333
307
|
|
334
308
|
### Ensure that the the receiver's connection is unbound.
|
335
|
-
### @return [void]
|
336
309
|
def unbind
|
337
310
|
if @conn.bound?
|
338
311
|
old_conn = @conn
|
@@ -343,7 +316,6 @@ class Treequel::Directory
|
|
343
316
|
|
344
317
|
|
345
318
|
### Return the RDN string to the given +dn+ from the base of the directory.
|
346
|
-
### @param [#to_s] dn the DN of the entry
|
347
319
|
def rdn_to( dn )
|
348
320
|
base_re = Regexp.new( ',' + Regexp.quote(self.base_dn) + '$' )
|
349
321
|
return dn.to_s.sub( base_re, '' )
|
@@ -352,8 +324,6 @@ class Treequel::Directory
|
|
352
324
|
|
353
325
|
### Given a Treequel::Branch object, find its corresponding LDAP::Entry and return
|
354
326
|
### it.
|
355
|
-
###
|
356
|
-
### @param [Treequel::Branch] branch the branch to look up
|
357
327
|
def get_entry( branch )
|
358
328
|
self.log.debug "Looking up entry for %p" % [ branch.dn ]
|
359
329
|
return self.conn.search_ext2( branch.dn, SCOPE[:base], '(objectClass=*)' ).first
|
@@ -366,8 +336,6 @@ class Treequel::Directory
|
|
366
336
|
### Given a Treequel::Branch object, find its corresponding LDAP::Entry and return
|
367
337
|
### it with its operational attributes (http://tools.ietf.org/html/rfc4512#section-3.4)
|
368
338
|
### included.
|
369
|
-
###
|
370
|
-
### @param [Treequel::Branch] branch the branch to look up
|
371
339
|
def get_extended_entry( branch )
|
372
340
|
self.log.debug "Looking up entry (with operational attributes) for %p" % [ branch.dn ]
|
373
341
|
return self.conn.search_ext2( branch.dn, SCOPE[:base], '(objectClass=*)', %w[* +] ).first
|
@@ -388,51 +356,46 @@ class Treequel::Directory
|
|
388
356
|
end
|
389
357
|
|
390
358
|
|
391
|
-
### Perform a +scope+ search at +base+ using the specified +filter+.
|
392
|
-
###
|
393
|
-
###
|
394
|
-
###
|
395
|
-
### +:onelevel+, +:base+, or +:subtree+.
|
396
|
-
### @param [#to_s] filter The search filter (RFC4515), either as a String
|
397
|
-
### or something that stringifies to an filter string.
|
398
|
-
### @param [Hash] options Search options.
|
359
|
+
### Perform a +scope+ search at +base+ using the specified +filter+. The scope can be one of
|
360
|
+
### +:onelevel+, +:base+, or +:subtree+. The search filter should be a RFC4515-style filter
|
361
|
+
### either as a String or something that stringifies to one (e.g., a Treequel::Filter). The
|
362
|
+
### available search options are:
|
399
363
|
###
|
400
|
-
###
|
364
|
+
### [+:results_class+]
|
401
365
|
### The Class to use when wrapping results; if not specified, defaults to the class
|
402
366
|
### of +base+ if it responds to #new_from_entry, or the directory object's
|
403
367
|
### #results_class if it does not.
|
404
|
-
###
|
368
|
+
### [+:selectattrs+]
|
405
369
|
### The attributes to return from the search; defaults to '*', which means to
|
406
370
|
### return all non-operational attributes. Specifying '+' will cause the search
|
407
371
|
### to include operational parameters as well.
|
408
|
-
###
|
372
|
+
### [+:attrsonly+]
|
409
373
|
### If +true, the LDAP::Entry objects returned from the search won't have attribute values.
|
410
374
|
### This has no real effect on Treequel::Branches, but is provided in case other
|
411
|
-
### +results_class+ classes need it.
|
412
|
-
###
|
413
|
-
### Any server controls that should be sent with the search
|
414
|
-
###
|
415
|
-
###
|
416
|
-
###
|
375
|
+
### +results_class+ classes need it. Defaults to +false+.
|
376
|
+
### [+:server_controls+]
|
377
|
+
### Any server controls that should be sent with the search as an Array of LDAP::Control
|
378
|
+
### objects.
|
379
|
+
### [+:client_controls+]
|
380
|
+
### Any client controls that should be applied to the search as an Array of LDAP::Control
|
381
|
+
### objects.
|
382
|
+
### [+:timeout_s+]
|
417
383
|
### The number of seconds (in addition to :timeout_us) after which the search request should
|
418
384
|
### be aborted.
|
419
|
-
###
|
385
|
+
### [+:timeout_us+]
|
420
386
|
### The number of microseconds (in addition to :timeout_s) after which the search request
|
421
387
|
### should be aborted.
|
422
|
-
###
|
388
|
+
### [+:limit+]
|
423
389
|
### The maximum number of results to return from the server.
|
424
|
-
###
|
390
|
+
### [+:sort_attribute+]
|
425
391
|
### An Array of String attribute names to sort by.
|
426
|
-
###
|
392
|
+
### [+:sort_func+]
|
427
393
|
### A function that will provide sorting.
|
428
394
|
###
|
429
|
-
###
|
430
|
-
###
|
431
|
-
###
|
395
|
+
### Returns the array of results, each of which is wrapped in the options[:results_class].
|
396
|
+
### If a block is given, it acts like a filter: it's called once for each result, and the
|
397
|
+
### array of return values from the block is returned instead.
|
432
398
|
###
|
433
|
-
### @yield [branch] an optional block, which will receive the results one at a time
|
434
|
-
### @yieldparam [Treequel::Branch] branch the resulting entry, wrapped in
|
435
|
-
### the options[:results_class].
|
436
399
|
def search( base, scope=:subtree, filter='(objectClass=*)', options={} )
|
437
400
|
collectclass = nil
|
438
401
|
|
@@ -451,13 +414,13 @@ class Treequel::Directory
|
|
451
414
|
self.normalize_search_parameters( base, scope, filter, options )
|
452
415
|
|
453
416
|
# Unwrap the search options from the hash in the correct order
|
454
|
-
self.log.debug
|
417
|
+
self.log.debug do
|
455
418
|
attrlist = SEARCH_PARAMETER_ORDER.inject([]) do |list, param|
|
456
419
|
list << "%s: %p" % [ param, searchopts[param] ]
|
457
420
|
end
|
458
421
|
"searching with base: %p, scope: %p, filter: %p, %s" %
|
459
422
|
[ base_dn, scope, filter, attrlist.join(', ') ]
|
460
|
-
|
423
|
+
end
|
461
424
|
parameters = searchopts.values_at( *SEARCH_PARAMETER_ORDER )
|
462
425
|
|
463
426
|
# Wrap each result in the class derived from the 'base' argument
|
@@ -515,11 +478,8 @@ class Treequel::Directory
|
|
515
478
|
end
|
516
479
|
|
517
480
|
|
518
|
-
### Create the entry for the given +branch+, setting its attributes to +newattrs
|
519
|
-
###
|
520
|
-
### @param [Hash, Array<LDAP::Mod>] newattrs the attributes to create the entry with. This
|
521
|
-
### can be either a Hash of attributes, or an Array of
|
522
|
-
### LDAP::Mod objects.
|
481
|
+
### Create the entry for the given +branch+, setting its attributes to +newattrs+, which
|
482
|
+
### can be either a Hash of attributes, or an Array of LDAP::Mod objects.
|
523
483
|
def create( branch, newattrs={} )
|
524
484
|
newattrs = normalize_attributes( newattrs ) if newattrs.is_a?( Hash )
|
525
485
|
self.conn.add( branch.to_s, newattrs )
|
@@ -556,7 +516,6 @@ class Treequel::Directory
|
|
556
516
|
### argument(e.g., Proc, Method, Hash); the argument is the raw value String returned
|
557
517
|
### from the LDAP entry, and it should return the converted value. Adding a mapping
|
558
518
|
### with a nil +conversion+ effectively clears it.
|
559
|
-
### @see #convert_to_object
|
560
519
|
def add_attribute_conversion( oid, conversion=nil )
|
561
520
|
conversion = Proc.new if block_given?
|
562
521
|
@attribute_conversions[ oid ] = conversion
|
@@ -567,7 +526,6 @@ class Treequel::Directory
|
|
567
526
|
### responds to #[] with an object argument(e.g., Proc, Method, Hash); the argument is
|
568
527
|
### the Ruby object that's being set as a value in an LDAP entry, and it should return the
|
569
528
|
### raw LDAP string. Adding a mapping with a nil +conversion+ effectively clears it.
|
570
|
-
### @see #convert_to_attribute
|
571
529
|
def add_object_conversion( oid, conversion=nil )
|
572
530
|
conversion = Proc.new if block_given?
|
573
531
|
@object_conversions[ oid ] = conversion
|
data/lib/treequel/exceptions.rb
CHANGED
@@ -30,7 +30,6 @@ module Treequel
|
|
30
30
|
class ValidationFailed < Treequel::ModelError
|
31
31
|
|
32
32
|
### Create a new Treequel::ValidationFailed exception with the given +errors+.
|
33
|
-
### @param [Treequel::Model::Errors, String] errors the validaton errors
|
34
33
|
def initialize( errors )
|
35
34
|
if errors.respond_to?( :full_messages )
|
36
35
|
@errors = errors
|
@@ -44,7 +43,7 @@ module Treequel
|
|
44
43
|
public
|
45
44
|
######
|
46
45
|
|
47
|
-
#
|
46
|
+
# the validation errors
|
48
47
|
attr_reader :errors
|
49
48
|
|
50
49
|
end # class ValidationFailed
|
data/lib/treequel/filter.rb
CHANGED
@@ -64,8 +64,6 @@ class Treequel::Filter
|
|
64
64
|
|
65
65
|
|
66
66
|
### Append operator: add the +other+ filter to the list.
|
67
|
-
### @param [Treequel::Filter] other the new filter to add
|
68
|
-
### @return [Treequel::Filter::FilterList] self (for chaining)
|
69
67
|
def <<( other )
|
70
68
|
@filters << other
|
71
69
|
return self
|
@@ -75,7 +73,7 @@ class Treequel::Filter
|
|
75
73
|
|
76
74
|
|
77
75
|
### An abstract class for filter components.
|
78
|
-
###
|
76
|
+
### Subclass and override #to_s to implement a custom Component class.
|
79
77
|
class Component
|
80
78
|
include Treequel::Loggable
|
81
79
|
|
@@ -150,7 +148,6 @@ class Treequel::Filter
|
|
150
148
|
end
|
151
149
|
|
152
150
|
### Add an additional filter to the list of requirements
|
153
|
-
### @param [Treequel::Filter] filter the new requirement
|
154
151
|
def add_requirement( filter )
|
155
152
|
@filterlist << filter
|
156
153
|
end
|
@@ -176,7 +173,6 @@ class Treequel::Filter
|
|
176
173
|
end
|
177
174
|
|
178
175
|
### Add an additional filter to the list of alternatives
|
179
|
-
### @param [Treequel::Filter] filter the new alternative
|
180
176
|
def add_alternation( filter )
|
181
177
|
@filterlist << filter
|
182
178
|
end
|
@@ -712,7 +708,7 @@ class Treequel::Filter
|
|
712
708
|
end
|
713
709
|
|
714
710
|
|
715
|
-
### AND
|
711
|
+
### Return a new Filter that is the AND filter of the receiver with +other_filter+.
|
716
712
|
def &( other_filter )
|
717
713
|
return other_filter if self.promiscuous?
|
718
714
|
return self.dup if other_filter.promiscuous?
|
@@ -721,8 +717,7 @@ class Treequel::Filter
|
|
721
717
|
alias_method :+, :&
|
722
718
|
|
723
719
|
|
724
|
-
### OR
|
725
|
-
### @param [Treequel::Filter] other_filter
|
720
|
+
### Return a new Filter that is the OR filter of the receiver with +other_filter+.
|
726
721
|
def |( other_filter )
|
727
722
|
return other_filter if self.promiscuous?
|
728
723
|
return self.dup if other_filter.promiscuous?
|
data/lib/treequel/mixins.rb
CHANGED
@@ -22,7 +22,6 @@ module Treequel
|
|
22
22
|
### Define the given +delegated_methods+ as delegators to the like-named method
|
23
23
|
### of the return value of the +delegate_method+.
|
24
24
|
###
|
25
|
-
### @example
|
26
25
|
### class MyClass
|
27
26
|
### extend Treequel::Delegation
|
28
27
|
###
|
@@ -122,10 +121,8 @@ module Treequel
|
|
122
121
|
module_function
|
123
122
|
###############
|
124
123
|
|
125
|
-
### Normalize the given key
|
126
|
-
###
|
127
|
-
### @return a downcased Symbol stripped of any invalid characters, and
|
128
|
-
### with '-' characters converted to '_'.
|
124
|
+
### Normalize the given key, returning a downcased Symbol stripped of any invalid
|
125
|
+
### characters, and with '-' characters converted to '_'.
|
129
126
|
def normalize_key( key )
|
130
127
|
return key if key.to_s =~ Treequel::Constants::Patterns::NUMERICOID
|
131
128
|
return key.to_s.downcase.
|
@@ -135,7 +132,6 @@ module Treequel
|
|
135
132
|
end
|
136
133
|
|
137
134
|
### Return a copy of +hash+ with all of its keys normalized by #normalize_key.
|
138
|
-
### @param [Hash] hash the Hash to normalize
|
139
135
|
def normalize_hash( hash )
|
140
136
|
hash = hash.dup
|
141
137
|
hash.keys.each do |key|
|
@@ -155,7 +151,6 @@ module Treequel
|
|
155
151
|
|
156
152
|
### A logging proxy class that wraps calls to the logger into calls that include
|
157
153
|
### the name of the calling class.
|
158
|
-
### @private
|
159
154
|
class ClassNameProxy
|
160
155
|
|
161
156
|
### Create a new proxy for the given +klass+.
|
@@ -48,22 +48,19 @@ class Treequel::Model::Errors < ::Hash
|
|
48
48
|
|
49
49
|
|
50
50
|
### Adds an error for the given +subject+.
|
51
|
-
### @param [Symbol, #to_sym] subject the subject of the error
|
52
|
-
### @param [String] message the description of the error condition
|
53
51
|
def add( subject, message )
|
54
52
|
self[ subject ] << message
|
55
53
|
end
|
56
54
|
|
57
55
|
|
58
56
|
### Get the number of errors that have been registered.
|
59
|
-
### @Return [Fixnum] the number of errors
|
60
57
|
def count
|
61
58
|
return self.values.inject( 0 ) {|num, val| num + val.length }
|
62
59
|
end
|
63
60
|
|
64
61
|
|
65
62
|
### Get an Array of messages describing errors which have occurred.
|
66
|
-
###
|
63
|
+
###
|
67
64
|
### errors.full_messages
|
68
65
|
### # => ['cn is not valid',
|
69
66
|
### # 'uid is not at least 2 letters']
|