activeldap 4.0.0 → 4.0.1

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.
@@ -1,5 +1,31 @@
1
1
  h1. News
2
2
 
3
+ h2(#4-0-1). 4.0.1: 2013-08-29
4
+
5
+ h3. Improvements
6
+
7
+ * Added ActiveLdap::EntryAttribute#exist?.
8
+ * [GitHub:#66] Improved Active Directory support.
9
+ Binary data can be validated correctly. [Reported by Nowhere Man]
10
+ * [GitHub:#6][GitHub:#69] Improved setup description in tutorial.
11
+ [Reported by Radosław Antoniuk] [Patch by Francisco Miguel Biete]
12
+ * [GitHub:#56] Supported moving sub-tree. It requires Ruby/LDAP 0.9.13 or later,
13
+ JRuby or net-ldap 0.5.0 or later. (net-ldap 0.5.0 isn't released yet.)
14
+ [Reported by Jean-François Rioux]
15
+
16
+ h3. Fixes
17
+
18
+ * [GitHub:#65] Removed removed attributes values by removing
19
+ objectClasses. [Reported by mbab]
20
+
21
+ h3. Thanks
22
+
23
+ * mbab
24
+ * Nowhere Man
25
+ * Radosław Antoniuk
26
+ * Francisco Miguel Biete
27
+ * Jean-François Rioux
28
+
3
29
  h2(#4-0-0). 4.0.0: 2013-07-13
4
30
 
5
31
  h3. Improvements
@@ -7,7 +7,7 @@ h2. Install
7
7
  To install, simply add the following code to your Gemfile:
8
8
 
9
9
  <pre>
10
- gem 'activeldap'
10
+ gem 'activeldap', :require => 'active_ldap/railtie'
11
11
  </pre>
12
12
 
13
13
  You should also depend on an LDAP adapter such as Net::LDAP
@@ -20,13 +20,6 @@ gem 'ruby-ldap'
20
20
  Bundler will install the gems automatically when you run
21
21
  'bundle install'.
22
22
 
23
- You also need to include the ActiveLdap railtie in
24
- config/application.rb, after the other railties:
25
-
26
- <pre>
27
- require "active_ldap/railtie"
28
- </pre>
29
-
30
23
  h2. Configuration
31
24
 
32
25
  You can use a LDAP configuration per environment. They are in
@@ -56,9 +56,9 @@ module ActiveLdap
56
56
 
57
57
  def parent=(entry)
58
58
  if entry.is_a?(String) or entry.is_a?(DN)
59
- base = entry
59
+ base = entry.to_s
60
60
  elsif entry.respond_to?(:dn)
61
- base = entry.dn
61
+ base = entry.dn.to_s
62
62
  if entry.respond_to?(:clear_association_cache)
63
63
  entry.clear_association_cache
64
64
  end
@@ -66,12 +66,20 @@ module ActiveLdap
66
66
  message = _("parent must be an entry or parent DN: %s") % entry.inspect
67
67
  raise ArgumentError, message
68
68
  end
69
+
69
70
  unless new_entry?
70
- self.class.delete_entry(dn, :connection => connection)
71
- @new_entry = true
71
+ begin
72
+ self.class.modify_rdn_entry(dn, "#{dn_attribute}=#{id}",
73
+ true, base,
74
+ :connection => connection)
75
+ rescue NotImplemented
76
+ self.class.delete_entry(dn, :connection => connection)
77
+ @new_entry = true
78
+ end
72
79
  end
80
+
73
81
  self.dn = "#{dn_attribute}=#{id},#{base}"
74
- save
82
+ save if new_entry?
75
83
  end
76
84
  end
77
85
  end
@@ -638,8 +638,8 @@ module ActiveLdap
638
638
  try_reconnect = options[:try_reconnect]
639
639
  else
640
640
  try_reconnect = true
641
- end
642
-
641
+ end
642
+
643
643
  search(:base => "",
644
644
  :scope => :base,
645
645
  :attributes => attrs,
@@ -152,7 +152,8 @@ module ActiveLdap
152
152
 
153
153
  def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
154
154
  super do |_dn, _new_rdn, _delete_old_rdn, _new_superior|
155
- if _new_superior
155
+ rename_available_p = @connection.respond_to?(:rename)
156
+ if _new_superior and not rename_available_p
156
157
  raise NotImplemented.new(_("modify RDN with new superior"))
157
158
  end
158
159
  info = {
@@ -162,7 +163,12 @@ module ActiveLdap
162
163
  :new_superior => _new_superior,
163
164
  :delete_old_rdn => _delete_old_rdn
164
165
  }
165
- execute(:modrdn, info, _dn, _new_rdn, _delete_old_rdn)
166
+ if rename_available_p
167
+ execute(:rename, info,
168
+ _dn, _new_rdn, _new_superior, _delete_old_rdn, [], [])
169
+ else
170
+ execute(:modrdn, info, _dn, _new_rdn, _delete_old_rdn)
171
+ end
166
172
  end
167
173
  end
168
174
 
@@ -119,9 +119,6 @@ module ActiveLdap
119
119
 
120
120
  def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
121
121
  super do |_dn, _new_rdn, _delete_old_rdn, _new_superior|
122
- if _new_superior
123
- raise NotImplemented.new(_("modify RDN with new superior"))
124
- end
125
122
  info = {
126
123
  :name => "modify: RDN",
127
124
  :dn => _dn,
@@ -132,7 +129,8 @@ module ActiveLdap
132
129
  execute(:rename, info,
133
130
  :olddn => _dn,
134
131
  :newrdn => _new_rdn,
135
- :delete_attributes => _delete_old_rdn)
132
+ :delete_attributes => _delete_old_rdn,
133
+ :new_superior => _new_superior)
136
134
  end
137
135
  end
138
136
 
@@ -147,9 +145,13 @@ module ActiveLdap
147
145
  end
148
146
  end
149
147
  message = nil
150
- if result.is_a?(Hash)
148
+ case result
149
+ when Hash
151
150
  message = result[:errorMessage]
152
151
  result = result[:resultCode]
152
+ when Net::LDAP::PDU
153
+ message = result.error_message
154
+ result = result.result_code
153
155
  end
154
156
  unless result.zero?
155
157
  klass = LdapError::ERRORS[result]
@@ -94,7 +94,7 @@ module ActiveLdap
94
94
 
95
95
  # has_many
96
96
  #
97
- # This defines a method for an extension class expand an
97
+ # This defines a method for an extension class expand an
98
98
  # existing multi-element attribute into ActiveLdap objects.
99
99
  # This discards any calls which result in entries that
100
100
  # don't exist in LDAP!
@@ -931,6 +931,17 @@ module ActiveLdap
931
931
  end
932
932
  end
933
933
 
934
+ def clear_removed_attributes_data(removed_attributes)
935
+ return if removed_attributes.empty?
936
+ removed_entry_attribute = EntryAttribute.new(nil, [])
937
+ removed_attributes.each do |attribute|
938
+ removed_entry_attribute.register(attribute)
939
+ end
940
+ @data.reject! do |key, _|
941
+ removed_entry_attribute.exist?(key)
942
+ end
943
+ end
944
+
934
945
  def schema
935
946
  @schema ||= super
936
947
  end
@@ -13,7 +13,7 @@ module ActiveLdap
13
13
  @must = []
14
14
  @may = []
15
15
  @object_classes = []
16
- register(schema.attribute('objectClass'))
16
+ register(schema.attribute('objectClass')) if schema
17
17
  object_classes.each do |objc|
18
18
  # get all attributes for the class
19
19
  object_class = schema.object_class(objc)
@@ -56,6 +56,10 @@ module ActiveLdap
56
56
  end
57
57
  end
58
58
 
59
+ def exist?(name)
60
+ not normalize(name).nil?
61
+ end
62
+
59
63
  def all_names
60
64
  @names.keys + @aliases.keys
61
65
  end
@@ -28,8 +28,12 @@ module ActiveLdap
28
28
  new_classes = target_classes.flatten.compact.uniq
29
29
  assert_object_classes(new_classes)
30
30
  if new_classes.sort != classes.sort
31
+ original_attributes = must + may
31
32
  set_attribute('objectClass', new_classes)
32
33
  clear_object_class_based_cache
34
+ new_attributes = must + may
35
+ removed_attributes = original_attributes - new_attributes
36
+ clear_removed_attributes_data(removed_attributes)
33
37
  end
34
38
  end
35
39
  alias_method(:classes=, :replace_class)
@@ -325,7 +325,12 @@ module ActiveLdap
325
325
  super(id, schema, "ldapSyntaxes")
326
326
  @id = id
327
327
  @name = nil if @name == @id
328
- @validator = Syntaxes[@id]
328
+ @built_in_syntax = Syntaxes[@id]
329
+ end
330
+
331
+ def binary?
332
+ return true if @built_in_syntax and @built_in_syntax.binary?
333
+ binary_transfer_required? or !human_readable?
329
334
  end
330
335
 
331
336
  def binary_transfer_required?
@@ -341,24 +346,24 @@ module ActiveLdap
341
346
  end
342
347
 
343
348
  def validate(value)
344
- if @validator
345
- @validator.validate(value)
349
+ if @built_in_syntax
350
+ @built_in_syntax.validate(value)
346
351
  else
347
352
  nil
348
353
  end
349
354
  end
350
355
 
351
356
  def type_cast(value)
352
- if @validator
353
- @validator.type_cast(value)
357
+ if @built_in_syntax
358
+ @built_in_syntax.type_cast(value)
354
359
  else
355
360
  value
356
361
  end
357
362
  end
358
363
 
359
364
  def normalize_value(value)
360
- if @validator
361
- @validator.normalize_value(value)
365
+ if @built_in_syntax
366
+ @built_in_syntax.normalize_value(value)
362
367
  else
363
368
  value
364
369
  end
@@ -413,8 +418,8 @@ module ActiveLdap
413
418
 
414
419
  # binary?
415
420
  #
416
- # Returns true if the given attribute's syntax
417
- # is X-NOT-HUMAN-READABLE or X-BINARY-TRANSFER-REQUIRED
421
+ # Returns true if the given attribute's syntax is binary syntax,
422
+ # X-NOT-HUMAN-READABLE or X-BINARY-TRANSFER-REQUIRED
418
423
  def binary?
419
424
  @binary
420
425
  end
@@ -503,7 +508,7 @@ module ActiveLdap
503
508
  @syntax = @schema.ldap_syntax(@syntax) if @syntax
504
509
  if @syntax
505
510
  @binary_required = @syntax.binary_transfer_required?
506
- @binary = (@binary_required or !@syntax.human_readable?)
511
+ @binary = @syntax.binary?
507
512
  @derived_syntax = @syntax
508
513
  else
509
514
  @binary_required = false
@@ -20,6 +20,10 @@ module ActiveLdap
20
20
  PRINTABLE_CHARACTER = /[#{printable_character_source}]/ #
21
21
  UNPRINTABLE_CHARACTER = /[^#{printable_character_source}]/ #
22
22
 
23
+ def binary?
24
+ false
25
+ end
26
+
23
27
  def type_cast(value)
24
28
  value
25
29
  end
@@ -366,6 +370,19 @@ module ActiveLdap
366
370
  end
367
371
  end
368
372
 
373
+ class OctetString < Base
374
+ SYNTAXES["1.3.6.1.4.1.1466.115.121.1.40"] = self
375
+
376
+ def binary?
377
+ true
378
+ end
379
+
380
+ private
381
+ def validate_normalized_value(value, original_value)
382
+ nil
383
+ end
384
+ end
385
+
369
386
  class PostalAddress < Base
370
387
  SYNTAXES["1.3.6.1.4.1.1466.115.121.1.41"] = self
371
388
 
@@ -1,3 +1,3 @@
1
1
  module ActiveLdap
2
- VERSION = "4.0.0"
2
+ VERSION = "4.0.1"
3
3
  end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "al-test-utils"
4
+
5
+ class TestEntryAttribute < Test::Unit::TestCase
6
+ include AlTestUtils
7
+
8
+ class TestExist < self
9
+ priority :must
10
+ def test_existence
11
+ schema = ActiveLdap::Base.connection.schema
12
+ object_classes = ["posixAccount"]
13
+ entry_attribute = ActiveLdap::EntryAttribute.new(schema, object_classes)
14
+ assert_true(entry_attribute.exist?("cn"))
15
+ end
16
+
17
+ def test_non_existence
18
+ schema = nil
19
+ object_classes = []
20
+ entry_attribute = ActiveLdap::EntryAttribute.new(schema, object_classes)
21
+ assert_false(entry_attribute.exist?("nonExistence"))
22
+ end
23
+ end
24
+ end
@@ -71,4 +71,23 @@ class TestObjectClass < Test::Unit::TestCase
71
71
  assert_raises(TypeError) {group.add_class(:posixAccount)}
72
72
  end
73
73
  end
74
+
75
+ class TestRemoveClass < self
76
+ def test_clear_existing_attributes
77
+ make_temporary_user(:simple => true) do |user, password|
78
+ user.add_class("inetOrgPerson")
79
+ user.given_name = "new given name"
80
+
81
+ original_attributes = user.attributes
82
+ user.remove_class("inetOrgPerson")
83
+ new_attributes = user.attributes
84
+ original_attributes.delete("objectClass")
85
+ removed_attributes = original_attributes.reject do |key, value|
86
+ value == new_attributes[key]
87
+ end
88
+ assert_equal({"givenName" => "new given name"},
89
+ removed_attributes)
90
+ end
91
+ end
92
+ end
74
93
  end
@@ -6,6 +6,16 @@ class TestValidation < Test::Unit::TestCase
6
6
  include ActiveLdap::Helper
7
7
 
8
8
  priority :must
9
+ def test_octet_string
10
+ make_temporary_user(:simple => true) do |user,|
11
+ utf8_encoded_binary_value = "\xff".force_encoding("UTF-8")
12
+ user.user_password = utf8_encoded_binary_value
13
+ assert_true(user.save)
14
+ assert_equal([], user.errors.full_messages)
15
+ end
16
+ end
17
+
18
+ priority :normal
9
19
  def test_rename_duplicated
10
20
  make_temporary_user(:simple => true) do |user1,|
11
21
  make_temporary_user(:simple => true) do |user2,|
@@ -20,7 +30,6 @@ class TestValidation < Test::Unit::TestCase
20
30
  end
21
31
  end
22
32
 
23
- priority :normal
24
33
  def test_not_show_binary_value
25
34
  make_temporary_user do |user,|
26
35
  user.user_certificate = nil
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.0
4
+ version: 4.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-07-13 00:00:00.000000000 Z
13
+ date: 2013-08-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activemodel
@@ -172,6 +172,22 @@ dependencies:
172
172
  - - ! '>='
173
173
  - !ruby/object:Gem::Version
174
174
  version: '0'
175
+ - !ruby/object:Gem::Dependency
176
+ name: packnga
177
+ requirement: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ type: :development
184
+ prerelease: false
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
175
191
  description: ! " 'ActiveLdap' is a ruby library which provides a clean\n objected
176
192
  oriented interface to the Ruby/LDAP library. It was inspired\n by ActiveRecord.
177
193
  This is not nearly as clean or as flexible as\n ActiveRecord, but it is still
@@ -303,6 +319,7 @@ files:
303
319
  - test/test_dirty.rb
304
320
  - test/test_dn.rb
305
321
  - test/test_entry.rb
322
+ - test/test_entry_attribute.rb
306
323
  - test/test_find.rb
307
324
  - test/test_groupadd.rb
308
325
  - test/test_groupdel.rb
@@ -343,7 +360,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
343
360
  version: '0'
344
361
  segments:
345
362
  - 0
346
- hash: -4416735177306675209
363
+ hash: -4556557570349939659
347
364
  required_rubygems_version: !ruby/object:Gem::Requirement
348
365
  none: false
349
366
  requirements:
@@ -352,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
369
  version: '0'
353
370
  segments:
354
371
  - 0
355
- hash: -4416735177306675209
372
+ hash: -4556557570349939659
356
373
  requirements: []
357
374
  rubyforge_project: ruby-activeldap
358
375
  rubygems_version: 1.8.23
@@ -381,6 +398,7 @@ test_files:
381
398
  - test/test_dirty.rb
382
399
  - test/test_dn.rb
383
400
  - test/test_entry.rb
401
+ - test/test_entry_attribute.rb
384
402
  - test/test_find.rb
385
403
  - test/test_groupadd.rb
386
404
  - test/test_groupdel.rb