ruby-activeldap 0.8.2 → 0.8.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.
Files changed (83) hide show
  1. data/test/test_adapter.rb +17 -0
  2. data/test/test_associations.rb +19 -0
  3. data/test/test_attributes.rb +2 -1
  4. data/test/test_base.rb +28 -1
  5. data/test/test_base_per_instance.rb +2 -1
  6. data/test/test_callback.rb +2 -2
  7. data/test/test_connection.rb +2 -1
  8. data/test/test_connection_per_dn.rb +81 -0
  9. data/test/test_dn.rb +3 -2
  10. data/test/test_find.rb +35 -1
  11. data/test/test_object_class.rb +12 -1
  12. data/test/test_reflection.rb +16 -10
  13. data/test/test_schema.rb +141 -2
  14. data/test/test_user.rb +14 -4
  15. metadata +7 -104
  16. data/CHANGES +0 -397
  17. data/COPYING +0 -340
  18. data/LICENSE +0 -58
  19. data/Manifest.txt +0 -99
  20. data/README +0 -85
  21. data/Rakefile +0 -70
  22. data/TODO +0 -23
  23. data/benchmark/bench-al.rb +0 -152
  24. data/examples/config.yaml.example +0 -5
  25. data/examples/example.der +0 -0
  26. data/examples/example.jpg +0 -0
  27. data/examples/groupadd +0 -41
  28. data/examples/groupdel +0 -35
  29. data/examples/groupls +0 -49
  30. data/examples/groupmod +0 -42
  31. data/examples/lpasswd +0 -55
  32. data/examples/objects/group.rb +0 -13
  33. data/examples/objects/ou.rb +0 -4
  34. data/examples/objects/user.rb +0 -20
  35. data/examples/ouadd +0 -38
  36. data/examples/useradd +0 -45
  37. data/examples/useradd-binary +0 -50
  38. data/examples/userdel +0 -34
  39. data/examples/userls +0 -50
  40. data/examples/usermod +0 -42
  41. data/examples/usermod-binary-add +0 -47
  42. data/examples/usermod-binary-add-time +0 -51
  43. data/examples/usermod-binary-del +0 -48
  44. data/examples/usermod-lang-add +0 -43
  45. data/lib/active_ldap.rb +0 -964
  46. data/lib/active_ldap/adapter/base.rb +0 -461
  47. data/lib/active_ldap/adapter/ldap.rb +0 -232
  48. data/lib/active_ldap/adapter/ldap_ext.rb +0 -69
  49. data/lib/active_ldap/adapter/net_ldap.rb +0 -288
  50. data/lib/active_ldap/adapter/net_ldap_ext.rb +0 -29
  51. data/lib/active_ldap/association/belongs_to.rb +0 -40
  52. data/lib/active_ldap/association/belongs_to_many.rb +0 -39
  53. data/lib/active_ldap/association/collection.rb +0 -80
  54. data/lib/active_ldap/association/has_many.rb +0 -40
  55. data/lib/active_ldap/association/has_many_wrap.rb +0 -55
  56. data/lib/active_ldap/association/proxy.rb +0 -89
  57. data/lib/active_ldap/associations.rb +0 -162
  58. data/lib/active_ldap/attributes.rb +0 -203
  59. data/lib/active_ldap/base.rb +0 -1510
  60. data/lib/active_ldap/callbacks.rb +0 -19
  61. data/lib/active_ldap/command.rb +0 -46
  62. data/lib/active_ldap/configuration.rb +0 -106
  63. data/lib/active_ldap/connection.rb +0 -142
  64. data/lib/active_ldap/distinguished_name.rb +0 -246
  65. data/lib/active_ldap/ldap_error.rb +0 -74
  66. data/lib/active_ldap/object_class.rb +0 -74
  67. data/lib/active_ldap/schema.rb +0 -299
  68. data/lib/active_ldap/timeout.rb +0 -75
  69. data/lib/active_ldap/timeout_stub.rb +0 -17
  70. data/lib/active_ldap/user_password.rb +0 -92
  71. data/lib/active_ldap/validations.rb +0 -76
  72. data/rails/plugin/active_ldap/README +0 -54
  73. data/rails/plugin/active_ldap/generators/scaffold_al/scaffold_al_generator.rb +0 -7
  74. data/rails/plugin/active_ldap/generators/scaffold_al/templates/ldap.yml +0 -21
  75. data/rails/plugin/active_ldap/init.rb +0 -12
  76. data/test/TODO +0 -2
  77. data/test/al-test-utils.rb +0 -381
  78. data/test/command.rb +0 -62
  79. data/test/config.yaml.sample +0 -6
  80. data/test/run-test.rb +0 -29
  81. data/test/test-unit-ext.rb +0 -2
  82. data/test/test-unit-ext/always-show-result.rb +0 -28
  83. data/test/test-unit-ext/priority.rb +0 -163
@@ -1,19 +0,0 @@
1
- require 'active_record/callbacks'
2
-
3
- module ActiveLdap
4
- module Callbacks
5
- def self.append_features(base)
6
- super
7
-
8
- base.class_eval do
9
- include ActiveRecord::Callbacks
10
-
11
- def callback(method)
12
- super
13
- rescue ActiveRecord::ActiveRecordError
14
- raise Error, $!.message
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,46 +0,0 @@
1
- require 'optparse'
2
- require 'ostruct'
3
-
4
- module ActiveLdap
5
- module Command
6
- module_function
7
- def parse_options(argv=nil, version=nil)
8
- argv ||= ARGV.dup
9
- options = OpenStruct.new
10
- opts = OptionParser.new do |opts|
11
- yield(opts, options)
12
-
13
- opts.separator ""
14
- opts.separator "Common options:"
15
-
16
- opts.on_tail("--config=CONFIG",
17
- "Specify configuration file written as YAML") do |file|
18
- require 'yaml'
19
- config = YAML.load(File.read(file)).symbolize_keys
20
- Configuration::DEFAULT_CONFIG.update(config)
21
- end
22
-
23
- opts.on_tail("-h", "--help", "Show this message") do
24
- puts opts
25
- exit
26
- end
27
-
28
- opts.on_tail("--version", "Show version") do
29
- puts(version || VERSION)
30
- exit
31
- end
32
- end
33
- opts.parse!(argv)
34
- [argv, opts, options]
35
- end
36
-
37
- def read_password(prompt, input=$stdin, output=$stdout)
38
- output.print prompt
39
- system "/bin/stty -echo" if input.tty?
40
- input.gets.chomp
41
- ensure
42
- system "/bin/stty echo" if input.tty?
43
- output.puts
44
- end
45
- end
46
- end
@@ -1,106 +0,0 @@
1
-
2
- module ActiveLdap
3
- # Configuration
4
- #
5
- # Configuration provides the default settings required for
6
- # ActiveLdap to work with your LDAP server. All of these
7
- # settings can be passed in at initialization time.
8
- module Configuration
9
- def self.included(base)
10
- base.extend(ClassMethods)
11
- end
12
-
13
- DEFAULT_CONFIG = {}
14
- DEFAULT_CONFIG[:host] = '127.0.0.1'
15
- DEFAULT_CONFIG[:port] = 389
16
- DEFAULT_CONFIG[:method] = :plain # :ssl, :tls, :plain allowed
17
-
18
- DEFAULT_CONFIG[:bind_dn] = nil
19
- DEFAULT_CONFIG[:password_block] = nil
20
- DEFAULT_CONFIG[:password] = nil
21
- DEFAULT_CONFIG[:store_password] = true
22
- DEFAULT_CONFIG[:allow_anonymous] = true
23
- DEFAULT_CONFIG[:sasl_quiet] = false
24
- DEFAULT_CONFIG[:try_sasl] = false
25
- # See http://www.iana.org/assignments/sasl-mechanisms
26
- DEFAULT_CONFIG[:sasl_mechanisms] = ["GSSAPI", "DIGEST-MD5",
27
- "CRAM-MD5", "EXTERNAL"]
28
-
29
- DEFAULT_CONFIG[:retry_limit] = 3
30
- DEFAULT_CONFIG[:retry_wait] = 3
31
- DEFAULT_CONFIG[:timeout] = 0 # in seconds; 0 <= Never timeout
32
- # Whether or not to retry on timeouts
33
- DEFAULT_CONFIG[:retry_on_timeout] = true
34
-
35
- DEFAULT_CONFIG[:logger] = nil
36
-
37
- module ClassMethods
38
- @@defined_configurations = {}
39
-
40
- def default_configuration
41
- DEFAULT_CONFIG.dup
42
- end
43
-
44
- def ensure_configuration(config=nil)
45
- if config.nil?
46
- if defined?(LDAP_ENV)
47
- config = LDAP_ENV
48
- elsif defined?(RAILS_ENV)
49
- config = RAILS_ENV
50
- else
51
- config = {}
52
- end
53
- end
54
-
55
- if config.is_a?(Symbol) or config.is_a?(String)
56
- _config = configurations[config.to_s]
57
- unless _config
58
- raise ConnectionError, "#{config} connection is not configured"
59
- end
60
- config = _config
61
- end
62
-
63
- config
64
- end
65
-
66
- def configuration(key=nil)
67
- @@defined_configurations[key || active_connection_name]
68
- end
69
-
70
- def define_configuration(key, config)
71
- @@defined_configurations[key] = config
72
- end
73
-
74
- def defined_configurations
75
- @@defined_configurations
76
- end
77
-
78
- def remove_configuration_by_configuration(config)
79
- @@defined_configurations.delete_if {|key, value| value == config}
80
- end
81
-
82
- CONNECTION_CONFIGURATION_KEYS = [:base, :ldap_scope, :adapter]
83
- def remove_connection_related_configuration(config)
84
- config.reject do |key, value|
85
- CONNECTION_CONFIGURATION_KEYS.include?(key)
86
- end
87
- end
88
-
89
- def merge_configuration(config)
90
- configuration = default_configuration
91
- config.symbolize_keys.each do |key, value|
92
- case key
93
- when :base
94
- # Scrub before inserting
95
- self.base = value.gsub(/['}{#]/, '')
96
- when :ldap_scope
97
- self.ldap_scope = value
98
- else
99
- configuration[key] = value
100
- end
101
- end
102
- configuration
103
- end
104
- end
105
- end
106
- end
@@ -1,142 +0,0 @@
1
- module ActiveLdap
2
- module Connection
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods
8
- @@active_connections = {}
9
-
10
- def active_connections
11
- @@active_connections[Thread.current.object_id] ||= {}
12
- end
13
-
14
- def active_connection_name
15
- @active_connection_name ||= determine_active_connection_name
16
- end
17
-
18
- def clear_active_connections!
19
- connections = active_connections
20
- connections.each do |key, connection|
21
- connection.disconnect!
22
- end
23
- connections.clear
24
- end
25
-
26
- def clear_active_connection_name
27
- @active_connection_name = nil
28
- ObjectSpace.each_object(Class) do |klass|
29
- if klass < self and !klass.name.empty?
30
- klass.instance_variable_set("@active_connection_name", nil)
31
- end
32
- end
33
- end
34
-
35
- def connection
36
- conn = nil
37
- @active_connection_name ||= nil
38
- if @active_connection_name
39
- conn = active_connections[@active_connection_name]
40
- end
41
- unless conn
42
- conn = retrieve_connection
43
- active_connections[@active_connection_name] = conn
44
- end
45
- conn
46
- end
47
-
48
- def connection=(adapter)
49
- if adapter.is_a?(Adapter::Base)
50
- @schema = nil
51
- active_connections[active_connection_name] = adapter
52
- elsif adapter.is_a?(Hash)
53
- config = adapter
54
- adapter = (config[:adapter] || "ldap")
55
- normalized_adapter = adapter.downcase.gsub(/-/, "_")
56
- adapter_method = "#{normalized_adapter}_connection"
57
- unless Adapter::Base.respond_to?(adapter_method)
58
- raise AdapterNotFound.new(adapter)
59
- end
60
- config = remove_connection_related_configuration(config)
61
- self.connection = Adapter::Base.send(adapter_method, config)
62
- elsif adapter.nil?
63
- raise ConnectionNotEstablished
64
- else
65
- establish_connection(adapter)
66
- end
67
- end
68
-
69
- def connected?
70
- active_connections[active_connection_name] ? true : false
71
- end
72
-
73
- def retrieve_connection
74
- conn = nil
75
- name = active_connection_name
76
- raise ConnectionNotEstablished unless name
77
- conn = active_connections[name]
78
- if conn.nil?
79
- config = configuration(name)
80
- raise ConnectionNotEstablished unless config
81
- self.connection = config
82
- conn = active_connections[name]
83
- end
84
- raise ConnectionNotEstablished if conn.nil?
85
- conn
86
- end
87
-
88
- def remove_connection(klass=self)
89
- key = active_connection_key(klass)
90
- config = configuration(key)
91
- conn = active_connections[key]
92
- remove_configuration_by_configuration(config)
93
- active_connections.delete_if {|key, value| value == conn}
94
- conn.disconnect! if conn
95
- config
96
- end
97
-
98
- def establish_connection(config=nil)
99
- config = ensure_configuration(config)
100
- remove_connection
101
-
102
- clear_active_connection_name
103
- key = active_connection_key
104
- @active_connection_name = key
105
- define_configuration(key, merge_configuration(config))
106
- end
107
-
108
- # Return the schema object
109
- def schema
110
- @schema ||= connection.schema
111
- end
112
-
113
- private
114
- def active_connection_key(k=self)
115
- k.name.empty? ? k.object_id : k.name
116
- end
117
-
118
- def determine_active_connection_name
119
- key = active_connection_key
120
- if active_connections[key] or configuration(key)
121
- key
122
- elsif self == ActiveLdap::Base
123
- nil
124
- else
125
- superclass.active_connection_name
126
- end
127
- end
128
- end
129
-
130
- def connection
131
- self.class.connection
132
- end
133
-
134
- # schema
135
- #
136
- # Returns the value of self.class.schema
137
- # This is just syntactic sugar
138
- def schema
139
- self.class.schema
140
- end
141
- end
142
- end
@@ -1,246 +0,0 @@
1
- require 'strscan'
2
-
3
- module ActiveLdap
4
- class DistinguishedName
5
- class Parser
6
- attr_reader :dn
7
- def initialize(source)
8
- @dn = nil
9
- @source = source
10
- end
11
-
12
- def parse
13
- return @dn if @dn
14
-
15
- rdns = []
16
- scanner = StringScanner.new(@source)
17
-
18
- scanner.scan(/\s*/)
19
- raise rdn_is_missing if scanner.scan(/\s*\+\s*/)
20
- raise name_component_is_missing if scanner.scan(/\s*,\s*/)
21
-
22
- rdn = {}
23
- until scanner.eos?
24
- type = scan_attribute_type(scanner)
25
- skip_attribute_type_and_value_separator(scanner)
26
- value = scan_attribute_value(scanner)
27
- rdn[type] = value
28
- if scanner.scan(/\s*\+\s*/)
29
- raise rdn_is_missing if scanner.eos?
30
- elsif scanner.scan(/\s*\,\s*/)
31
- rdns << rdn
32
- rdn = {}
33
- raise name_component_is_missing if scanner.eos?
34
- else
35
- scanner.scan(/\s*/)
36
- rdns << rdn if scanner.eos?
37
- end
38
- end
39
-
40
- @dn = DN.new(*rdns)
41
- @dn
42
- end
43
-
44
- private
45
- ATTRIBUTE_TYPE_RE = /\s*([a-zA-Z][a-zA-Z\d\-]*|\d+(?:\.\d+)*)\s*/
46
- def scan_attribute_type(scanner)
47
- raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE)
48
- scanner[1]
49
- end
50
-
51
- def skip_attribute_type_and_value_separator(scanner)
52
- raise attribute_value_is_missing unless scanner.scan(/\s*=\s*/)
53
- end
54
-
55
- HEX_PAIR = "(?:[\\da-fA-F]{2})"
56
- STRING_CHARS_RE = /[^,=\+<>\#;\\\"]*/ #
57
- PAIR_RE = /\\([,=\+<>\#;]|\\|\"|(#{HEX_PAIR}))/ #
58
- HEX_STRING_RE = /\#(#{HEX_PAIR}+)/ #
59
- def scan_attribute_value(scanner)
60
- if scanner.scan(HEX_STRING_RE)
61
- value = scanner[1].scan(/../).collect do |hex_pair|
62
- hex_pair.hex
63
- end.pack("C*")
64
- elsif scanner.scan(/\"/)
65
- value = scan_quoted_attribute_value(scanner)
66
- else
67
- value = scan_not_quoted_attribute_value(scanner)
68
- end
69
- raise attribute_value_is_missing if value.blank?
70
-
71
- value
72
- end
73
-
74
- def scan_quoted_attribute_value(scanner)
75
- result = ""
76
- until scanner.scan(/\"/)
77
- scanner.scan(/([^\\\"]*)/)
78
- quoted_strings = scanner[1]
79
- pairs = collect_pairs(scanner)
80
-
81
- if scanner.eos? or (quoted_strings.empty? and pairs.empty?)
82
- raise found_unmatched_quotation
83
- end
84
-
85
- result << quoted_strings
86
- result << pairs
87
- end
88
- result
89
- end
90
-
91
- def scan_not_quoted_attribute_value(scanner)
92
- result = ""
93
- until scanner.eos?
94
- prev_size = result.size
95
- pairs = collect_pairs(scanner)
96
- strings = scanner.scan(STRING_CHARS_RE)
97
- result << pairs if !pairs.nil? and !pairs.empty?
98
- unless strings.nil?
99
- if scanner.peek(1) == ","
100
- result << strings.rstrip
101
- else
102
- result << strings
103
- end
104
- end
105
- break if prev_size == result.size
106
- end
107
- result
108
- end
109
-
110
- def collect_pairs(scanner)
111
- result = ""
112
- while scanner.scan(PAIR_RE)
113
- if scanner[2]
114
- result << [scanner[2].hex].pack("C*")
115
- else
116
- result << scanner[1]
117
- end
118
- end
119
- result
120
- end
121
-
122
- def invalid_dn(reason)
123
- DistinguishedNameInvalid.new(@source, reason)
124
- end
125
-
126
- def name_component_is_missing
127
- invalid_dn("name component is missing")
128
- end
129
-
130
- def rdn_is_missing
131
- invalid_dn("relative distinguished name (RDN) is missing")
132
- end
133
-
134
- def attribute_type_is_missing
135
- invalid_dn("attribute type is missing")
136
- end
137
-
138
- def attribute_value_is_missing
139
- invalid_dn("attribute value is missing")
140
- end
141
-
142
- def found_unmatched_quotation
143
- invalid_dn("found unmatched quotation")
144
- end
145
- end
146
-
147
- class << self
148
- def parse(source)
149
- Parser.new(source).parse
150
- end
151
- end
152
-
153
- attr_reader :rdns
154
- def initialize(*rdns)
155
- @rdns = rdns.collect do |rdn|
156
- rdn = {rdn[0] => rdn[1]} if rdn.is_a?(Array) and rdn.size == 2
157
- rdn
158
- end
159
- end
160
-
161
- def -(other)
162
- rdns = @rdns.dup
163
- normalized_rdns = normalize(@rdns)
164
- normalize(other.rdns).reverse_each do |rdn|
165
- if rdn == normalized_rdns.pop
166
- rdns.pop
167
- else
168
- raise ArgumentError, "#{other} isn't sub DN of #{self}"
169
- end
170
- end
171
- self.class.new(*rdns)
172
- end
173
-
174
- def <<(rdn)
175
- @rdns << rdn
176
- end
177
-
178
- def unshift(rdn)
179
- @rdns.unshift(rdn)
180
- end
181
-
182
- def <=>(other)
183
- normalize_for_comparing(@rdns) <=>
184
- normalize_for_comparing(other.rdns)
185
- end
186
-
187
- def ==(other)
188
- other.is_a?(self.class) and
189
- normalize(@rdns) == normalize(other.rdns)
190
- end
191
-
192
- def eql?(other)
193
- other.is_a?(self.class) and
194
- normalize(@rdns).to_s.eql?(normalize(other.rdns).to_s)
195
- end
196
-
197
- def hash
198
- normalize(@rdns).to_s.hash
199
- end
200
-
201
- def inspect
202
- super
203
- end
204
-
205
- def to_s
206
- @rdns.collect do |rdn|
207
- rdn.sort_by do |type, value|
208
- type.upcase
209
- end.collect do |type, value|
210
- "#{type}=#{escape(value)}"
211
- end.join("+")
212
- end.join(",")
213
- end
214
-
215
- private
216
- def normalize(rdns)
217
- rdns.collect do |rdn|
218
- normalized_rdn = {}
219
- rdn.each do |key, value|
220
- normalized_rdn[key.upcase] = value.upcase
221
- end
222
- normalized_rdn
223
- end
224
- end
225
-
226
- def normalize_for_comparing(rdns)
227
- normalize(rdns).collect do |rdn|
228
- rdn.sort_by do |key, value|
229
- key
230
- end
231
- end.collect do |key, value|
232
- [key, value]
233
- end
234
- end
235
-
236
- def escape(value)
237
- if /(\A | \z)/.match(value)
238
- '"' + value.gsub(/([\\\"])/, '\\\\\1') + '"'
239
- else
240
- value.gsub(/([,=\+<>#;\\\"])/, '\\\\\1')
241
- end
242
- end
243
- end
244
-
245
- DN = DistinguishedName
246
- end