powerhome-activeldap 3.2.3
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.
- checksums.yaml +7 -0
- data/.yardopts +6 -0
- data/COPYING +340 -0
- data/Gemfile +12 -0
- data/LICENSE +59 -0
- data/README.textile +140 -0
- data/TODO +32 -0
- data/benchmark/README.md +64 -0
- data/benchmark/bench-backend.rb +247 -0
- data/benchmark/bench-instantiate.rb +98 -0
- data/benchmark/config.yaml.sample +5 -0
- data/doc/text/development.textile +54 -0
- data/doc/text/news.textile +811 -0
- data/doc/text/rails.textile +144 -0
- data/doc/text/tutorial.textile +1010 -0
- data/examples/config.yaml.example +5 -0
- data/examples/example.der +0 -0
- data/examples/example.jpg +0 -0
- data/examples/groupadd +41 -0
- data/examples/groupdel +35 -0
- data/examples/groupls +49 -0
- data/examples/groupmod +42 -0
- data/examples/lpasswd +55 -0
- data/examples/objects/group.rb +13 -0
- data/examples/objects/ou.rb +4 -0
- data/examples/objects/user.rb +20 -0
- data/examples/ouadd +38 -0
- data/examples/useradd +45 -0
- data/examples/useradd-binary +53 -0
- data/examples/userdel +34 -0
- data/examples/userls +50 -0
- data/examples/usermod +42 -0
- data/examples/usermod-binary-add +50 -0
- data/examples/usermod-binary-add-time +54 -0
- data/examples/usermod-binary-del +48 -0
- data/examples/usermod-lang-add +43 -0
- data/lib/active_ldap.rb +85 -0
- data/lib/active_ldap/action_controller/ldap_benchmarking.rb +55 -0
- data/lib/active_ldap/acts/tree.rb +78 -0
- data/lib/active_ldap/adapter/base.rb +707 -0
- data/lib/active_ldap/adapter/jndi.rb +184 -0
- data/lib/active_ldap/adapter/jndi_connection.rb +185 -0
- data/lib/active_ldap/adapter/ldap.rb +290 -0
- data/lib/active_ldap/adapter/ldap_ext.rb +105 -0
- data/lib/active_ldap/adapter/net_ldap.rb +309 -0
- data/lib/active_ldap/adapter/net_ldap_ext.rb +23 -0
- data/lib/active_ldap/association/belongs_to.rb +47 -0
- data/lib/active_ldap/association/belongs_to_many.rb +58 -0
- data/lib/active_ldap/association/children.rb +21 -0
- data/lib/active_ldap/association/collection.rb +105 -0
- data/lib/active_ldap/association/has_many.rb +31 -0
- data/lib/active_ldap/association/has_many_utils.rb +44 -0
- data/lib/active_ldap/association/has_many_wrap.rb +75 -0
- data/lib/active_ldap/association/proxy.rb +107 -0
- data/lib/active_ldap/associations.rb +205 -0
- data/lib/active_ldap/attribute_methods.rb +23 -0
- data/lib/active_ldap/attribute_methods/before_type_cast.rb +24 -0
- data/lib/active_ldap/attribute_methods/dirty.rb +43 -0
- data/lib/active_ldap/attribute_methods/query.rb +31 -0
- data/lib/active_ldap/attribute_methods/read.rb +44 -0
- data/lib/active_ldap/attribute_methods/write.rb +38 -0
- data/lib/active_ldap/attributes.rb +176 -0
- data/lib/active_ldap/base.rb +1410 -0
- data/lib/active_ldap/callbacks.rb +71 -0
- data/lib/active_ldap/command.rb +49 -0
- data/lib/active_ldap/compatible.rb +44 -0
- data/lib/active_ldap/configuration.rb +147 -0
- data/lib/active_ldap/connection.rb +299 -0
- data/lib/active_ldap/distinguished_name.rb +291 -0
- data/lib/active_ldap/entry_attribute.rb +78 -0
- data/lib/active_ldap/escape.rb +12 -0
- data/lib/active_ldap/get_text.rb +20 -0
- data/lib/active_ldap/get_text/parser.rb +161 -0
- data/lib/active_ldap/helper.rb +92 -0
- data/lib/active_ldap/human_readable.rb +133 -0
- data/lib/active_ldap/ldap_error.rb +74 -0
- data/lib/active_ldap/ldif.rb +930 -0
- data/lib/active_ldap/log_subscriber.rb +50 -0
- data/lib/active_ldap/object_class.rb +95 -0
- data/lib/active_ldap/operations.rb +624 -0
- data/lib/active_ldap/persistence.rb +100 -0
- data/lib/active_ldap/populate.rb +53 -0
- data/lib/active_ldap/railtie.rb +43 -0
- data/lib/active_ldap/railties/controller_runtime.rb +48 -0
- data/lib/active_ldap/schema.rb +701 -0
- data/lib/active_ldap/schema/syntaxes.rb +422 -0
- data/lib/active_ldap/timeout.rb +75 -0
- data/lib/active_ldap/timeout_stub.rb +17 -0
- data/lib/active_ldap/user_password.rb +99 -0
- data/lib/active_ldap/validations.rb +200 -0
- data/lib/active_ldap/version.rb +3 -0
- data/lib/active_ldap/xml.rb +139 -0
- data/lib/rails/generators/active_ldap/model/USAGE +18 -0
- data/lib/rails/generators/active_ldap/model/model_generator.rb +47 -0
- data/lib/rails/generators/active_ldap/model/templates/model_active_ldap.rb +3 -0
- data/lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb +14 -0
- data/lib/rails/generators/active_ldap/scaffold/templates/ldap.yml +19 -0
- data/po/en/active-ldap.po +4029 -0
- data/po/ja/active-ldap.po +4060 -0
- data/test/add-phonetic-attribute-options-to-slapd.ldif +10 -0
- data/test/al-test-utils.rb +428 -0
- data/test/command.rb +111 -0
- data/test/config.yaml.sample +6 -0
- data/test/fixtures/lower_case_object_class_schema.rb +802 -0
- data/test/run-test.rb +34 -0
- data/test/test_acts_as_tree.rb +60 -0
- data/test/test_adapter.rb +121 -0
- data/test/test_associations.rb +701 -0
- data/test/test_attributes.rb +117 -0
- data/test/test_base.rb +1214 -0
- data/test/test_base_per_instance.rb +61 -0
- data/test/test_bind.rb +62 -0
- data/test/test_callback.rb +31 -0
- data/test/test_configuration.rb +40 -0
- data/test/test_connection.rb +82 -0
- data/test/test_connection_per_class.rb +112 -0
- data/test/test_connection_per_dn.rb +112 -0
- data/test/test_dirty.rb +98 -0
- data/test/test_dn.rb +172 -0
- data/test/test_find.rb +176 -0
- data/test/test_groupadd.rb +50 -0
- data/test/test_groupdel.rb +46 -0
- data/test/test_groupls.rb +107 -0
- data/test/test_groupmod.rb +51 -0
- data/test/test_ldif.rb +1890 -0
- data/test/test_load.rb +133 -0
- data/test/test_lpasswd.rb +75 -0
- data/test/test_object_class.rb +74 -0
- data/test/test_persistence.rb +131 -0
- data/test/test_reflection.rb +175 -0
- data/test/test_schema.rb +559 -0
- data/test/test_syntax.rb +444 -0
- data/test/test_user.rb +217 -0
- data/test/test_user_password.rb +108 -0
- data/test/test_useradd-binary.rb +62 -0
- data/test/test_useradd.rb +57 -0
- data/test/test_userdel.rb +48 -0
- data/test/test_userls.rb +91 -0
- data/test/test_usermod-binary-add-time.rb +65 -0
- data/test/test_usermod-binary-add.rb +64 -0
- data/test/test_usermod-binary-del.rb +66 -0
- data/test/test_usermod-lang-add.rb +59 -0
- data/test/test_usermod.rb +58 -0
- data/test/test_validation.rb +274 -0
- metadata +379 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
require 'strscan'
|
|
2
|
+
|
|
3
|
+
module ActiveLdap
|
|
4
|
+
class DistinguishedName
|
|
5
|
+
include GetTextSupport
|
|
6
|
+
|
|
7
|
+
class Parser
|
|
8
|
+
include GetTextSupport
|
|
9
|
+
|
|
10
|
+
attr_reader :dn
|
|
11
|
+
def initialize(source)
|
|
12
|
+
@dn = nil
|
|
13
|
+
source = source.to_s if source.is_a?(DN)
|
|
14
|
+
unless source.is_a?(String)
|
|
15
|
+
raise DistinguishedNameInputInvalid.new(source)
|
|
16
|
+
end
|
|
17
|
+
@source = source
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def parse
|
|
21
|
+
return @dn if @dn
|
|
22
|
+
|
|
23
|
+
rdns = []
|
|
24
|
+
scanner = StringScanner.new(@source)
|
|
25
|
+
|
|
26
|
+
scanner.scan(/\s*/)
|
|
27
|
+
raise rdn_is_missing if scanner.scan(/\s*\+\s*/)
|
|
28
|
+
raise name_component_is_missing if scanner.scan(/\s*,\s*/)
|
|
29
|
+
|
|
30
|
+
rdn = {}
|
|
31
|
+
until scanner.eos?
|
|
32
|
+
type = scan_attribute_type(scanner)
|
|
33
|
+
skip_attribute_type_and_value_separator(scanner)
|
|
34
|
+
value = scan_attribute_value(scanner)
|
|
35
|
+
rdn[type] = value
|
|
36
|
+
if scanner.scan(/\s*\+\s*/)
|
|
37
|
+
raise rdn_is_missing if scanner.eos?
|
|
38
|
+
elsif scanner.scan(/\s*\,\s*/)
|
|
39
|
+
rdns << rdn
|
|
40
|
+
rdn = {}
|
|
41
|
+
raise name_component_is_missing if scanner.eos?
|
|
42
|
+
else
|
|
43
|
+
scanner.scan(/\s*/)
|
|
44
|
+
rdns << rdn if scanner.eos?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@dn = DN.new(*rdns)
|
|
49
|
+
@dn
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
ATTRIBUTE_TYPE_RE = /\s*([a-zA-Z][a-zA-Z\d\-]*|\d+(?:\.\d+)*)\s*/
|
|
54
|
+
def scan_attribute_type(scanner)
|
|
55
|
+
raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE)
|
|
56
|
+
scanner[1]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def skip_attribute_type_and_value_separator(scanner)
|
|
60
|
+
raise attribute_value_is_missing unless scanner.scan(/\s*=\s*/)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
HEX_PAIR = "(?:[\\da-fA-F]{2})"
|
|
64
|
+
STRING_CHARS_RE = /[^,=\+<>\#;\\\"]*/ #
|
|
65
|
+
PAIR_RE = /\\([,=\+<>\#;]|\\|\"|(#{HEX_PAIR}))/ #
|
|
66
|
+
HEX_STRING_RE = /\#(#{HEX_PAIR}+)/ #
|
|
67
|
+
def scan_attribute_value(scanner)
|
|
68
|
+
if scanner.scan(HEX_STRING_RE)
|
|
69
|
+
value = scanner[1].scan(/../).collect do |hex_pair|
|
|
70
|
+
hex_pair.hex
|
|
71
|
+
end.pack("C*")
|
|
72
|
+
elsif scanner.scan(/\"/)
|
|
73
|
+
value = scan_quoted_attribute_value(scanner)
|
|
74
|
+
else
|
|
75
|
+
value = scan_not_quoted_attribute_value(scanner)
|
|
76
|
+
end
|
|
77
|
+
raise attribute_value_is_missing if value.blank?
|
|
78
|
+
|
|
79
|
+
value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def scan_quoted_attribute_value(scanner)
|
|
83
|
+
result = ""
|
|
84
|
+
until scanner.scan(/\"/)
|
|
85
|
+
scanner.scan(/([^\\\"]*)/)
|
|
86
|
+
quoted_strings = scanner[1]
|
|
87
|
+
pairs = collect_pairs(scanner)
|
|
88
|
+
|
|
89
|
+
if scanner.eos? or (quoted_strings.empty? and pairs.empty?)
|
|
90
|
+
raise found_unmatched_quotation
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
result << quoted_strings
|
|
94
|
+
result << pairs
|
|
95
|
+
end
|
|
96
|
+
result
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def scan_not_quoted_attribute_value(scanner)
|
|
100
|
+
result = ""
|
|
101
|
+
until scanner.eos?
|
|
102
|
+
prev_size = result.size
|
|
103
|
+
pairs = collect_pairs(scanner)
|
|
104
|
+
strings = scanner.scan(STRING_CHARS_RE)
|
|
105
|
+
result << pairs if !pairs.nil? and !pairs.empty?
|
|
106
|
+
unless strings.nil?
|
|
107
|
+
if scanner.peek(1) == ","
|
|
108
|
+
result << strings.rstrip
|
|
109
|
+
else
|
|
110
|
+
result << strings
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
break if prev_size == result.size
|
|
114
|
+
end
|
|
115
|
+
result
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def collect_pairs(scanner)
|
|
119
|
+
result = ""
|
|
120
|
+
while scanner.scan(PAIR_RE)
|
|
121
|
+
if scanner[2]
|
|
122
|
+
result << [scanner[2].hex].pack("C*")
|
|
123
|
+
else
|
|
124
|
+
result << scanner[1]
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
|
|
128
|
+
result
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def invalid_dn(reason)
|
|
132
|
+
DistinguishedNameInvalid.new(@source, reason)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def name_component_is_missing
|
|
136
|
+
invalid_dn(_("name component is missing"))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def rdn_is_missing
|
|
140
|
+
invalid_dn(_("relative distinguished name (RDN) is missing"))
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def attribute_type_is_missing
|
|
144
|
+
invalid_dn(_("attribute type is missing"))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def attribute_value_is_missing
|
|
148
|
+
invalid_dn(_("attribute value is missing"))
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def found_unmatched_quotation
|
|
152
|
+
invalid_dn(_("found unmatched quotation"))
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class << self
|
|
157
|
+
def parse(source)
|
|
158
|
+
Parser.new(source).parse
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def escape_value(value)
|
|
162
|
+
if /(\A | \z)/.match(value)
|
|
163
|
+
'"' + value.gsub(/([\\\"])/, '\\\\\1') + '"'
|
|
164
|
+
else
|
|
165
|
+
value.gsub(/([,=\+<>#;\\\"])/, '\\\\\1')
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
attr_reader :rdns
|
|
171
|
+
def initialize(*rdns)
|
|
172
|
+
@rdns = rdns.collect do |rdn|
|
|
173
|
+
if rdn.is_a?(Array) and rdn.size == 2
|
|
174
|
+
{rdn[0] => rdn[1]}
|
|
175
|
+
else
|
|
176
|
+
rdn
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def blank?
|
|
182
|
+
@rdns.blank?
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def +(other)
|
|
186
|
+
self.class.new(*(@rdns + other.rdns))
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def -(other)
|
|
190
|
+
rdns = @rdns.dup
|
|
191
|
+
normalized_rdns = normalize(@rdns)
|
|
192
|
+
normalize(other.rdns).reverse_each do |rdn|
|
|
193
|
+
if rdn == normalized_rdns.pop
|
|
194
|
+
rdns.pop
|
|
195
|
+
else
|
|
196
|
+
raise ArgumentError, _("%s isn't sub DN of %s") % [other, self]
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
self.class.new(*rdns)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def <<(rdn)
|
|
203
|
+
@rdns << rdn
|
|
204
|
+
self
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def unshift(rdn)
|
|
208
|
+
@rdns.unshift(rdn)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def parent
|
|
212
|
+
return nil if @rdns.size <= 1
|
|
213
|
+
self.class.new(*@rdns[1..-1])
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def <=>(other)
|
|
217
|
+
other = DN.parse(other) if other.is_a?(String)
|
|
218
|
+
return nil unless other.is_a?(self.class)
|
|
219
|
+
normalize_for_comparing(@rdns) <=>
|
|
220
|
+
normalize_for_comparing(other.rdns)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def ==(other)
|
|
224
|
+
case other
|
|
225
|
+
when self.class
|
|
226
|
+
normalize(@rdns) == normalize(other.rdns)
|
|
227
|
+
when String
|
|
228
|
+
parsed_other = nil
|
|
229
|
+
begin
|
|
230
|
+
parsed_other = self.class.parse(other)
|
|
231
|
+
rescue DistinguishedNameInvalid
|
|
232
|
+
return false
|
|
233
|
+
end
|
|
234
|
+
self == parsed_other
|
|
235
|
+
else
|
|
236
|
+
false
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def eql?(other)
|
|
241
|
+
other.is_a?(self.class) and
|
|
242
|
+
normalize(@rdns).to_s.eql?(normalize(other.rdns).to_s)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def hash
|
|
246
|
+
normalize(@rdns).to_s.hash
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def to_s
|
|
250
|
+
klass = self.class
|
|
251
|
+
@rdns.collect do |rdn|
|
|
252
|
+
rdn.sort_by do |type, value|
|
|
253
|
+
type.upcase
|
|
254
|
+
end.collect do |type, value|
|
|
255
|
+
"#{type}=#{klass.escape_value(value)}"
|
|
256
|
+
end.join("+")
|
|
257
|
+
end.join(",")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def to_str # for backward compatibility
|
|
261
|
+
to_s
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def to_human_readable_format
|
|
265
|
+
to_s.inspect
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
private
|
|
269
|
+
def normalize(rdns)
|
|
270
|
+
rdns.collect do |rdn|
|
|
271
|
+
normalized_rdn = {}
|
|
272
|
+
rdn.each do |key, value|
|
|
273
|
+
normalized_rdn[key.upcase] = value.upcase
|
|
274
|
+
end
|
|
275
|
+
normalized_rdn
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def normalize_for_comparing(rdns)
|
|
280
|
+
normalize(rdns).collect do |rdn|
|
|
281
|
+
rdn.sort_by do |key, value|
|
|
282
|
+
key
|
|
283
|
+
end
|
|
284
|
+
end.collect do |key, value|
|
|
285
|
+
[key, value]
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
DN = DistinguishedName
|
|
291
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require "active_ldap/attributes"
|
|
2
|
+
|
|
3
|
+
module ActiveLdap
|
|
4
|
+
class EntryAttribute
|
|
5
|
+
include Attributes::Normalizable
|
|
6
|
+
|
|
7
|
+
attr_reader :must, :may, :object_classes, :schemata
|
|
8
|
+
def initialize(schema, object_classes)
|
|
9
|
+
@schemata = {}
|
|
10
|
+
@names = {}
|
|
11
|
+
@normalized_names = {}
|
|
12
|
+
@aliases = {}
|
|
13
|
+
@must = []
|
|
14
|
+
@may = []
|
|
15
|
+
@object_classes = []
|
|
16
|
+
register(schema.attribute('objectClass'))
|
|
17
|
+
object_classes.each do |objc|
|
|
18
|
+
# get all attributes for the class
|
|
19
|
+
object_class = schema.object_class(objc)
|
|
20
|
+
@object_classes << object_class
|
|
21
|
+
@must.concat(object_class.must)
|
|
22
|
+
@may.concat(object_class.may)
|
|
23
|
+
end
|
|
24
|
+
@must.uniq!
|
|
25
|
+
@may.uniq!
|
|
26
|
+
(@must + @may).each do |attr|
|
|
27
|
+
# Update attr_method with appropriate
|
|
28
|
+
register(attr)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def names(normalize=false)
|
|
33
|
+
names = @names.keys
|
|
34
|
+
if normalize
|
|
35
|
+
names.collect do |name|
|
|
36
|
+
normalize(name)
|
|
37
|
+
end.uniq
|
|
38
|
+
else
|
|
39
|
+
names
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def normalize(name, allow_normalized_name=false)
|
|
44
|
+
return name if name.nil?
|
|
45
|
+
return nil if @names.empty? and @aliases.empty?
|
|
46
|
+
name = name.to_s
|
|
47
|
+
real_name = @names[name]
|
|
48
|
+
real_name ||= @aliases[name.underscore]
|
|
49
|
+
if real_name
|
|
50
|
+
real_name
|
|
51
|
+
elsif allow_normalized_name
|
|
52
|
+
return nil if @normalized_names.empty?
|
|
53
|
+
@normalized_names[normalize_attribute_name(name)]
|
|
54
|
+
else
|
|
55
|
+
nil
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def all_names
|
|
60
|
+
@names.keys + @aliases.keys
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# register
|
|
64
|
+
#
|
|
65
|
+
# Make a method entry for _every_ alias of a valid attribute and map it
|
|
66
|
+
# onto the first attribute passed in.
|
|
67
|
+
def register(attribute)
|
|
68
|
+
real_name = attribute.name
|
|
69
|
+
return if @schemata.has_key?(real_name)
|
|
70
|
+
@schemata[real_name] = attribute
|
|
71
|
+
([real_name] + attribute.aliases).each do |name|
|
|
72
|
+
@names[name] = real_name
|
|
73
|
+
@aliases[name.underscore] = real_name
|
|
74
|
+
@normalized_names[normalize_attribute_name(name)] = real_name
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "gettext"
|
|
2
|
+
|
|
3
|
+
module ActiveLdap
|
|
4
|
+
class << self
|
|
5
|
+
def get_text_supported?
|
|
6
|
+
true
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module GetTextSupport
|
|
11
|
+
class << self
|
|
12
|
+
def included(base)
|
|
13
|
+
base.class_eval do
|
|
14
|
+
include(GetText)
|
|
15
|
+
bindtextdomain("active-ldap")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require 'active_ldap'
|
|
2
|
+
require 'gettext/parser/ruby'
|
|
3
|
+
|
|
4
|
+
module ActiveLdap
|
|
5
|
+
module GetText
|
|
6
|
+
class Parser
|
|
7
|
+
include GetText
|
|
8
|
+
|
|
9
|
+
def initialize(configuration=nil)
|
|
10
|
+
configuration = ensure_configuration(configuration)
|
|
11
|
+
configuration = default_configuration.merge(configuration)
|
|
12
|
+
|
|
13
|
+
configuration = extract_options(configuration)
|
|
14
|
+
ActiveLdap::Base.setup_connection(configuration)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def parse(file, targets=[])
|
|
18
|
+
targets = RubyParser.parse(file, targets) if RubyParser.target?(file)
|
|
19
|
+
extract(targets) do
|
|
20
|
+
load_constants(file).each do |name|
|
|
21
|
+
klass = name.constantize
|
|
22
|
+
next unless klass.is_a?(Class)
|
|
23
|
+
next unless klass < ActiveLdap::Base
|
|
24
|
+
register(klass.name.singularize.underscore.gsub(/_/, " "), file)
|
|
25
|
+
next unless @extract_schema
|
|
26
|
+
klass.classes.each do |object_class|
|
|
27
|
+
register_object_class(object_class, file)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def target?(file)
|
|
34
|
+
@classes_re.match(File.read(file))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def extract_all_in_schema(targets=[])
|
|
38
|
+
extract(targets) do
|
|
39
|
+
schema = ActiveLdap::Base.schema
|
|
40
|
+
schema.object_classes.each do |object_class|
|
|
41
|
+
register_object_class(object_class, "-")
|
|
42
|
+
end
|
|
43
|
+
schema.attributes.each do |attribute|
|
|
44
|
+
register_attribute(attribute, "-")
|
|
45
|
+
end
|
|
46
|
+
schema.ldap_syntaxes.each do |syntax|
|
|
47
|
+
register_syntax(syntax, "-")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
def extract_options(configuration)
|
|
54
|
+
configuration = configuration.dup
|
|
55
|
+
classes = configuration.delete(:classes) || ["ActiveLdap::Base"]
|
|
56
|
+
@classes_re = /class.*#{Regexp.union(*classes)}/ #
|
|
57
|
+
@extract_schema = configuration.delete(:extract_schema)
|
|
58
|
+
configuration
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def default_configuration
|
|
62
|
+
{
|
|
63
|
+
:host => "127.0.0.1",
|
|
64
|
+
:allow_anonymous => true,
|
|
65
|
+
:extract_schema => false,
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def ensure_configuration(configuration)
|
|
70
|
+
configuration ||= ENV["RAILS_ENV"] || {}
|
|
71
|
+
if configuration.is_a?(String)
|
|
72
|
+
if File.exists?(configuration)
|
|
73
|
+
require 'erb'
|
|
74
|
+
require 'yaml'
|
|
75
|
+
erb = ERB.new(File.read(configuration))
|
|
76
|
+
erb.filename = configuration
|
|
77
|
+
configuration = YAML.load(erb.result)
|
|
78
|
+
else
|
|
79
|
+
ENV["RAILS_ENV"] = configuration
|
|
80
|
+
require 'config/environment'
|
|
81
|
+
configuration = ActiveLdap::Base.configurations[configuration]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
if defined?(Rails)
|
|
85
|
+
rails_configuration = ActiveLdap::Base.configurations[Rails.env]
|
|
86
|
+
configuration = rails_configuration.merge(configuration)
|
|
87
|
+
end
|
|
88
|
+
configuration = configuration.symbolize_keys
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def load_constants(file)
|
|
92
|
+
old_constants = Object.constants
|
|
93
|
+
begin
|
|
94
|
+
eval(File.read(file), TOPLEVEL_BINDING, file)
|
|
95
|
+
rescue
|
|
96
|
+
format = _("Ignored '%{file}'. Solve dependencies first.")
|
|
97
|
+
$stderr.puts(format % {:file => file})
|
|
98
|
+
$stderr.puts($!)
|
|
99
|
+
end
|
|
100
|
+
Object.constants - old_constants
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def extract(targets)
|
|
104
|
+
@targets = {}
|
|
105
|
+
targets.each do |id, *file_infos|
|
|
106
|
+
@targets[id] = file_infos
|
|
107
|
+
end
|
|
108
|
+
yield
|
|
109
|
+
@targets.collect do |id, file_infos|
|
|
110
|
+
[id, *file_infos.uniq]
|
|
111
|
+
end.sort_by do |id,|
|
|
112
|
+
id
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def register(id, file)
|
|
117
|
+
file_info = "#{file}:-"
|
|
118
|
+
@targets[id] ||= []
|
|
119
|
+
@targets[id] << file_info
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def register_object_class(object_class, file)
|
|
123
|
+
[object_class.name, *object_class.aliases].each do |name|
|
|
124
|
+
register(ActiveLdap::Base.human_object_class_name_msgid(name), file)
|
|
125
|
+
end
|
|
126
|
+
if object_class.description
|
|
127
|
+
msgid =
|
|
128
|
+
ActiveLdap::Base.human_object_class_description_msgid(object_class)
|
|
129
|
+
register(msgid, file)
|
|
130
|
+
end
|
|
131
|
+
(object_class.must(false) + object_class.may(false)).each do |attribute|
|
|
132
|
+
register_attribute(attribute, file)
|
|
133
|
+
end
|
|
134
|
+
object_class.super_classes.each do |super_class|
|
|
135
|
+
register_object_class(super_class, file)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def register_attribute(attribute, file)
|
|
140
|
+
[attribute.name, *attribute.aliases].each do |name|
|
|
141
|
+
msgid = ActiveLdap::Base.human_attribute_name_msgid(name)
|
|
142
|
+
register(msgid, file) if msgid
|
|
143
|
+
end
|
|
144
|
+
if attribute.description
|
|
145
|
+
msgid = ActiveLdap::Base.human_attribute_description_msgid(attribute)
|
|
146
|
+
register(msgid, file)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def register_syntax(syntax, file)
|
|
151
|
+
msgid = ActiveLdap::Base.human_syntax_name_msgid(syntax)
|
|
152
|
+
register(msgid, file)
|
|
153
|
+
|
|
154
|
+
if syntax.description
|
|
155
|
+
msgid = ActiveLdap::Base.human_syntax_description_msgid(syntax)
|
|
156
|
+
register(msgid, file)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|