activeldap 4.0.2 → 4.0.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 +4 -4
- data/doc/text/news.textile +37 -0
- data/doc/text/rails.textile +8 -4
- data/doc/text/tutorial.textile +0 -9
- data/lib/active_ldap/adapter/base.rb +15 -53
- data/lib/active_ldap/adapter/ldap.rb +17 -4
- data/lib/active_ldap/adapter/ldap_ext.rb +50 -7
- data/lib/active_ldap/adapter/net_ldap.rb +9 -1
- data/lib/active_ldap/association/belongs_to_many.rb +6 -2
- data/lib/active_ldap/association/collection.rb +5 -0
- data/lib/active_ldap/base.rb +0 -3
- data/lib/active_ldap/connection.rb +0 -7
- data/lib/active_ldap/ldap_controls.rb +11 -0
- data/lib/active_ldap/log_subscriber.rb +18 -15
- data/lib/active_ldap/railtie.rb +0 -2
- data/lib/active_ldap/supported_control.rb +14 -0
- data/lib/active_ldap/validations.rb +14 -1
- data/lib/active_ldap/version.rb +1 -1
- data/test/run-test.rb +9 -4
- data/test/test_associations.rb +18 -0
- data/test/test_connection.rb +4 -1
- data/test/test_supported_control.rb +23 -0
- data/test/test_validation.rb +31 -1
- metadata +32 -29
- data/lib/active_ldap/action_controller/ldap_benchmarking.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68d1e26bd0a299b5afa18d537f9c0dc973798acb
|
4
|
+
data.tar.gz: 354eae82bd94b70f77d0f3a62b66ec45cc69afef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 248bab09098603beb4c65c1a4a01461f2330a82a7bc1d65eaca4cd8c1ce393d9a6a7457dd6fbf5e653ca97af5c91b85c3d13c5f92aea487f839b589896f1f1d0
|
7
|
+
data.tar.gz: 4d502e9d14654390f95c1d2dae264144e28490662dd3739c492b9413b107ba809ceb2aed0b0baa40ae3eb8adcc1b8d9627dad66f4b6701edf5446e986b83625d
|
data/doc/text/news.textile
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
h1. News
|
2
2
|
|
3
|
+
h2(#4-0-3). 4.0.3: 2014-05-15
|
4
|
+
|
5
|
+
h3. Improvements
|
6
|
+
|
7
|
+
* Supported stopping colorize logging by @config.colorize_logging = false@.
|
8
|
+
[GitHub:#81] [Reported by nengxu]
|
9
|
+
* Supported PagedResults defined in RFC 2696 in the net-ldap adapter.
|
10
|
+
[activeldap-discuss] Paged results
|
11
|
+
[Suggested by Aaron Knister]
|
12
|
+
* Supported PagedResults defined in RFC 2696 in the ldap adapter.
|
13
|
+
[GitHub#83] [Patch by Aaron Knister]
|
14
|
+
* Stopped to override ORM generator by default.
|
15
|
+
[GitHub#87] [Patch by Josef Šimánek]
|
16
|
+
* Supported Rails 4.1.0.
|
17
|
+
[GitHub#90] [Patch by Francisco Miguel Biete]
|
18
|
+
* document: Removed obsoleted description.
|
19
|
+
[activeldap-discuss] [Reported by Jarod Watkins]
|
20
|
+
* Supported @ActiveLdap::Base.attribute_method?@ .
|
21
|
+
[GitHub#92] [Reported by Renaud Chaput]
|
22
|
+
|
23
|
+
h3. Fixes
|
24
|
+
|
25
|
+
* Fixed a bug that @belongs_to :many@ 's inconsistent behavior.
|
26
|
+
You get DN attribute when you add an entry by DN attribute to
|
27
|
+
belongs_to :many collection. It should return entry object instead of
|
28
|
+
DN attribute. Because loaded collection returns entry objects.
|
29
|
+
[activeldap-discuss] [Reported by Jarod Watkins]
|
30
|
+
|
31
|
+
h3. Thanks
|
32
|
+
|
33
|
+
* nengxu
|
34
|
+
* Aaron Knister
|
35
|
+
* Josef Šimánek
|
36
|
+
* Francisco Miguel Biete
|
37
|
+
* Jarod Watkins
|
38
|
+
* Renaud Chaput
|
39
|
+
|
3
40
|
h2(#4-0-2). 4.0.2: 2014-01-04
|
4
41
|
|
5
42
|
h3. Improvements
|
data/doc/text/rails.textile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
h1. Rails
|
2
2
|
|
3
|
-
ActiveLdap supports Rails
|
3
|
+
ActiveLdap supports Rails 4.0 or later.
|
4
4
|
|
5
5
|
h2. Install
|
6
6
|
|
@@ -30,7 +30,7 @@ connection configurations per environment. Similarly, the
|
|
30
30
|
ldap.yml file allows configurations to be set for
|
31
31
|
development, test, and production environments.
|
32
32
|
|
33
|
-
You can generate 'config/ldap.yml' by the
|
33
|
+
You can generate 'config/ldap.yml' by the following command:
|
34
34
|
|
35
35
|
<pre class="command">
|
36
36
|
% script/rails generate active_ldap:scaffold
|
@@ -54,13 +54,17 @@ When your application starts up,
|
|
54
54
|
ActiveLdap::Base.setup_connection will be called with the
|
55
55
|
parameters specified for your current environment.
|
56
56
|
|
57
|
+
You can replace default orm generators with gems one
|
58
|
+
to skip active_ldap prefix in 'config/application.rb':
|
59
|
+
<pre>config.app_generators.orm :active_ldap</pre>
|
60
|
+
|
57
61
|
h2. Model
|
58
62
|
|
59
63
|
You can generate a User model that represents entries under
|
60
64
|
ou=Users by the following command:
|
61
65
|
|
62
66
|
<pre class="command">
|
63
|
-
% script/rails generate model User --dn-attribute uid --classes person PosixAccount
|
67
|
+
% script/rails generate active_ldap:model User --dn-attribute uid --classes person PosixAccount
|
64
68
|
</pre>
|
65
69
|
|
66
70
|
It generates the following app/model/user.rb:
|
@@ -125,7 +129,7 @@ end
|
|
125
129
|
You can also generate a Ou model by the following command:
|
126
130
|
|
127
131
|
<pre class="command">
|
128
|
-
% script/rails generate model Ou --prefix '' --classes organizationalUnit
|
132
|
+
% script/rails generate active_ldap:model Ou --prefix '' --classes organizationalUnit
|
129
133
|
</pre>
|
130
134
|
|
131
135
|
<pre>
|
data/doc/text/tutorial.textile
CHANGED
@@ -313,15 +313,6 @@ Relation is resolved by searching entries of :class_name class with :foreign_key
|
|
313
313
|
|
314
314
|
:many is used for an object belongs to many objects. All of matched objects are treated as belonged objects.
|
315
315
|
|
316
|
-
In addition, you can do simple membership tests by doing the following:
|
317
|
-
|
318
|
-
<pre>
|
319
|
-
irb> me.groups.member? 'root'
|
320
|
-
=> false
|
321
|
-
irb> me.groups.member? 'develop'
|
322
|
-
=> true
|
323
|
-
</pre>
|
324
|
-
|
325
316
|
h5. has_many
|
326
317
|
|
327
318
|
This method is the opposite of belongs_to. Instead of checking other objects in
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
|
3
1
|
require 'active_ldap/schema'
|
4
2
|
require 'active_ldap/entry_attribute'
|
5
3
|
require 'active_ldap/ldap_error'
|
4
|
+
require 'active_ldap/supported_control'
|
6
5
|
|
7
6
|
module ActiveLdap
|
8
7
|
module Adapter
|
@@ -19,9 +18,7 @@ module ActiveLdap
|
|
19
18
|
|
20
19
|
@@row_even = true
|
21
20
|
|
22
|
-
attr_reader :runtime
|
23
21
|
def initialize(configuration={})
|
24
|
-
@runtime = 0
|
25
22
|
@connection = nil
|
26
23
|
@disconnected = false
|
27
24
|
@bound = false
|
@@ -36,11 +33,6 @@ module ActiveLdap
|
|
36
33
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
37
34
|
end
|
38
35
|
|
39
|
-
def reset_runtime
|
40
|
-
runtime, @runtime = @runtime, 0
|
41
|
-
runtime
|
42
|
-
end
|
43
|
-
|
44
36
|
def connect(options={})
|
45
37
|
host = options[:host] || @host
|
46
38
|
method = options[:method] || @method || :plain
|
@@ -148,6 +140,11 @@ module ActiveLdap
|
|
148
140
|
root_dse_values('namingContexts')
|
149
141
|
end
|
150
142
|
|
143
|
+
def supported_control
|
144
|
+
@supported_control ||=
|
145
|
+
SupportedControl.new(root_dse_values("supportedControl"))
|
146
|
+
end
|
147
|
+
|
151
148
|
def entry_attribute(object_classes)
|
152
149
|
@entry_attributes[object_classes.uniq.sort] ||=
|
153
150
|
EntryAttribute.new(schema, object_classes)
|
@@ -240,13 +237,6 @@ module ActiveLdap
|
|
240
237
|
end
|
241
238
|
end
|
242
239
|
|
243
|
-
def log_info(name, runtime_in_seconds, info=nil)
|
244
|
-
return unless @logger
|
245
|
-
return unless @logger.debug?
|
246
|
-
message = "LDAP: #{name} (#{'%.1f' % (runtime_in_seconds * 1000)}ms)"
|
247
|
-
@logger.debug(format_log_entry(message, info))
|
248
|
-
end
|
249
|
-
|
250
240
|
private
|
251
241
|
def ensure_port(method)
|
252
242
|
if method == :ssl
|
@@ -589,7 +579,7 @@ module ActiveLdap
|
|
589
579
|
@logger.error do
|
590
580
|
_("Reconnect to server failed: %s\n" \
|
591
581
|
"Reconnect to server failed backtrace:\n" \
|
592
|
-
"%s") % [detail.
|
582
|
+
"%s") % [detail.message, detail.backtrace.join("\n")]
|
593
583
|
end
|
594
584
|
# Do not loop if forced
|
595
585
|
raise ConnectionError, detail.message if force
|
@@ -645,7 +635,8 @@ module ActiveLdap
|
|
645
635
|
:scope => :base,
|
646
636
|
:attributes => attrs,
|
647
637
|
:limit => 1,
|
648
|
-
:try_reconnect => try_reconnect
|
638
|
+
:try_reconnect => try_reconnect,
|
639
|
+
:use_paged_results => false) do |dn, attributes|
|
649
640
|
found_attributes = attributes
|
650
641
|
end
|
651
642
|
found_attributes
|
@@ -666,42 +657,13 @@ module ActiveLdap
|
|
666
657
|
end
|
667
658
|
|
668
659
|
def log(name, info=nil)
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
:name => name) { result = yield }
|
675
|
-
result
|
676
|
-
else
|
677
|
-
log_info(name, 0, info)
|
678
|
-
nil
|
679
|
-
end
|
680
|
-
rescue Exception
|
681
|
-
log_info("#{name}: FAILED", 0,
|
682
|
-
(info || {}).merge(:error => $!.class.name,
|
683
|
-
:error_message => $!.message))
|
684
|
-
raise
|
685
|
-
end
|
686
|
-
|
687
|
-
def format_log_entry(message, info=nil)
|
688
|
-
if ActiveLdap::Base.colorize_logging
|
689
|
-
if @@row_even
|
690
|
-
message_color, dump_color = "4;36;1", "0;1"
|
691
|
-
else
|
692
|
-
@@row_even = true
|
693
|
-
message_color, dump_color = "4;35;1", "0"
|
694
|
-
end
|
695
|
-
@@row_even = !@@row_even
|
696
|
-
|
697
|
-
log_entry = " \e[#{message_color}m#{message}\e[0m"
|
698
|
-
log_entry << ": \e[#{dump_color}m#{info.inspect}\e[0m" if info
|
699
|
-
log_entry
|
700
|
-
else
|
701
|
-
log_entry = message
|
702
|
-
log_entry += ": #{info.inspect}" if info
|
703
|
-
log_entry
|
660
|
+
result = nil
|
661
|
+
payload = {:name => name}
|
662
|
+
payload[:info] = info if info
|
663
|
+
@instrumenter.instrument("log_info.active_ldap", payload) do
|
664
|
+
result = yield if block_given?
|
704
665
|
end
|
666
|
+
result
|
705
667
|
end
|
706
668
|
|
707
669
|
def ensure_dn_string(dn)
|
@@ -55,8 +55,10 @@ module ActiveLdap
|
|
55
55
|
uri = construct_uri(host, port, method.ssl?)
|
56
56
|
with_start_tls = method.start_tls?
|
57
57
|
info = {:uri => uri, :with_start_tls => with_start_tls}
|
58
|
-
|
59
|
-
|
58
|
+
connection = log("connect", info) do
|
59
|
+
method.connect(host, port)
|
60
|
+
end
|
61
|
+
[connection, uri, with_start_tls]
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
@@ -82,12 +84,23 @@ module ActiveLdap
|
|
82
84
|
def search(options={})
|
83
85
|
super(options) do |base, scope, filter, attrs, limit|
|
84
86
|
begin
|
87
|
+
use_paged_results = options[:use_paged_results]
|
88
|
+
if use_paged_results or use_paged_results.nil?
|
89
|
+
use_paged_results = supported_control.paged_results?
|
90
|
+
end
|
85
91
|
info = {
|
86
92
|
:base => base, :scope => scope_name(scope),
|
87
93
|
:filter => filter, :attributes => attrs, :limit => limit,
|
88
94
|
}
|
89
|
-
|
90
|
-
|
95
|
+
options = {
|
96
|
+
:base => base,
|
97
|
+
:scope => scope,
|
98
|
+
:filter => filter,
|
99
|
+
:attributes => attrs,
|
100
|
+
:limit => limit,
|
101
|
+
:use_paged_results => use_paged_results
|
102
|
+
}
|
103
|
+
execute(:search_full, info, options) do |entry|
|
91
104
|
attributes = {}
|
92
105
|
entry.attrs.each do |attr|
|
93
106
|
value = entry.vals(attr)
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "ldap"
|
2
|
+
require "ldap/ldif"
|
3
|
+
require "ldap/schema"
|
4
|
+
require "ldap/control"
|
4
5
|
|
5
6
|
module LDAP
|
6
7
|
unless const_defined?(:LDAP_OPT_ERROR_NUMBER)
|
@@ -57,16 +58,26 @@ module LDAP
|
|
57
58
|
@@have_search_ext = false
|
58
59
|
end
|
59
60
|
|
60
|
-
def
|
61
|
+
def search_full(options, &block)
|
62
|
+
base = options[:base]
|
63
|
+
scope = options[:scope]
|
64
|
+
filter = options[:filter]
|
65
|
+
attributes = options[:attributes]
|
66
|
+
limit = options[:limit] || 0
|
67
|
+
use_paged_results = options[:use_paged_results]
|
61
68
|
if @@have_search_ext
|
62
|
-
|
63
|
-
|
69
|
+
if use_paged_results
|
70
|
+
paged_search(base, scope, filter, attributes, limit, &block)
|
71
|
+
else
|
72
|
+
search_ext(base, scope, filter, attributes,
|
73
|
+
false, nil, nil, 0, 0, limit, &block)
|
74
|
+
end
|
64
75
|
else
|
65
76
|
i = 0
|
66
77
|
search(base, scope, filter, attributes) do |entry|
|
67
78
|
i += 1
|
68
79
|
block.call(entry)
|
69
|
-
break if limit and limit <= i
|
80
|
+
break if 0 < limit and limit <= i
|
70
81
|
end
|
71
82
|
end
|
72
83
|
end
|
@@ -101,5 +112,37 @@ module LDAP
|
|
101
112
|
klass ||= ActiveLdap::LdapError
|
102
113
|
raise klass, message
|
103
114
|
end
|
115
|
+
|
116
|
+
private
|
117
|
+
def find_paged_results_control(controls)
|
118
|
+
controls.find do |control|
|
119
|
+
control.oid == LDAP::LDAP_CONTROL_PAGEDRESULTS
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def paged_search(base, scope, filter, attributes, limit, &block)
|
124
|
+
# work around a bug with openldap
|
125
|
+
page_size = 126
|
126
|
+
cookie = ""
|
127
|
+
critical = true
|
128
|
+
|
129
|
+
loop do
|
130
|
+
ber_string = LDAP::Control.encode(page_size, cookie)
|
131
|
+
control = LDAP::Control.new(LDAP::LDAP_CONTROL_PAGEDRESULTS,
|
132
|
+
ber_string,
|
133
|
+
critical)
|
134
|
+
|
135
|
+
search_ext(base, scope, filter, attributes,
|
136
|
+
false, [control], nil, 0, 0, limit, &block)
|
137
|
+
|
138
|
+
control = find_paged_results_control(@controls)
|
139
|
+
break if control.nil?
|
140
|
+
returned_size, cookie = control.decode
|
141
|
+
returned_size = returned_size.to_i
|
142
|
+
page_size = returned_size if returned_size > 0
|
143
|
+
|
144
|
+
break if cookie.empty?
|
145
|
+
end
|
146
|
+
end
|
104
147
|
end
|
105
148
|
end
|
@@ -63,6 +63,12 @@ module ActiveLdap
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def search(options={})
|
66
|
+
use_paged_results = options[:use_paged_results]
|
67
|
+
if use_paged_results or use_paged_results.nil?
|
68
|
+
paged_results_supported = supported_control.paged_results?
|
69
|
+
else
|
70
|
+
paged_results_supported = false
|
71
|
+
end
|
66
72
|
super(options) do |base, scope, filter, attrs, limit|
|
67
73
|
args = {
|
68
74
|
:base => base,
|
@@ -70,10 +76,12 @@ module ActiveLdap
|
|
70
76
|
:filter => filter,
|
71
77
|
:attributes => attrs,
|
72
78
|
:size => limit,
|
79
|
+
:paged_searches_supported => paged_results_supported,
|
73
80
|
}
|
74
81
|
info = {
|
75
82
|
:base => base, :scope => scope_name(scope),
|
76
|
-
:filter => filter, :attributes => attrs, :limit => limit
|
83
|
+
:filter => filter, :attributes => attrs, :limit => limit,
|
84
|
+
:paged_results_supported => paged_results_supported,
|
77
85
|
}
|
78
86
|
execute(:search, info, args) do |entry|
|
79
87
|
attributes = {}
|
@@ -4,9 +4,13 @@ module ActiveLdap
|
|
4
4
|
module Association
|
5
5
|
class BelongsToMany < Collection
|
6
6
|
private
|
7
|
-
def
|
7
|
+
def normalize_entry(entry)
|
8
8
|
_foreign_class = foreign_class
|
9
9
|
entry = _foreign_class.find(entry) unless entry.is_a?(_foreign_class)
|
10
|
+
entry
|
11
|
+
end
|
12
|
+
|
13
|
+
def insert_entry(entry)
|
10
14
|
old_value = entry[@options[:many], true]
|
11
15
|
primary_key_name = @options[:primary_key_name]
|
12
16
|
if primary_key_name == "dn"
|
@@ -23,7 +27,7 @@ module ActiveLdap
|
|
23
27
|
end
|
24
28
|
|
25
29
|
def delete_entries(entries)
|
26
|
-
|
30
|
+
_foreign_class = foreign_class
|
27
31
|
entries.each do |entry|
|
28
32
|
entry = _foreign_class.find(entry) unless entry.is_a?(_foreign_class)
|
29
33
|
old_value = entry[@options[:many], true]
|
@@ -71,6 +71,10 @@ module ActiveLdap
|
|
71
71
|
end.flatten
|
72
72
|
end
|
73
73
|
|
74
|
+
def normalize_entry(entry)
|
75
|
+
entry
|
76
|
+
end
|
77
|
+
|
74
78
|
def insert_entry(entry)
|
75
79
|
entry[@options[:foreign_key_name]] = @owner[@options[:local_key_name]]
|
76
80
|
entry.save
|
@@ -81,6 +85,7 @@ module ActiveLdap
|
|
81
85
|
load_target
|
82
86
|
|
83
87
|
flatten_deeper(entries).each do |entry|
|
88
|
+
entry = normalize_entry(entry)
|
84
89
|
unless @owner.new_entry?
|
85
90
|
infect_connection(entry)
|
86
91
|
result &&= insert_entry(entry)
|
data/lib/active_ldap/base.rb
CHANGED
@@ -292,9 +292,6 @@ module ActiveLdap
|
|
292
292
|
end
|
293
293
|
end
|
294
294
|
|
295
|
-
cattr_accessor :colorize_logging, :instance_writer => false
|
296
|
-
@@colorize_logging = true
|
297
|
-
|
298
295
|
VALID_LDAP_MAPPING_OPTIONS = [:dn_attribute, :prefix, :scope,
|
299
296
|
:classes, :recommended_classes,
|
300
297
|
:excluded_classes, :sort_by, :order]
|
@@ -165,13 +165,6 @@ module ActiveLdap
|
|
165
165
|
connection.schema
|
166
166
|
end
|
167
167
|
|
168
|
-
def reset_runtime
|
169
|
-
active_connections.inject(0) do |result, (name, connection)|
|
170
|
-
_ = name # for suppress a warning on Ruby 1.9.3
|
171
|
-
result + connection.reset_runtime
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
168
|
private
|
176
169
|
def active_connection_key(k=self)
|
177
170
|
k.name.blank? ? k.object_id : k.name
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module ActiveLdap
|
2
|
+
module LdapControls
|
3
|
+
PAGED_RESULTS = "1.2.840.113556.1.4.319"
|
4
|
+
ASSERTION = "1.3.6.1.1.12"
|
5
|
+
PRE_READ = "1.3.6.1.1.13.1"
|
6
|
+
POST_READ = "1.3.6.1.1.13.2"
|
7
|
+
SUBENTRIES = "1.3.6.1.4.1.4203.1.10.1"
|
8
|
+
MANAGE_DSA_IT = "2.16.840.1.113730.3.4.2"
|
9
|
+
PROXIED_AUTHORIZATION = "2.16.840.1.113730.3.4.18"
|
10
|
+
end
|
11
|
+
end
|
@@ -3,42 +3,45 @@ module ActiveLdap
|
|
3
3
|
def self.runtime=(value)
|
4
4
|
Thread.current["active_ldap_runtime"] = value
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def self.runtime
|
8
8
|
Thread.current["active_ldap_runtime"] ||= 0
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def self.reset_runtime
|
12
12
|
rt, self.runtime = runtime, 0
|
13
13
|
rt
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def initialize
|
17
17
|
super
|
18
|
-
@
|
18
|
+
@odd = false
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def log_info(event)
|
22
22
|
self.class.runtime += event.duration
|
23
23
|
return unless logger.debug?
|
24
|
-
|
24
|
+
|
25
25
|
payload = event.payload
|
26
|
-
|
26
|
+
label = payload[:name]
|
27
|
+
label += ": FAILED" if payload[:info][:exception]
|
28
|
+
name = 'LDAP: %s (%.1fms)' % [label, event.duration]
|
27
29
|
info = payload[:info].inspect
|
28
|
-
|
30
|
+
|
29
31
|
if odd?
|
30
|
-
|
32
|
+
name = color(name, CYAN, true)
|
33
|
+
info = color(info, nil, true)
|
31
34
|
else
|
32
|
-
|
35
|
+
name = color(name, MAGENTA, true)
|
33
36
|
end
|
34
|
-
|
35
|
-
debug "
|
37
|
+
|
38
|
+
debug " #{name} #{info}"
|
36
39
|
end
|
37
|
-
|
40
|
+
|
38
41
|
def odd?
|
39
|
-
@
|
42
|
+
@odd = !@odd
|
40
43
|
end
|
41
|
-
|
44
|
+
|
42
45
|
def logger
|
43
46
|
ActiveLdap::Base.logger
|
44
47
|
end
|
data/lib/active_ldap/railtie.rb
CHANGED
@@ -6,8 +6,6 @@ Locale.init(:driver => :cgi)
|
|
6
6
|
|
7
7
|
module ActiveLdap
|
8
8
|
class Railtie < Rails::Railtie
|
9
|
-
config.app_generators.orm :active_ldap
|
10
|
-
|
11
9
|
initializer "active_ldap.setup_connection" do
|
12
10
|
ldap_configuration_file = Rails.root.join('config', 'ldap.yml')
|
13
11
|
if File.exist?(ldap_configuration_file)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "active_ldap/ldap_controls"
|
2
|
+
|
3
|
+
module ActiveLdap
|
4
|
+
class SupportedControl
|
5
|
+
def initialize(controls)
|
6
|
+
@controls = controls
|
7
|
+
@paged_results = @controls.include?(LdapControls::PAGED_RESULTS)
|
8
|
+
end
|
9
|
+
|
10
|
+
def paged_results?
|
11
|
+
@paged_results
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -2,7 +2,20 @@ module ActiveLdap
|
|
2
2
|
module Validations
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
include ActiveModel::Validations
|
5
|
-
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def attribute_method?(attribute)
|
8
|
+
normalized_attribute = entry_attribute.normalize(attribute)
|
9
|
+
normalized_attribute and normalized_attribute != "objectClass"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def entry_attribute
|
14
|
+
@entry_attribute ||=
|
15
|
+
connection.entry_attribute(classes.collect(&:name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
6
19
|
included do
|
7
20
|
alias_method :new_record?, :new_entry?
|
8
21
|
class << self
|
data/lib/active_ldap/version.rb
CHANGED
data/test/run-test.rb
CHANGED
@@ -6,9 +6,10 @@ $KCODE = 'u' if RUBY_VERSION < "1.9"
|
|
6
6
|
|
7
7
|
base_dir = File.expand_path(File.dirname(__FILE__))
|
8
8
|
top_dir = File.expand_path(File.join(base_dir, ".."))
|
9
|
-
|
10
|
-
|
11
|
-
$LOAD_PATH.unshift(
|
9
|
+
lib_dir = File.join(top_dir, "lib")
|
10
|
+
test_dir = File.join(top_dir, "test")
|
11
|
+
$LOAD_PATH.unshift(lib_dir)
|
12
|
+
$LOAD_PATH.unshift(test_dir)
|
12
13
|
|
13
14
|
require "rubygems"
|
14
15
|
require "bundler/setup"
|
@@ -17,6 +18,10 @@ require "test/unit"
|
|
17
18
|
require "test/unit/notify"
|
18
19
|
Test::Unit::Priority.enable
|
19
20
|
|
21
|
+
Dir.glob(File.join(test_dir, "**", "test_*.rb")) do |test_file|
|
22
|
+
require test_file
|
23
|
+
end
|
24
|
+
|
20
25
|
succeeded = true
|
21
26
|
target_adapters = [ENV["ACTIVE_LDAP_TEST_ADAPTER"]]
|
22
27
|
# target_adapters << "ldap"
|
@@ -25,7 +30,7 @@ target_adapters = [ENV["ACTIVE_LDAP_TEST_ADAPTER"]]
|
|
25
30
|
target_adapters.each do |adapter|
|
26
31
|
ENV["ACTIVE_LDAP_TEST_ADAPTER"] = adapter
|
27
32
|
puts "using adapter: #{adapter ? adapter : 'default'}"
|
28
|
-
unless Test::Unit::AutoRunner.run(
|
33
|
+
unless Test::Unit::AutoRunner.run(false, nil, ARGV.dup)
|
29
34
|
succeeded = false
|
30
35
|
end
|
31
36
|
puts
|
data/test/test_associations.rb
CHANGED
@@ -294,6 +294,24 @@ EOX
|
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
297
|
+
def test_belongs_to_many_add_by_dn_attribute
|
298
|
+
make_temporary_group do |group1|
|
299
|
+
make_temporary_group do |group2|
|
300
|
+
make_temporary_user do |user,|
|
301
|
+
user.update_attribute(:cn, "new #{user.cn}")
|
302
|
+
|
303
|
+
user.groups = [group1]
|
304
|
+
assert_equal([group1.id].sort,
|
305
|
+
user.groups.collect {|g| g.id}.sort)
|
306
|
+
|
307
|
+
user.groups << group2.id
|
308
|
+
assert_equal([group1.id, group2.id].sort,
|
309
|
+
user.groups.collect {|g| g.id}.sort)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
297
315
|
def test_belongs_to_many_delete
|
298
316
|
make_temporary_group do |group1|
|
299
317
|
make_temporary_group do |group2|
|
data/test/test_connection.rb
CHANGED
@@ -47,7 +47,10 @@ class TestConnection < Test::Unit::TestCase
|
|
47
47
|
raise
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
expected_message = "Unknown key: :bind_format. Valid keys are: "
|
51
|
+
valid_keys = ActiveLdap::Adapter::Base::VALID_ADAPTER_CONFIGURATION_KEYS
|
52
|
+
expected_message << valid_keys.collect(&:inspect).join(", ")
|
53
|
+
assert_equal(expected_message, exception.message)
|
51
54
|
end
|
52
55
|
|
53
56
|
def test_can_reconnect?
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'al-test-utils'
|
4
|
+
|
5
|
+
class TestSupportedControl < Test::Unit::TestCase
|
6
|
+
def supported_control(controls)
|
7
|
+
ActiveLdap::SupportedControl.new(controls)
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestPagedResults < self
|
11
|
+
def paged_results?(controls)
|
12
|
+
supported_control(controls).paged_results?
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_true
|
16
|
+
assert_true(paged_results?(ActiveLdap::LdapControls::PAGED_RESULTS))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_false
|
20
|
+
assert_true(paged_results?(ActiveLdap::LdapControls::PAGED_RESULTS))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/test/test_validation.rb
CHANGED
@@ -5,7 +5,38 @@ class TestValidation < Test::Unit::TestCase
|
|
5
5
|
include AlTestUtils
|
6
6
|
include ActiveLdap::Helper
|
7
7
|
|
8
|
+
class TestAttributeMethod < self
|
9
|
+
priority :must
|
10
|
+
|
11
|
+
priority :normal
|
12
|
+
def test_symbol
|
13
|
+
assert_true(@user_class.attribute_method?(:cn))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_string
|
17
|
+
assert_true(@user_class.attribute_method?("cn"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_upper_case
|
21
|
+
assert_true(@user_class.attribute_method?(:CN))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_mixed_case
|
25
|
+
assert_true(@user_class.attribute_method?(:Cn))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_snake_case
|
29
|
+
assert_true(@user_class.attribute_method?(:common_name))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_full_name
|
33
|
+
assert_true(@user_class.attribute_method?(:commonName))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
8
37
|
priority :must
|
38
|
+
|
39
|
+
priority :normal
|
9
40
|
def test_octet_string
|
10
41
|
make_temporary_user(:simple => true) do |user,|
|
11
42
|
utf8_encoded_binary_value = "\xff".force_encoding("UTF-8")
|
@@ -15,7 +46,6 @@ class TestValidation < Test::Unit::TestCase
|
|
15
46
|
end
|
16
47
|
end
|
17
48
|
|
18
|
-
priority :normal
|
19
49
|
def test_rename_duplicated
|
20
50
|
make_temporary_user(:simple => true) do |user1,|
|
21
51
|
make_temporary_user(:simple => true) do |user2,|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Drewry
|
@@ -9,160 +9,160 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-05-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 4.0.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 4.0.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: locale
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '0'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: gettext
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- -
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: gettext_i18n_rails
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- -
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '0'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: bundler
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: rake
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- -
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: test-unit
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: test-unit-notify
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: yard
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- -
|
130
|
+
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: RedCloth
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
type: :development
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- -
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
155
|
name: packnga
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
|
-
- -
|
158
|
+
- - ">="
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '0'
|
161
161
|
type: :development
|
162
162
|
prerelease: false
|
163
163
|
version_requirements: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- -
|
165
|
+
- - ">="
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
168
|
description: |2
|
@@ -178,7 +178,7 @@ executables: []
|
|
178
178
|
extensions: []
|
179
179
|
extra_rdoc_files: []
|
180
180
|
files:
|
181
|
-
- .yardopts
|
181
|
+
- ".yardopts"
|
182
182
|
- COPYING
|
183
183
|
- Gemfile
|
184
184
|
- LICENSE
|
@@ -214,7 +214,6 @@ files:
|
|
214
214
|
- examples/usermod-binary-del
|
215
215
|
- examples/usermod-lang-add
|
216
216
|
- lib/active_ldap.rb
|
217
|
-
- lib/active_ldap/action_controller/ldap_benchmarking.rb
|
218
217
|
- lib/active_ldap/acts/tree.rb
|
219
218
|
- lib/active_ldap/adapter/base.rb
|
220
219
|
- lib/active_ldap/adapter/jndi.rb
|
@@ -253,6 +252,7 @@ files:
|
|
253
252
|
- lib/active_ldap/get_text/parser.rb
|
254
253
|
- lib/active_ldap/helper.rb
|
255
254
|
- lib/active_ldap/human_readable.rb
|
255
|
+
- lib/active_ldap/ldap_controls.rb
|
256
256
|
- lib/active_ldap/ldap_error.rb
|
257
257
|
- lib/active_ldap/ldif.rb
|
258
258
|
- lib/active_ldap/log_subscriber.rb
|
@@ -264,6 +264,7 @@ files:
|
|
264
264
|
- lib/active_ldap/railties/controller_runtime.rb
|
265
265
|
- lib/active_ldap/schema.rb
|
266
266
|
- lib/active_ldap/schema/syntaxes.rb
|
267
|
+
- lib/active_ldap/supported_control.rb
|
267
268
|
- lib/active_ldap/timeout.rb
|
268
269
|
- lib/active_ldap/timeout_stub.rb
|
269
270
|
- lib/active_ldap/user_password.rb
|
@@ -311,6 +312,7 @@ files:
|
|
311
312
|
- test/test_persistence.rb
|
312
313
|
- test/test_reflection.rb
|
313
314
|
- test/test_schema.rb
|
315
|
+
- test/test_supported_control.rb
|
314
316
|
- test/test_syntax.rb
|
315
317
|
- test/test_user.rb
|
316
318
|
- test/test_user_password.rb
|
@@ -335,17 +337,17 @@ require_paths:
|
|
335
337
|
- lib
|
336
338
|
required_ruby_version: !ruby/object:Gem::Requirement
|
337
339
|
requirements:
|
338
|
-
- -
|
340
|
+
- - ">="
|
339
341
|
- !ruby/object:Gem::Version
|
340
342
|
version: '0'
|
341
343
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
342
344
|
requirements:
|
343
|
-
- -
|
345
|
+
- - ">="
|
344
346
|
- !ruby/object:Gem::Version
|
345
347
|
version: '0'
|
346
348
|
requirements: []
|
347
349
|
rubyforge_project: ruby-activeldap
|
348
|
-
rubygems_version: 2.
|
350
|
+
rubygems_version: 2.2.2
|
349
351
|
signing_key:
|
350
352
|
specification_version: 4
|
351
353
|
summary: ActiveLdap is a object-oriented API to LDAP
|
@@ -384,6 +386,7 @@ test_files:
|
|
384
386
|
- test/test_persistence.rb
|
385
387
|
- test/test_reflection.rb
|
386
388
|
- test/test_schema.rb
|
389
|
+
- test/test_supported_control.rb
|
387
390
|
- test/test_syntax.rb
|
388
391
|
- test/test_user.rb
|
389
392
|
- test/test_user_password.rb
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module ActiveLdap
|
2
|
-
module ActionController
|
3
|
-
module LdapBenchmarking
|
4
|
-
def self.included(base)
|
5
|
-
base.class_eval do
|
6
|
-
alias_method_chain :render_with_benchmark, :active_ldap
|
7
|
-
if private_method_defined?(:view_runtime)
|
8
|
-
alias_method_chain :view_runtime, :active_ldap
|
9
|
-
else
|
10
|
-
alias_method_chain :rendering_runtime, :active_ldap
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
def render_with_benchmark_with_active_ldap(*args, &block)
|
17
|
-
if logger
|
18
|
-
ldap_runtime_before_render = ActiveLdap::Base.reset_runtime
|
19
|
-
end
|
20
|
-
result = render_with_benchmark_without_active_ldap(*args, &block)
|
21
|
-
if logger
|
22
|
-
@ldap_runtime_before_render = ldap_runtime_before_render
|
23
|
-
@ldap_runtime_after_render = ActiveLdap::Base.reset_runtime
|
24
|
-
if defined?(@rendering_runtime)
|
25
|
-
@rendering_runtime -= @ldap_runtime_after_render
|
26
|
-
else
|
27
|
-
@view_runtime -= @ldap_runtime_after_render
|
28
|
-
end
|
29
|
-
end
|
30
|
-
result
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
def rendering_runtime_with_active_ldap(runtime)
|
35
|
-
result = rendering_runtime_without_active_ldap(runtime)
|
36
|
-
ldap_runtime = ActiveLdap::Base.reset_runtime
|
37
|
-
ldap_runtime += @ldap_runtime_before_render || 0
|
38
|
-
ldap_runtime += @ldap_runtime_after_render || 0
|
39
|
-
ldap_percentage = ldap_runtime * 100 / runtime
|
40
|
-
result + (" | LDAP: %.5f (%d%%)" % [ldap_runtime, ldap_percentage])
|
41
|
-
end
|
42
|
-
|
43
|
-
def view_runtime_with_active_ldap
|
44
|
-
result = view_runtime_without_active_ldap
|
45
|
-
ldap_runtime = ActiveLdap::Base.reset_runtime
|
46
|
-
@ldap_runtime_before_render ||= 0
|
47
|
-
@ldap_runtime_after_render ||= 0
|
48
|
-
ldap_runtime += @ldap_runtime_before_render
|
49
|
-
ldap_runtime += @ldap_runtime_after_render
|
50
|
-
result + (", LDAP: %.0f" % (ldap_runtime * 1000))
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|