treequel 1.5.3 → 1.6.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 +181 -3
- data/{History.md → History.rdoc} +53 -19
- data/Manifest.txt +5 -2
- data/{README.md → README.rdoc} +0 -0
- data/Rakefile +55 -21
- data/bin/treewhat +4 -0
- data/lib/treequel/branch.rb +28 -1
- data/lib/treequel/branchset.rb +9 -0
- data/lib/treequel/constants.rb +145 -22
- data/lib/treequel/directory.rb +12 -0
- data/lib/treequel/model.rb +5 -0
- data/lib/treequel/schema/attributetype.rb +28 -4
- data/lib/treequel/schema/objectclass.rb +40 -8
- data/lib/treequel/schema.rb +77 -28
- data/lib/treequel.rb +2 -2
- data/spec/data/ad_schema.yml +1752 -0
- data/spec/data/opends.yml +1986 -0
- data/spec/data/ticket11.yml +17 -0
- data/spec/lib/helpers.rb +17 -2
- data/spec/treequel/branch_spec.rb +8 -1
- data/spec/treequel/branchset_spec.rb +9 -0
- data/spec/treequel/directory_spec.rb +4 -2
- data/spec/treequel/monkeypatches_spec.rb +1 -1
- data/spec/treequel/schema/attributetype_spec.rb +88 -11
- data/spec/treequel/schema/matchingrule_spec.rb +37 -0
- data/spec/treequel/schema/objectclass_spec.rb +85 -1
- data/spec/treequel/schema_spec.rb +145 -30
- data.tar.gz.sig +0 -0
- metadata +147 -222
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
attributeTypes:
|
|
3
|
+
- ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
4
|
+
- ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
5
|
+
- ( 1.3.6.1.1.4 NAME 'vendorName' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dsaOperation X-ORIGIN 'RFC 3045' )
|
|
6
|
+
- ( 1.3.6.1.4.1.42.2.27.9.1.800 NAME 'supportedSSLCiphers' DESC 'List of ciphers supported by SSL lib' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'Sun Directory Server' )
|
|
7
|
+
- ( 1.3.6.1.1.5 NAME 'vendorVersion' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dsaOperation X-ORIGIN 'RFC 3045' )
|
|
8
|
+
- ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
9
|
+
- ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
10
|
+
- ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
11
|
+
- ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
|
|
12
|
+
|
|
13
|
+
matchingRules:
|
|
14
|
+
- ( 1.3.6.1.4.1.42.2.27.9.4.0.3 NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
|
15
|
+
- ( 1.3.6.1.4.1.42.2.27.9.4.0.3.6 NAME 'caseExactSubstringMatch-2.16.840.1.113730.3.3.2.0.3' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
|
16
|
+
- ( 1.3.6.1.4.1.42.2.27.9.4.34.3 NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.11.3' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
|
17
|
+
- ( 1.3.6.1.4.1.42.2.27.9.4.34.3.6 NAME 'caseExactSubstringMatch-2.16.840.1.113730.3.3.2.11.3' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
data/spec/lib/helpers.rb
CHANGED
|
@@ -10,6 +10,17 @@ BEGIN {
|
|
|
10
10
|
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
# SimpleCov test coverage reporting; enable this using the :coverage rake task
|
|
14
|
+
if ENV['COVERAGE']
|
|
15
|
+
require 'simplecov'
|
|
16
|
+
SimpleCov.start do
|
|
17
|
+
add_filter 'spec'
|
|
18
|
+
add_group "Needing tests" do |file|
|
|
19
|
+
file.covered_percent < 90
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
13
24
|
require 'rspec'
|
|
14
25
|
|
|
15
26
|
require 'treequel'
|
|
@@ -161,8 +172,10 @@ module Treequel::SpecHelpers
|
|
|
161
172
|
end
|
|
162
173
|
|
|
163
174
|
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec )
|
|
176
|
+
|
|
177
|
+
### Mock with RSpec
|
|
178
|
+
RSpec.configure do |c|
|
|
166
179
|
include Treequel::TestConstants
|
|
167
180
|
|
|
168
181
|
c.mock_with :rspec
|
|
@@ -175,6 +188,8 @@ Rspec.configure do |c|
|
|
|
175
188
|
|
|
176
189
|
c.filter_run_excluding( :ruby_1_8_only => true ) if
|
|
177
190
|
Treequel::SpecHelpers.vvec( RUBY_VERSION ) >= Treequel::SpecHelpers.vvec('1.9.1')
|
|
191
|
+
c.filter_run_excluding( :mri_only => true ) if
|
|
192
|
+
defined?( RUBY_ENGINE ) && RUBY_ENGINE != 'ruby'
|
|
178
193
|
end
|
|
179
194
|
|
|
180
195
|
# vim: set nosta noet ts=4 sw=4:
|
|
@@ -636,7 +636,14 @@ describe Treequel::Branch do
|
|
|
636
636
|
end
|
|
637
637
|
|
|
638
638
|
|
|
639
|
-
it "knows how to represent its DN as an RFC1781-style UFN" do
|
|
639
|
+
it "knows how to represent its DN as an RFC1781-style UFN", :if => LDAP.respond_to?(:dn2ufn) do
|
|
640
|
+
@branch.to_ufn.should =~ /Hosts, acme\.com/i
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
it "knows how to represent its DN as a UFN even if the LDAP library doesn't " +
|
|
645
|
+
"define #dn2ufn" do
|
|
646
|
+
LDAP.stub( :respond_to? ).with( :dn2ufn ).and_return( false )
|
|
640
647
|
@branch.to_ufn.should =~ /Hosts, acme\.com/i
|
|
641
648
|
end
|
|
642
649
|
|
|
@@ -418,6 +418,15 @@ describe Treequel::Branchset do
|
|
|
418
418
|
newset.base_dn.should == TEST_SUBHOSTS_DN
|
|
419
419
|
end
|
|
420
420
|
|
|
421
|
+
|
|
422
|
+
#
|
|
423
|
+
# with_operational_attributes
|
|
424
|
+
#
|
|
425
|
+
it "can create a new branchset cloned from itself with operational attributes selected" do
|
|
426
|
+
newset = @branchset.with_operational_attributes
|
|
427
|
+
newset.options[:select].should include( :+ )
|
|
428
|
+
end
|
|
429
|
+
|
|
421
430
|
end
|
|
422
431
|
|
|
423
432
|
|
|
@@ -191,7 +191,6 @@ describe Treequel::Directory do
|
|
|
191
191
|
@dir.should be_bound()
|
|
192
192
|
end
|
|
193
193
|
|
|
194
|
-
|
|
195
194
|
it "can be unbound, which replaces the bound connection with a duplicate that is unbound" do
|
|
196
195
|
dupconn = mock( "duplicate connection" )
|
|
197
196
|
@conn.should_receive( :bound? ).and_return( true )
|
|
@@ -203,7 +202,6 @@ describe Treequel::Directory do
|
|
|
203
202
|
@dir.conn.should == dupconn
|
|
204
203
|
end
|
|
205
204
|
|
|
206
|
-
|
|
207
205
|
it "doesn't do anything if told to unbind but the current connection is not bound" do
|
|
208
206
|
@conn.should_receive( :bound? ).and_return( false )
|
|
209
207
|
@conn.should_not_receive( :dup )
|
|
@@ -385,6 +383,10 @@ describe Treequel::Directory do
|
|
|
385
383
|
end
|
|
386
384
|
|
|
387
385
|
|
|
386
|
+
it "doesn't retain its connection when duplicated" do
|
|
387
|
+
@dir.dup.conn.should_not equal( @dir.conn )
|
|
388
|
+
end
|
|
389
|
+
|
|
388
390
|
describe "and a custom search results class" do
|
|
389
391
|
|
|
390
392
|
before( :each ) do
|
|
@@ -52,7 +52,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
52
52
|
%{EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
|
|
53
53
|
|
|
54
54
|
before( :each ) do
|
|
55
|
-
@attrtype =
|
|
55
|
+
@attrtype = described_class.parse( @schema, OBJECTCLASS_ATTRTYPE )
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it "knows what OID corresponds to the type" do
|
|
@@ -138,7 +138,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
138
138
|
%{SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
|
|
139
139
|
|
|
140
140
|
before( :each ) do
|
|
141
|
-
@attrtype =
|
|
141
|
+
@attrtype = described_class.parse( @schema, DERIVED_ATTRTYPE )
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
it "can fetch its superior type from its schema" do
|
|
@@ -184,7 +184,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
184
184
|
DERIVED_NOSYN_ATTRTYPE = %{( 1.11.2.11.1 SUP aSuperType )}
|
|
185
185
|
|
|
186
186
|
before( :each ) do
|
|
187
|
-
@attrtype =
|
|
187
|
+
@attrtype = described_class.parse( @schema, DERIVED_NOSYN_ATTRTYPE )
|
|
188
188
|
end
|
|
189
189
|
|
|
190
190
|
it "fetches its SYNTAX from its supertype" do
|
|
@@ -203,7 +203,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
203
203
|
MULTINAME_ATTRIBUTETYPE = %{( 1.1.1.1 NAME ('firstName' 'secondName') )}
|
|
204
204
|
|
|
205
205
|
before( :each ) do
|
|
206
|
-
@attrtype =
|
|
206
|
+
@attrtype = described_class.parse( @schema, MULTINAME_ATTRIBUTETYPE )
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
it "knows what both names are" do
|
|
@@ -234,7 +234,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
234
234
|
%{'This spec\\27s example, which includes a \\5c character.' )}
|
|
235
235
|
|
|
236
236
|
before( :each ) do
|
|
237
|
-
@attrtype =
|
|
237
|
+
@attrtype = described_class.parse( @schema, ESCAPED_DESC_ATTRIBUTETYPE )
|
|
238
238
|
end
|
|
239
239
|
|
|
240
240
|
it "unscapes the escaped characters" do
|
|
@@ -248,7 +248,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
248
248
|
OBSOLETE_ATTRIBUTETYPE = %{( 1.1.1.1 OBSOLETE )}
|
|
249
249
|
|
|
250
250
|
before( :each ) do
|
|
251
|
-
@attrtype =
|
|
251
|
+
@attrtype = described_class.parse( @schema, OBSOLETE_ATTRIBUTETYPE )
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
it "knows that it's obsolete" do
|
|
@@ -262,8 +262,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
262
262
|
DIRECTORY_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE directoryOperation )}
|
|
263
263
|
|
|
264
264
|
before( :each ) do
|
|
265
|
-
@attrtype =
|
|
266
|
-
parse( @schema, DIRECTORY_OPERATIONAL_ATTRIBUTETYPE )
|
|
265
|
+
@attrtype = described_class.parse( @schema, DIRECTORY_OPERATIONAL_ATTRIBUTETYPE )
|
|
267
266
|
end
|
|
268
267
|
|
|
269
268
|
it "knows that it's not a user-application attribute type" do
|
|
@@ -293,7 +292,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
293
292
|
DISTRIBUTED_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE distributedOperation )}
|
|
294
293
|
|
|
295
294
|
before( :each ) do
|
|
296
|
-
@attrtype =
|
|
295
|
+
@attrtype = described_class.
|
|
297
296
|
parse( @schema, DISTRIBUTED_OPERATIONAL_ATTRIBUTETYPE )
|
|
298
297
|
end
|
|
299
298
|
|
|
@@ -324,8 +323,7 @@ describe Treequel::Schema::AttributeType do
|
|
|
324
323
|
DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE dSAOperation )}
|
|
325
324
|
|
|
326
325
|
before( :each ) do
|
|
327
|
-
@attrtype =
|
|
328
|
-
parse( @schema, DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE )
|
|
326
|
+
@attrtype = described_class.parse( @schema, DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE )
|
|
329
327
|
end
|
|
330
328
|
|
|
331
329
|
it "knows that it's not a user-application attribute type" do
|
|
@@ -350,6 +348,85 @@ describe Treequel::Schema::AttributeType do
|
|
|
350
348
|
|
|
351
349
|
end
|
|
352
350
|
|
|
351
|
+
describe "parsed from the 'supportedLDAPVersion' attribute type" do
|
|
352
|
+
|
|
353
|
+
SUPPORTED_LDAP_VERSION_ATTRIBUTETYPE = %{( 1.3.6.1.4.1.1466.101.120.15 NAME } +
|
|
354
|
+
%{'supportedLDAPVersion' DESC 'Standard LDAP attribute type' SYNTAX } +
|
|
355
|
+
%{1.3.6.1.4.1.1466.115.121.1.27 USAGE dsaOperation X-ORIGIN 'RFC 2252' )}
|
|
356
|
+
|
|
357
|
+
before( :each ) do
|
|
358
|
+
@attrtype = described_class.parse( @schema, SUPPORTED_LDAP_VERSION_ATTRIBUTETYPE )
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it "knows what OID corresponds to the type" do
|
|
362
|
+
@attrtype.oid.should == '1.3.6.1.4.1.1466.101.120.15'
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
it "knows what its NAME attribute is" do
|
|
366
|
+
@attrtype.name.should == :supportedLDAPVersion
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "knows what its DESC attribute is" do
|
|
370
|
+
@attrtype.desc.should == 'Standard LDAP attribute type'
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
it "knows it doesn't have a superior type" do
|
|
374
|
+
@attrtype.sup.should be_nil()
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it "knows what the name of its equality matching rule is" do
|
|
378
|
+
@attrtype.eqmatch_oid.should be_nil()
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
describe "compatibility with malformed declarations: " do
|
|
384
|
+
|
|
385
|
+
LDAP_CHANGELOG_ATTRIBUTETYPE = %{
|
|
386
|
+
( 2.16.840.1.113730.3.1.35
|
|
387
|
+
NAME 'changelog'
|
|
388
|
+
DESC 'the distinguished name of the entry which contains
|
|
389
|
+
the set of entries comprising this server's changelog'
|
|
390
|
+
EQUALITY distinguishedNameMatch
|
|
391
|
+
SYNTAX 'DN'
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
it "parses the 'changelog' attribute type from draft-good-ldap-changelog" do
|
|
396
|
+
attrtype = described_class.parse( @schema, LDAP_CHANGELOG_ATTRIBUTETYPE )
|
|
397
|
+
|
|
398
|
+
attrtype.should be_a( described_class )
|
|
399
|
+
attrtype.name.should == :changelog
|
|
400
|
+
attrtype.oid.should == '2.16.840.1.113730.3.1.35'
|
|
401
|
+
attrtype.desc.should == %{the distinguished name of the entry which contains } +
|
|
402
|
+
%{the set of entries comprising this server's changelog}
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
LDAP_CHANGELOG_CHANGENUMBER_ATTRIBUTETYPE = %{
|
|
406
|
+
( 2.16.840.1.113730.3.1.5
|
|
407
|
+
NAME 'changeNumber'
|
|
408
|
+
DESC 'a number which uniquely identifies a change made to a
|
|
409
|
+
directory entry'
|
|
410
|
+
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
|
|
411
|
+
EQUALITY integerMatch
|
|
412
|
+
ORDERING integerOrderingMatch
|
|
413
|
+
SINGLE-VALUE
|
|
414
|
+
)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
it "parses the 'changeNumber' attribute from draft-good-ldap-changelog" do
|
|
418
|
+
attrtype = described_class.parse( @schema, LDAP_CHANGELOG_CHANGENUMBER_ATTRIBUTETYPE )
|
|
419
|
+
|
|
420
|
+
attrtype.should be_a( described_class )
|
|
421
|
+
attrtype.name.should == :changeNumber
|
|
422
|
+
attrtype.oid.should == '2.16.840.1.113730.3.1.5'
|
|
423
|
+
attrtype.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.27'
|
|
424
|
+
attrtype.desc.should == %{a number which uniquely identifies a change made to a } +
|
|
425
|
+
%{directory entry}
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
end
|
|
429
|
+
|
|
353
430
|
end
|
|
354
431
|
|
|
355
432
|
|
|
@@ -158,6 +158,43 @@ describe Treequel::Schema::MatchingRule do
|
|
|
158
158
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
+
|
|
162
|
+
describe "parsed from one of the matching rules from the OpenDS schema" do
|
|
163
|
+
|
|
164
|
+
TIME_BASED_MATCHINGRULE = %{( 1.3.6.1.4.1.26027.1.4.5 NAME } +
|
|
165
|
+
%{( 'relativeTimeGTOrderingMatch' 'relativeTimeOrderingMatch.gt' ) } +
|
|
166
|
+
%{SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )}
|
|
167
|
+
|
|
168
|
+
before( :each ) do
|
|
169
|
+
@rule = Treequel::Schema::MatchingRule.parse( @schema, TIME_BASED_MATCHINGRULE )
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "knows that it's obsolete" do
|
|
173
|
+
@rule.name.should == :relativeTimeGTOrderingMatch
|
|
174
|
+
@rule.names.should include( :relativeTimeGTOrderingMatch, :'relativeTimeOrderingMatch.gt' )
|
|
175
|
+
@rule.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.24'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
describe "parsed from one of the matching rules from issue 11" do
|
|
182
|
+
|
|
183
|
+
NAME_AND_OID_MATCHINGRULE = %{( 1.3.6.1.4.1.42.2.27.9.4.0.3 } +
|
|
184
|
+
%{NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3' } +
|
|
185
|
+
%{SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )}
|
|
186
|
+
|
|
187
|
+
before( :each ) do
|
|
188
|
+
@rule = Treequel::Schema::MatchingRule.parse( @schema, NAME_AND_OID_MATCHINGRULE )
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "knows what its rule is" do
|
|
192
|
+
@rule.name.should == 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3'.to_sym
|
|
193
|
+
@rule.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.15'
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
|
|
161
198
|
end
|
|
162
199
|
|
|
163
200
|
|
|
@@ -53,7 +53,6 @@ describe Treequel::Schema::ObjectClass do
|
|
|
53
53
|
%{ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $} +
|
|
54
54
|
%{ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l ) )}
|
|
55
55
|
|
|
56
|
-
|
|
57
56
|
before( :all ) do
|
|
58
57
|
setup_logging( :fatal )
|
|
59
58
|
@datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
|
|
@@ -316,6 +315,91 @@ describe Treequel::Schema::ObjectClass do
|
|
|
316
315
|
end
|
|
317
316
|
end
|
|
318
317
|
|
|
318
|
+
|
|
319
|
+
# Sun/Oracle OpenDS (as of 2.2, at least) "allows a non-numeric OID [as the
|
|
320
|
+
# 'numericoid' part of an objectClass definition] for the purpose of convenience"
|
|
321
|
+
describe "Sun OpenDS compatibility workarounds (ticket #11)" do
|
|
322
|
+
|
|
323
|
+
SUN_ODS_DESCR_OID_OBJECTCLASS =
|
|
324
|
+
%{( interwovengroup-oid NAME 'interwovengroup' SUP posixgroup } +
|
|
325
|
+
%{ STRUCTURAL MAY path X-ORIGIN 'user defined' )}
|
|
326
|
+
|
|
327
|
+
before( :each ) do
|
|
328
|
+
@oc = Treequel::Schema::ObjectClass.parse( @schema, SUN_ODS_DESCR_OID_OBJECTCLASS )
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
it "sets the oid to the non-numeric OID value" do
|
|
333
|
+
@oc.oid.should == 'interwovengroup-oid'
|
|
334
|
+
@oc.name.should == :interwovengroup
|
|
335
|
+
@oc.extensions.should == %{X-ORIGIN 'user defined'}
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
describe "compatibility with malformed declarations: " do
|
|
342
|
+
|
|
343
|
+
SLP_SERVICE_OBJECTCLASS = %{
|
|
344
|
+
( 1.3.6.1.4.1.6252.2.27.6.2.1
|
|
345
|
+
NAME 'slpService'
|
|
346
|
+
DESC 'parent superclass for SLP services'
|
|
347
|
+
ABSTRACT
|
|
348
|
+
SUP top
|
|
349
|
+
MUST ( template-major-version-number $
|
|
350
|
+
template-minor-version-number $
|
|
351
|
+
description $
|
|
352
|
+
template-url-syntax $
|
|
353
|
+
service-advert-service-type $
|
|
354
|
+
service-advert-scopes )
|
|
355
|
+
MAY ( service-advert-url-authenticator $
|
|
356
|
+
service-advert-attribute-authenticator ) )
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
it "parses the malformed objectClass from RFC 2926" do
|
|
360
|
+
oc = Treequel::Schema::ObjectClass.parse( @schema, SLP_SERVICE_OBJECTCLASS )
|
|
361
|
+
|
|
362
|
+
oc.should be_a( Treequel::Schema::ObjectClass )
|
|
363
|
+
oc.name.should == :slpService
|
|
364
|
+
oc.oid.should == '1.3.6.1.4.1.6252.2.27.6.2.1'
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
AUTH_PASSWORD_OBJECT_OBJECTCLASS = %{
|
|
369
|
+
( 1.3.6.1.4.1.4203.1.4.7 NAME 'authPasswordObject'
|
|
370
|
+
DESC 'authentication password mix in class'
|
|
371
|
+
MAY 'authPassword'
|
|
372
|
+
AUXILIARY )
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
it "parses the malformed authPasswordObject objectClass from RFC2696" do
|
|
376
|
+
oc = Treequel::Schema::ObjectClass.parse( @schema, AUTH_PASSWORD_OBJECT_OBJECTCLASS )
|
|
377
|
+
|
|
378
|
+
oc.should be_a( Treequel::Schema::ObjectClass )
|
|
379
|
+
oc.name.should == :authPasswordObject
|
|
380
|
+
oc.oid.should == '1.3.6.1.4.1.4203.1.4.7'
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
DRAFT_HOWARD_RFC2307BIS_OBJECTCLASS = %{
|
|
384
|
+
( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
|
|
385
|
+
SUP top
|
|
386
|
+
AUXILIARY
|
|
387
|
+
DESC 'Abstraction of an account with POSIX attributes'
|
|
388
|
+
MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
|
|
389
|
+
MAY ( authPassword $ userPassword $ loginShell $ gecos $ description )
|
|
390
|
+
X-ORIGIN 'draft-howard-rfc2307bis' )
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
it "parses the malformed objectClasses from draft-howard-rfc2307bis" do
|
|
394
|
+
oc = Treequel::Schema::ObjectClass.parse( @schema, DRAFT_HOWARD_RFC2307BIS_OBJECTCLASS )
|
|
395
|
+
|
|
396
|
+
oc.should be_a( Treequel::Schema::ObjectClass )
|
|
397
|
+
oc.name.should == :posixAccount
|
|
398
|
+
oc.oid.should == '1.3.6.1.1.1.2.0'
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
end
|
|
402
|
+
|
|
319
403
|
end
|
|
320
404
|
|
|
321
405
|
|
|
@@ -12,7 +12,6 @@ BEGIN {
|
|
|
12
12
|
|
|
13
13
|
require 'rspec'
|
|
14
14
|
|
|
15
|
-
require 'spec/lib/constants'
|
|
16
15
|
require 'spec/lib/helpers'
|
|
17
16
|
|
|
18
17
|
require 'yaml'
|
|
@@ -21,29 +20,108 @@ require 'ldap/schema'
|
|
|
21
20
|
require 'treequel/schema'
|
|
22
21
|
|
|
23
22
|
|
|
24
|
-
include Treequel::TestConstants
|
|
25
|
-
include Treequel::Constants
|
|
26
|
-
|
|
27
|
-
#####################################################################
|
|
28
|
-
### C O N T E X T S
|
|
29
|
-
#####################################################################
|
|
30
|
-
|
|
31
23
|
describe Treequel::Schema do
|
|
32
24
|
include Treequel::SpecHelpers
|
|
33
25
|
|
|
34
26
|
before( :all ) do
|
|
35
|
-
setup_logging( :
|
|
27
|
+
setup_logging( :warn )
|
|
36
28
|
@datadir = Pathname( __FILE__ ).dirname.parent + 'data'
|
|
37
29
|
end
|
|
38
30
|
|
|
31
|
+
before( :each ) do
|
|
32
|
+
@strict_flag = Treequel::Schema.strict_parse_mode?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
after( :each ) do
|
|
36
|
+
Treequel::Schema.strict_parse_mode = @strict_flag
|
|
37
|
+
end
|
|
38
|
+
|
|
39
39
|
after( :all ) do
|
|
40
40
|
reset_logging()
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
### Constants
|
|
44
|
+
|
|
45
|
+
# Some simple parser-testing values
|
|
43
46
|
TEST_NUMERICOID = '1.12.3.8.16.1.1.5'
|
|
44
47
|
TEST_DESCR = 'objectClass'
|
|
45
48
|
TEST_OIDLIST = %:( #{TEST_DESCR} $ objectCaste $ #{TEST_NUMERICOID} ) :
|
|
46
49
|
|
|
50
|
+
# The malformed objectClass from RFC2926, for testing schema-parsing lenience
|
|
51
|
+
BAD_OBJECTCLASS = "( 1.3.6.1.4.1.6252.2.27.6.2.1 NAME 'slpService' " +
|
|
52
|
+
"DESC 'parent superclass for SLP services' ABSTRACT SUP top MUST " +
|
|
53
|
+
" ( template-major-version-number $ template-minor-version-number " +
|
|
54
|
+
"$ description $ template-url-syntax $ service-advert-service-type " +
|
|
55
|
+
"$ service-advert-scopes ) MAY ( service-advert-url-authenticator " +
|
|
56
|
+
"$ service-advert-attribute-authenticator ) X-ORIGIN 'RFC 2926' )"
|
|
57
|
+
|
|
58
|
+
### Matchers
|
|
59
|
+
|
|
60
|
+
RSpec::Matchers.define( :be_lenient ) do
|
|
61
|
+
match do |actual|
|
|
62
|
+
!actual.strict_parse_mode?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### Examples
|
|
68
|
+
|
|
69
|
+
it "defaults to lenient schema-parsing" do
|
|
70
|
+
Treequel::Schema.should be_lenient()
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "can be told to propagate schema-parsing failures for easier problem-detection" do
|
|
74
|
+
Treequel::Schema.strict_parse_mode = true
|
|
75
|
+
Treequel::Schema.should_not be_lenient()
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
it "doesn't propagate parse errors while in lenient schema-parsing mode" do
|
|
80
|
+
schema = Treequel::Schema.new( 'objectClasses' => [BAD_OBJECTCLASS],
|
|
81
|
+
'attributeTypes' => [],
|
|
82
|
+
'ldapSyntaxes' => [],
|
|
83
|
+
'matchingRules' => [],
|
|
84
|
+
'matchingRuleUse' => [] )
|
|
85
|
+
schema.should be_a( Treequel::Schema )
|
|
86
|
+
schema.object_classes.keys.should_not include( 'slpService' )
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "propagates parse errors while in strict schema-parsing mode" do
|
|
90
|
+
Treequel::Schema.strict_parse_mode = true
|
|
91
|
+
expect {
|
|
92
|
+
Treequel::Schema.new( 'objectClasses' => [BAD_OBJECTCLASS] )
|
|
93
|
+
}.to raise_exception( Treequel::ParseError, /malformed objectClass/i )
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "can parse a valid oidlist" do
|
|
97
|
+
oids = Treequel::Schema.parse_oids( TEST_OIDLIST )
|
|
98
|
+
oids.should have(3).members
|
|
99
|
+
oids.should == [ :objectClass, :objectCaste, TEST_NUMERICOID ]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "returns an empty Array if oidlist it's asked to parse is nil" do
|
|
103
|
+
Treequel::Schema.parse_oids( nil ).should == []
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "raises an exception if it's asked to parse an invalid oidlist" do
|
|
107
|
+
expect do
|
|
108
|
+
Treequel::Schema.parse_oids( %Q{my name is Jorma, I'm the sensitive one} )
|
|
109
|
+
end.to raise_error( Treequel::ParseError, /oidlist/i )
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
it "keeps a numeric OID as a String when parsing it" do
|
|
114
|
+
Treequel::Schema.parse_oid( TEST_NUMERICOID ).should be_a( String )
|
|
115
|
+
Treequel::Schema.parse_oid( TEST_NUMERICOID ).should == TEST_NUMERICOID
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "transforms a named OID as a Symbol when parsing it" do
|
|
119
|
+
Treequel::Schema.parse_oid( TEST_DESCR ).should be_a( Symbol )
|
|
120
|
+
Treequel::Schema.parse_oid( TEST_DESCR ).should == TEST_DESCR.to_sym
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
47
125
|
context "OpenLDAP schema" do
|
|
48
126
|
before( :all ) do
|
|
49
127
|
@schema_dumpfile = @datadir + 'schema.yml'
|
|
@@ -72,7 +150,8 @@ describe Treequel::Schema do
|
|
|
72
150
|
end
|
|
73
151
|
|
|
74
152
|
|
|
75
|
-
it "can parse the schema structure returned from LDAP::Conn#schema even under $SAFE >= 1"
|
|
153
|
+
it "can parse the schema structure returned from LDAP::Conn#schema even under $SAFE >= 1",
|
|
154
|
+
:mri_only => true do
|
|
76
155
|
schema = nil
|
|
77
156
|
Thread.new do
|
|
78
157
|
Thread.current.abort_on_exception = true
|
|
@@ -105,37 +184,73 @@ describe Treequel::Schema do
|
|
|
105
184
|
@schema.operational_attribute_types.should be_empty()
|
|
106
185
|
end
|
|
107
186
|
|
|
108
|
-
|
|
109
187
|
end
|
|
110
188
|
|
|
111
189
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
190
|
+
# Dumped from an OpenDS 2.2 server with the included 'test data' -- dunno if that's
|
|
191
|
+
# representative of schemas one would find in the wild, but it doesn't parse as-is
|
|
192
|
+
# currently because of (at least) the objectClasses from RFCs 2696, 3112, 3712, and
|
|
193
|
+
# draft-howard-rfc2307bi
|
|
194
|
+
context "OpenDS schema" do
|
|
117
195
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
196
|
+
before( :all ) do
|
|
197
|
+
@schema_dumpfile = @datadir + 'opends.yml'
|
|
198
|
+
@hash = YAML.load_file( @schema_dumpfile )
|
|
199
|
+
@schemahash = LDAP::Schema.new( @hash )
|
|
200
|
+
end
|
|
121
201
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Treequel::Schema.parse_oids( %Q{my name is Jorma, I'm the sensitive one} )
|
|
125
|
-
end.to raise_error( Treequel::ParseError, /oidlist/i )
|
|
126
|
-
end
|
|
202
|
+
it "can parse an OpenDS schema structure, too" do
|
|
203
|
+
@schema = Treequel::Schema.new( @schemahash )
|
|
127
204
|
|
|
205
|
+
@schema.object_classes.values.uniq.should have( @hash['objectClasses'].length ).members
|
|
206
|
+
@schema.attribute_types.values.uniq.should have( @hash['attributeTypes'].length ).members
|
|
207
|
+
@schema.matching_rules.values.uniq.should have( @hash['matchingRules'].length ).members
|
|
208
|
+
@schema.ldap_syntaxes.values.uniq.should have( @hash['ldapSyntaxes'].length ).members
|
|
209
|
+
|
|
210
|
+
@schema.matching_rule_uses.should be_empty()
|
|
211
|
+
|
|
212
|
+
# Not yet supported
|
|
213
|
+
# @schema.dit_structure_rules.values.uniq.should have( @hash['dITStructureRules'].length ).members
|
|
214
|
+
# @schema.dit_content_rules.values.uniq.should have( @hash['dITContentRules'].length ).members
|
|
215
|
+
# @schema.name_forms.values.uniq.should have( @hash['nameForms'].length ).members
|
|
216
|
+
|
|
217
|
+
dirop_count = @hash['attributeTypes'].
|
|
218
|
+
count {|type| type.index('USAGE directoryOperation') }
|
|
219
|
+
dsaop_count = @hash['attributeTypes'].
|
|
220
|
+
count {|type| type.index('USAGE dSAOperation') }
|
|
221
|
+
distop_count = @hash['attributeTypes'].
|
|
222
|
+
count {|type| type.index('USAGE distributedOperation') }
|
|
223
|
+
op_attrcount = dirop_count + dsaop_count + distop_count
|
|
224
|
+
|
|
225
|
+
@schema.operational_attribute_types.should have( op_attrcount ).members
|
|
226
|
+
end
|
|
128
227
|
|
|
129
|
-
it "keeps a numeric OID as a String when parsing it" do
|
|
130
|
-
Treequel::Schema.parse_oid( TEST_NUMERICOID ).should be_a( String )
|
|
131
|
-
Treequel::Schema.parse_oid( TEST_NUMERICOID ).should == TEST_NUMERICOID
|
|
132
228
|
end
|
|
133
229
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
230
|
+
|
|
231
|
+
# Attribute types and matching rules from ticket #11
|
|
232
|
+
context "ticket 11 schema artifacts" do
|
|
233
|
+
|
|
234
|
+
before( :all ) do
|
|
235
|
+
@schema_dumpfile = @datadir + 'ticket11.yml'
|
|
236
|
+
@hash = YAML.load_file( @schema_dumpfile )
|
|
237
|
+
@schemahash = LDAP::Schema.new( @hash )
|
|
238
|
+
@schema = Treequel::Schema.new( @schemahash )
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it "can parse schema artifacts from ticket 11" do
|
|
242
|
+
@schema.attribute_types.values.uniq.should have( @hash['attributeTypes'].length ).members
|
|
243
|
+
@schema.matching_rules.values.uniq.should have( @hash['matchingRules'].length ).members
|
|
244
|
+
|
|
245
|
+
dsaop_count = @hash['attributeTypes'].
|
|
246
|
+
count {|type| type.index('USAGE dsaOperation') }
|
|
247
|
+
|
|
248
|
+
@schema.operational_attribute_types.should have( dsaop_count ).members
|
|
249
|
+
end
|
|
250
|
+
|
|
137
251
|
end
|
|
138
252
|
|
|
253
|
+
|
|
139
254
|
end
|
|
140
255
|
|
|
141
256
|
|
data.tar.gz.sig
CHANGED
|
Binary file
|