scashin133-net-ldap 0.1.2

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.
@@ -0,0 +1,208 @@
1
+ # LDAP Entry (search-result) support classes
2
+ #
3
+ #----------------------------------------------------------------------------
4
+ #
5
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
6
+ #
7
+ # Gmail: garbagecat10
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation; either version 2 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # This program is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with this program; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #
23
+ #---------------------------------------------------------------------------
24
+
25
+ ##
26
+ # Objects of this class represent individual entries in an LDAP directory.
27
+ # User code generally does not instantiate this class. Net::LDAP#search
28
+ # provides objects of this class to user code, either as block parameters or
29
+ # as return values.
30
+ #
31
+ # In LDAP-land, an "entry" is a collection of attributes that are uniquely
32
+ # and globally identified by a DN ("Distinguished Name"). Attributes are
33
+ # identified by short, descriptive words or phrases. Although a directory is
34
+ # free to implement any attribute name, most of them follow rigorous
35
+ # standards so that the range of commonly-encountered attribute names is not
36
+ # large.
37
+ #
38
+ # An attribute name is case-insensitive. Most directories also restrict the
39
+ # range of characters allowed in attribute names. To simplify handling
40
+ # attribute names, Net::LDAP::Entry internally converts them to a standard
41
+ # format. Therefore, the methods which take attribute names can take Strings
42
+ # or Symbols, and work correctly regardless of case or capitalization.
43
+ #
44
+ # An attribute consists of zero or more data items called <i>values.</i> An
45
+ # entry is the combination of a unique DN, a set of attribute names, and a
46
+ # (possibly-empty) array of values for each attribute.
47
+ #
48
+ # Class Net::LDAP::Entry provides convenience methods for dealing with LDAP
49
+ # entries. In addition to the methods documented below, you may access
50
+ # individual attributes of an entry simply by giving the attribute name as
51
+ # the name of a method call. For example:
52
+ #
53
+ # ldap.search( ... ) do |entry|
54
+ # puts "Common name: #{entry.cn}"
55
+ # puts "Email addresses:"
56
+ # entry.mail.each {|ma| puts ma}
57
+ # end
58
+ #
59
+ # If you use this technique to access an attribute that is not present in a
60
+ # particular Entry object, a NoMethodError exception will be raised.
61
+ #
62
+ #--
63
+ # Ugly problem to fix someday: We key off the internal hash with a canonical
64
+ # form of the attribute name: convert to a string, downcase, then take the
65
+ # symbol. Unfortunately we do this in at least three places. Should do it in
66
+ # ONE place.
67
+ class Net::LDAP::Entry
68
+ ##
69
+ # This constructor is not generally called by user code.
70
+ def initialize(dn = nil) #:nodoc:
71
+ @myhash = {}
72
+ @myhash[:dn] = [dn]
73
+ end
74
+
75
+ ##
76
+ # Use the LDIF format for Marshal serialization.
77
+ def _dump(depth) #:nodoc:
78
+ to_ldif
79
+ end
80
+
81
+ ##
82
+ # Use the LDIF format for Marshal serialization.
83
+ def self._load(entry) #:nodoc:
84
+ from_single_ldif_string(entry)
85
+ end
86
+
87
+ class << self
88
+ ##
89
+ # Converts a single LDIF entry string into an Entry object. Useful for
90
+ # Marshal serialization. If a string with multiple LDIF entries is
91
+ # provided, an exception will be raised.
92
+ def from_single_ldif_string(ldif)
93
+ ds = Net::LDAP::Dataset.read_ldif(::StringIO.new(ldif))
94
+
95
+ return nil if ds.empty?
96
+
97
+ raise Net::LDAP::LdapError, "Too many LDIF entries" unless ds.size == 1
98
+
99
+ entry = ds.to_entries.first
100
+
101
+ return nil if entry.dn.nil?
102
+ entry
103
+ end
104
+
105
+ ##
106
+ # Canonicalizes an LDAP attribute name as a \Symbol. The name is
107
+ # lowercased and, if present, a trailing equals sign is removed.
108
+ def attribute_name(name)
109
+ name = name.to_s.downcase
110
+ name = name[0..-2] if name[-1] == ?=
111
+ name.to_sym
112
+ end
113
+ end
114
+
115
+ ##
116
+ # Sets or replaces the array of values for the provided attribute. The
117
+ # attribute name is canonicalized prior to assignment.
118
+ #
119
+ # When an attribute is set using this, that attribute is now made
120
+ # accessible through methods as well.
121
+ #
122
+ # entry = Net::LDAP::Entry.new("dc=com")
123
+ # entry.foo # => NoMethodError
124
+ # entry["foo"] = 12345 # => [12345]
125
+ # entry.foo # => [12345]
126
+ def []=(name, value)
127
+ @myhash[self.class.attribute_name(name)] = Kernel::Array(value)
128
+ end
129
+
130
+ ##
131
+ # Reads the array of values for the provided attribute. The attribute name
132
+ # is canonicalized prior to reading. Returns an empty array if the
133
+ # attribute does not exist.
134
+ def [](name)
135
+ name = self.class.attribute_name(name)
136
+ @myhash[name] || []
137
+ end
138
+
139
+ ##
140
+ # Returns the first distinguished name (dn) of the Entry as a \String.
141
+ def dn
142
+ self[:dn].first.to_s
143
+ end
144
+
145
+ ##
146
+ # Returns an array of the attribute names present in the Entry.
147
+ def attribute_names
148
+ @myhash.keys
149
+ end
150
+
151
+ ##
152
+ # Accesses each of the attributes present in the Entry.
153
+ #
154
+ # Calls a user-supplied block with each attribute in turn, passing two
155
+ # arguments to the block: a Symbol giving the name of the attribute, and a
156
+ # (possibly empty) \Array of data values.
157
+ def each # :yields: attribute-name, data-values-array
158
+ if block_given?
159
+ attribute_names.each {|a|
160
+ attr_name,values = a,self[a]
161
+ yield attr_name, values
162
+ }
163
+ end
164
+ end
165
+ alias_method :each_attribute, :each
166
+
167
+ ##
168
+ # Converts the Entry to an LDIF-formatted String
169
+ def to_ldif
170
+ Net::LDAP::Dataset.from_entry(self).to_ldif_string
171
+ end
172
+
173
+ def respond_to?(sym) #:nodoc:
174
+ return true if valid_attribute?(self.class.attribute_name(sym))
175
+ return super
176
+ end
177
+
178
+ def method_missing(sym, *args, &block) #:nodoc:
179
+ name = self.class.attribute_name(sym)
180
+
181
+ if valid_attribute?(name )
182
+ if setter?(sym) && args.size == 1
183
+ value = args.first
184
+ value = Array(value)
185
+ self[name]= value
186
+ return value
187
+ elsif args.empty?
188
+ return self[name]
189
+ end
190
+ end
191
+
192
+ super
193
+ end
194
+
195
+ # Given a valid attribute symbol, returns true.
196
+ def valid_attribute?(attr_name)
197
+ attribute_names.include?(attr_name)
198
+ end
199
+ private :valid_attribute?
200
+
201
+ # Returns true if the symbol ends with an equal sign.
202
+ def setter?(sym)
203
+ sym.to_s[-1] == ?=
204
+ end
205
+ private :setter?
206
+ end # class Entry
207
+
208
+ require 'net/ldap/dataset' unless defined? Net::LDAP::Dataset