treequel 1.6.0 → 1.7.0
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/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']
|