jruby-ldap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,74 @@
1
+ module LDAP
2
+ class << self
3
+ def mod(mod_type, attr, vals)
4
+ Mod.new(mod_type, attr, vals)
5
+ end
6
+
7
+ def hash2mods(mod_type, hash)
8
+ hash.map do |key, value|
9
+ mod(mod_type, key, value)
10
+ end
11
+ end
12
+ end
13
+
14
+ class Mod
15
+ BasicAttributes = javax.naming.directory.BasicAttributes
16
+ BasicAttribute = javax.naming.directory.BasicAttribute
17
+ ModificationItem = javax.naming.directory.ModificationItem
18
+ DirContext = javax.naming.directory.DirContext
19
+ class << self
20
+ def to_java_attributes(*attrs)
21
+ attrs.inject(BasicAttributes.new) do |res, attr|
22
+ res.put(attr.to_java_attribute)
23
+ res
24
+ end
25
+ end
26
+
27
+ def ruby_mod_to_java(mod_op)
28
+ case (mod_op&~LDAP::LDAP_MOD_BVALUES)
29
+ when LDAP::LDAP_MOD_ADD: DirContext::ADD_ATTRIBUTE
30
+ when LDAP::LDAP_MOD_REPLACE: DirContext::REPLACE_ATTRIBUTE
31
+ when LDAP::LDAP_MOD_DELETE: DirContext::REMOVE_ATTRIBUTE
32
+ else raise LDAP::Error, "can't handle operation #{mod_op}"
33
+ end
34
+ end
35
+
36
+ def to_java_modification_items(*attrs)
37
+ attrs.map do |val|
38
+ ModificationItem.new(ruby_mod_to_java(val.mod_op), val.to_java_attribute)
39
+ end.to_java ModificationItem
40
+ end
41
+ end
42
+
43
+ def initialize(mod_type, attr, vals)
44
+ @type, @attr, @vals = mod_type, attr, vals
45
+ end
46
+
47
+ def mod_op #should be mod_type
48
+ @type
49
+ end
50
+
51
+ def mod_type #should be attr
52
+ @attr
53
+ end
54
+
55
+ def mod_vals
56
+ @vals
57
+ end
58
+
59
+ def to_java_attribute
60
+ v = BasicAttribute.new(self.mod_type)
61
+ binary = mod_op & LDAP::LDAP_MOD_BVALUES
62
+ if binary
63
+ self.mod_vals.each do |val|
64
+ v.add(val.to_java_bytes)
65
+ end
66
+ else
67
+ self.mod_vals.each do |val|
68
+ v.add(val)
69
+ end
70
+ end
71
+ v
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,131 @@
1
+ # Manipulation of LDAP schema data.
2
+ #
3
+ #--
4
+ # $Id: schema.rb,v 1.9 2006/02/08 23:15:17 ianmacd Exp $
5
+ #++
6
+
7
+ # The LDAP module encapsulates the various LDAP-related classes in their own
8
+ # namespace.
9
+ #
10
+ module LDAP
11
+
12
+ # Retrieve and process information pertaining to LDAP schemas.
13
+ #
14
+ class Schema < Hash
15
+
16
+ def initialize(entry)
17
+ if( entry )
18
+ entry.each{|key,vals|
19
+ self[key] = vals
20
+ }
21
+ end
22
+ end
23
+
24
+ # Return the list of values related to the schema component given in
25
+ # +key+. See LDAP::Conn#schema for common values of +key+.
26
+ #
27
+ def names(key)
28
+ self[key].collect{|val| val =~ /NAME\s+'([\w\d_-]+)'/; $1}
29
+ end
30
+
31
+ # Return the list of attributes in object class +oc+ that are of category
32
+ # +at+. +at+ may be the string *MUST*, *MAY* or *SUP*.
33
+ #
34
+ def attr(oc,at)
35
+ self['objectClasses'].each{|s|
36
+ if( s =~ /NAME\s+'#{oc}'/ )
37
+ case s
38
+ when /#{at}\s+\(([\w\d_-\s\$]+)\)/i
39
+ return $1.split("$").collect{|attr| attr.strip}
40
+ when /#{at}\s+([\w\d_-]+)/i
41
+ return $1.split("$").collect{|attr| attr.strip}
42
+ end
43
+ end
44
+ }
45
+ return nil
46
+ end
47
+
48
+ # Return the list of attributes that an entry with object class +oc+
49
+ # _must_ possess.
50
+ #
51
+ def must(oc)
52
+ attr(oc, "MUST")
53
+ end
54
+
55
+ # Return the list of attributes that an entry with object class +oc+
56
+ # _may_ possess.
57
+ #
58
+ def may(oc)
59
+ attr(oc, "MAY")
60
+ end
61
+
62
+ # Return the superior object class of object class +oc+.
63
+ #
64
+ def sup(oc)
65
+ attr(oc, "SUP")
66
+ end
67
+ end
68
+
69
+ class Conn
70
+
71
+ # Fetch the schema data for the connection.
72
+ #
73
+ # If +base+ is given, it gives the base DN for the search. +attrs+, if
74
+ # given, is an array of attributes that should be returned from the
75
+ # server. The default list is *objectClasses*, *attributeTypes*,
76
+ # *matchingRules*, *matchingRuleUse*, *dITStructureRules*,
77
+ # *dITContentRules*, *nameForms* and *ldapSyntaxes*.
78
+ #
79
+ # +sec+ and +usec+ can be used to specify a time-out for the search in
80
+ # seconds and microseconds, respectively.
81
+ #
82
+ def schema(base = nil, attrs = nil, sec = 0, usec = 0)
83
+ attrs ||= [
84
+ 'objectClasses',
85
+ 'attributeTypes',
86
+ 'matchingRules',
87
+ 'matchingRuleUse',
88
+ 'dITStructureRules',
89
+ 'dITContentRules',
90
+ 'nameForms',
91
+ 'ldapSyntaxes',
92
+ ]
93
+ base ||= root_dse(['subschemaSubentry'], sec, usec)[0]['subschemaSubentry'][0]
94
+ base ||= 'cn=schema'
95
+ ent = search2(base, LDAP_SCOPE_BASE, '(objectClass=subschema)',
96
+ attrs, false, sec, usec)
97
+ return Schema.new(ent[0])
98
+ end
99
+
100
+ # Fetch the root DSE (DSA-specific Entry) for the connection. DSA stands
101
+ # for Directory System Agent and simply refers to the LDAP server you are
102
+ # using.
103
+ #
104
+ # +attrs+, if given, is an array of attributes that should be returned
105
+ # from the server. The default list is *subschemaSubentry*,
106
+ # *namingContexts*, *monitorContext*, *altServer*, *supportedControl*,
107
+ # *supportedExtension*, *supportedFeatures*, *supportedSASLMechanisms*
108
+ # and *supportedLDAPVersion*.
109
+ #
110
+ # +sec+ and +usec+ can be used to specify a time-out for the search in
111
+ # seconds and microseconds, respectively.
112
+ #
113
+ def root_dse(attrs = nil, sec = 0, usec = 0)
114
+ attrs ||= [
115
+ 'subschemaSubentry',
116
+ 'namingContexts',
117
+ 'monitorContext',
118
+ 'altServer',
119
+ 'supportedControl',
120
+ 'supportedExtension',
121
+ 'supportedFeatures',
122
+ 'supportedSASLMechanisms',
123
+ 'supportedLDAPVersion',
124
+ ]
125
+
126
+ entries = search2('', LDAP_SCOPE_BASE, '(objectClass=*)',
127
+ attrs, false, sec, usec)
128
+ return entries
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,51 @@
1
+
2
+ require 'ldap'
3
+ require './username_and_password'
4
+
5
+ $LDAP_test_host = 'localhost'
6
+ $LDAP_test_port = LDAP::LDAP_PORT
7
+
8
+ def delete_tree(c, name)
9
+ c.search(name, LDAP::LDAP_SCOPE_ONELEVEL, "(objectClass=*)", ['dn']) do |v|
10
+ delete_tree c, v.get_dn
11
+ end rescue nil
12
+ c.delete(name)
13
+ end
14
+
15
+
16
+ c = LDAP::Conn.new($LDAP_test_host, $LDAP_test_port)
17
+ c.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
18
+ c.bind($LDAP_test_username, $LDAP_test_password) do
19
+ # just clean out and create our tree
20
+
21
+ delete_tree(c, 'o=ruby_ldap_test_tree')
22
+
23
+ c.add('o=ruby_ldap_test_tree', {'objectClass' => ['organization'], 'o' => ['ruby_ldap_test_tree']})
24
+ c.add('o=sub_tree, o=ruby_ldap_test_tree', {'objectClass' => ['organization'], 'o' => ['sub_tree']})
25
+ end
26
+
27
+
28
+ module Test::Unit::Assertions
29
+ def assert_exists_in_ldap dn, attrs = {}
30
+ found = 0
31
+ @conn.search(dn, LDAP::LDAP_SCOPE_BASE, "(objectClass=*)", attrs.keys) do |entry|
32
+ found += 1
33
+
34
+ assert_equal dn, entry.get_dn
35
+ assert_equal attrs.keys.sort, entry.get_attributes.sort unless attrs == { }
36
+ attrs.each do |k,v|
37
+ assert_equal v, entry[k]
38
+ assert_equal v, entry[k.downcase]
39
+ assert_equal v, entry[k.upcase]
40
+ end
41
+ end
42
+
43
+ assert_equal 1,found
44
+ end
45
+
46
+ def assert_dont_exists_in_ldap dn
47
+ assert_raises(LDAP::ResultError) do
48
+ @conn.search(dn, LDAP::LDAP_SCOPE_BASE, "(objectClass=*)", []) { }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ require 'test/unit'
2
+ require 'setup'
3
+
4
+ class TestAdd < Test::Unit::TestCase
5
+ def setup
6
+ @conn = LDAP::Conn.new($LDAP_test_host, $LDAP_test_port)
7
+ @conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
8
+ @conn.bind($LDAP_test_username, $LDAP_test_password)
9
+ end
10
+
11
+ def teardown
12
+ @conn.unbind rescue nil
13
+ end
14
+
15
+ def test_simple_add
16
+ @conn.add("o=fox3,o=ruby_ldap_test_tree", {'o' => ["fox3"], 'objectClass' => ['organization']})
17
+ assert_exists_in_ldap "o=fox3,o=ruby_ldap_test_tree", {'o' => ["fox3"]}
18
+ ensure
19
+ @conn.delete("o=fox3,o=ruby_ldap_test_tree") rescue nil
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ require 'test/unit'
2
+ require 'setup'
3
+
4
+ class TestConnection < Test::Unit::TestCase
5
+ def setup
6
+ @conn = LDAP::Conn.new($LDAP_test_host, $LDAP_test_port)
7
+ @conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
8
+ @conn.bind($LDAP_test_username, $LDAP_test_password)
9
+ end
10
+
11
+ def teardown
12
+ @conn.unbind rescue nil
13
+ end
14
+
15
+ if defined?(JRUBY_VERSION)
16
+ def test_rebind
17
+ id = @conn.object_id
18
+
19
+ assert_nothing_raised do
20
+ @conn.unbind
21
+ @conn.bind
22
+ end
23
+
24
+ id2 = @conn.object_id
25
+ assert_equal( id, id2 )
26
+
27
+ assert_nothing_raised do
28
+ @conn.unbind
29
+ @conn.simple_bind
30
+ end
31
+
32
+ id2 = @conn.object_id
33
+ assert_equal( id, id2 )
34
+ end
35
+ end
36
+
37
+ def test_double_bind
38
+ assert_raises( LDAP::Error ) { @conn.bind }
39
+ assert_raises( LDAP::Error ) { @conn.simple_bind }
40
+ end
41
+
42
+ def test_double_unbind
43
+ assert_nothing_raised { @conn.unbind }
44
+ assert_raises( LDAP::InvalidDataError ) { @conn.unbind }
45
+ end
46
+
47
+ def test_bound?
48
+ assert( @conn.bound? )
49
+ @conn.unbind
50
+ assert( ! @conn.bound? )
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ require 'test/unit'
2
+ require 'setup'
3
+
4
+ class TestDelete < Test::Unit::TestCase
5
+ def setup
6
+ @conn = LDAP::Conn.new($LDAP_test_host, $LDAP_test_port)
7
+ @conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
8
+ @conn.bind($LDAP_test_username, $LDAP_test_password)
9
+ end
10
+
11
+ def teardown
12
+ @conn.unbind rescue nil
13
+ end
14
+
15
+ def test_simple_delete
16
+ @conn.add("o=fox3,o=ruby_ldap_test_tree", {'o' => ["fox3"], 'objectClass' => ['organization']})
17
+ assert_exists_in_ldap "o=fox3,o=ruby_ldap_test_tree"
18
+ @conn.delete("o=fox3,o=ruby_ldap_test_tree")
19
+ assert_dont_exists_in_ldap "o=fox3,o=ruby_ldap_test_tree"
20
+ end
21
+ end
@@ -0,0 +1,87 @@
1
+ require 'test/unit'
2
+ require 'setup'
3
+
4
+ class TestSearch < Test::Unit::TestCase
5
+ def setup
6
+ @conn = LDAP::Conn.new($LDAP_test_host, $LDAP_test_port)
7
+ @conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
8
+ @conn.bind($LDAP_test_username, $LDAP_test_password)
9
+ end
10
+
11
+ def teardown
12
+ @conn.unbind rescue nil
13
+ end
14
+
15
+ def test_simple_base_search
16
+ found = 0
17
+ @conn.search('o=ruby_ldap_test_tree', LDAP::LDAP_SCOPE_BASE, "(objectClass=*)", []) do |v|
18
+ found += 1
19
+
20
+ assert_equal 'o=ruby_ldap_test_tree', v.get_dn
21
+ assert_equal ['o', 'objectClass'].sort, v.get_attributes.sort
22
+ assert_equal ['ruby_ldap_test_tree'], v['o']
23
+ assert_equal ['organization'], v['objectClass']
24
+ assert_equal ['organization'], v['OBJECTCLASS']
25
+ end
26
+
27
+ assert_equal 1,found
28
+ end
29
+
30
+ def test_simple_one_level_search
31
+ found = 0
32
+ @conn.search('o=ruby_ldap_test_tree', LDAP::LDAP_SCOPE_ONELEVEL, "(objectClass=*)", []) do |v|
33
+ found += 1
34
+
35
+ assert_equal 'o=sub_tree,o=ruby_ldap_test_tree', v.get_dn
36
+ assert_equal ['o', 'objectClass'].sort, v.get_attributes.sort
37
+ assert_equal ['sub_tree'], v['o']
38
+ assert_equal ['organization'], v['objectClass']
39
+ assert_equal ['organization'], v['OBJECTCLASS']
40
+ end
41
+
42
+ assert_equal 1,found
43
+ end
44
+
45
+ def test_simple_subtree_search
46
+ found = 0
47
+
48
+ @conn.search('o=ruby_ldap_test_tree', LDAP::LDAP_SCOPE_SUBTREE, "(objectClass=*)", []) do |v|
49
+ found += 1
50
+ if v.get_dn =~ /sub_tree/
51
+ assert_equal 'o=sub_tree,o=ruby_ldap_test_tree', v.get_dn
52
+ assert_equal ['o', 'objectClass'].sort, v.get_attributes.sort
53
+ assert_equal ['sub_tree'], v['o']
54
+ assert_equal ['organization'], v['objectClass']
55
+ assert_equal ['organization'], v['OBJECTCLASS']
56
+ else
57
+ assert_equal 'o=ruby_ldap_test_tree', v.get_dn
58
+ assert_equal ['o', 'objectClass'].sort, v.get_attributes.sort
59
+ assert_equal ['ruby_ldap_test_tree'], v['o']
60
+ assert_equal ['organization'], v['objectClass']
61
+ assert_equal ['organization'], v['OBJECTCLASS']
62
+ end
63
+ end
64
+
65
+ assert_equal 2,found
66
+ end
67
+
68
+ def test_filter
69
+ found = 0
70
+
71
+ @conn.search('o=ruby_ldap_test_tree', LDAP::LDAP_SCOPE_SUBTREE, "(o=sub_tree)", []) do |v|
72
+ found += 1
73
+
74
+ assert_equal 'o=sub_tree,o=ruby_ldap_test_tree', v.get_dn
75
+ assert_equal ['o', 'objectClass'].sort, v.get_attributes.sort
76
+ assert_equal ['sub_tree'], v['o']
77
+ assert_equal ['organization'], v['objectClass']
78
+ assert_equal ['organization'], v['OBJECTCLASS']
79
+ end
80
+
81
+ assert_equal 1,found
82
+ end
83
+
84
+ def test_attributes
85
+ assert_exists_in_ldap 'o=sub_tree,o=ruby_ldap_test_tree', {'objectClass' => ['organization'] }
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+ require 'test/unit'
2
+ require 'setup'
3
+
4
+ class TestSSLAdd# < Test::Unit::TestCase
5
+ def setup
6
+ @conn = LDAP::SSLConn.new($LDAP_test_host, LDAP::LDAPS_PORT)
7
+ @conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
8
+ @conn.bind($LDAP_test_username, $LDAP_test_password)
9
+ end
10
+
11
+ def teardown
12
+ @conn.unbind rescue nil
13
+ end
14
+
15
+ def test_simple_add
16
+ @conn.add("o=fox3,o=ruby_ldap_test_tree", {'o' => ["fox3"], 'objectClass' => ['organization']})
17
+ assert_exists_in_ldap "o=fox3,o=ruby_ldap_test_tree", {'o' => ["fox3"]}
18
+ ensure
19
+ @conn.delete("o=fox3,o=ruby_ldap_test_tree") rescue nil
20
+ end
21
+ end