activeldap 1.2.4 → 3.1.0

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 (45) hide show
  1. data/Gemfile +18 -0
  2. data/LICENSE +2 -1
  3. data/README.textile +137 -0
  4. data/doc/text/development.textile +50 -0
  5. data/{CHANGES → doc/text/news.textile} +256 -237
  6. data/doc/text/rails.textile +144 -0
  7. data/doc/text/tutorial.textile +1005 -0
  8. data/lib/active_ldap/adapter/base.rb +5 -3
  9. data/lib/active_ldap/adapter/net_ldap_ext.rb +1 -1
  10. data/lib/active_ldap/associations.rb +6 -2
  11. data/lib/active_ldap/base.rb +16 -71
  12. data/lib/active_ldap/callbacks.rb +52 -33
  13. data/lib/active_ldap/configuration.rb +2 -2
  14. data/lib/active_ldap/get_text/parser.rb +2 -2
  15. data/lib/active_ldap/human_readable.rb +5 -4
  16. data/lib/active_ldap/log_subscriber.rb +50 -0
  17. data/lib/active_ldap/persistence.rb +65 -0
  18. data/lib/active_ldap/railtie.rb +40 -0
  19. data/lib/active_ldap/railties/controller_runtime.rb +48 -0
  20. data/lib/active_ldap/user_password.rb +1 -0
  21. data/lib/active_ldap/validations.rb +34 -72
  22. data/lib/active_ldap.rb +13 -912
  23. data/{rails_generators/model_active_ldap → lib/rails/generators/active_ldap/model}/USAGE +2 -1
  24. data/lib/rails/generators/active_ldap/model/model_generator.rb +47 -0
  25. data/{rails_generators/model_active_ldap → lib/rails/generators/active_ldap/model}/templates/model_active_ldap.rb +0 -0
  26. data/lib/rails/generators/active_ldap/scaffold/scaffold_generator.rb +14 -0
  27. data/{rails_generators/scaffold_active_ldap → lib/rails/generators/active_ldap/scaffold}/templates/ldap.yml +1 -0
  28. data/test/test_base.rb +9 -0
  29. data/test/test_callback.rb +2 -6
  30. data/test/test_connection.rb +2 -2
  31. data/test/test_user.rb +2 -2
  32. data/test/test_validation.rb +11 -11
  33. metadata +165 -106
  34. data/README +0 -155
  35. data/Rakefile +0 -133
  36. data/rails/README +0 -54
  37. data/rails/init.rb +0 -33
  38. data/rails_generators/model_active_ldap/model_active_ldap_generator.rb +0 -69
  39. data/rails_generators/model_active_ldap/templates/unit_test.rb +0 -8
  40. data/rails_generators/scaffold_active_ldap/scaffold_active_ldap_generator.rb +0 -7
  41. data/test/al-test-utils.rb +0 -439
  42. data/test/command.rb +0 -112
  43. data/test/config.yaml.sample +0 -6
  44. data/test/fixtures/lower_case_object_class_schema.rb +0 -802
  45. data/test/run-test.rb +0 -44
@@ -33,6 +33,7 @@ module ActiveLdap
33
33
  VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
34
34
  instance_variable_set("@#{name}", configuration[name])
35
35
  end
36
+ @instrumenter = ActiveSupport::Notifications.instrumenter
36
37
  end
37
38
 
38
39
  def reset_runtime
@@ -658,9 +659,10 @@ module ActiveLdap
658
659
  def log(name, info=nil)
659
660
  if block_given?
660
661
  result = nil
661
- seconds = Benchmark.realtime {result = yield}
662
- @runtime += seconds
663
- log_info(name, seconds, info)
662
+ @instrumenter.instrument(
663
+ "log_info.active_ldap",
664
+ :info => info,
665
+ :name => name) { result = yield }
664
666
  result
665
667
  else
666
668
  log_info(name, 0, info)
@@ -1,4 +1,4 @@
1
- require_library_or_gem 'net/ldap'
1
+ require 'net/ldap'
2
2
 
3
3
  module Net
4
4
  class LDAP
@@ -13,8 +13,8 @@ module ActiveLdap
13
13
  def self.append_features(base)
14
14
  super
15
15
  base.extend(ClassMethods)
16
- base.class_inheritable_array(:associations)
17
- base.associations = []
16
+ base.class_attribute(:associations)
17
+ base.associations ||= []
18
18
  end
19
19
 
20
20
  module ClassMethods
@@ -198,4 +198,8 @@ module ActiveLdap
198
198
  end
199
199
  end
200
200
  end
201
+
202
+ module Association
203
+ autoload :Children, 'active_ldap/association/children'
204
+ end
201
205
  end
@@ -1,6 +1,7 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # === activeldap - an OO-interface to LDAP objects inspired by ActiveRecord
2
3
  # Author: Will Drewry <will@alum.bu.edu>
3
- # License: See LICENSE and COPYING.txt
4
+ # License: See LICENSE and COPYING
4
5
  # Copyright 2004-2006 Will Drewry <will@alum.bu.edu>
5
6
  # Some portions Copyright 2006 Google Inc
6
7
  #
@@ -223,6 +224,12 @@ module ActiveLdap
223
224
  end
224
225
 
225
226
  class EntryInvalid < Error
227
+ attr_reader :entry
228
+ def initialize(entry)
229
+ @entry = entry
230
+ errors = @entry.errors.full_messages.join(", ")
231
+ super(errors)
232
+ end
226
233
  end
227
234
 
228
235
  class OperationNotPermitted < Error
@@ -528,14 +535,6 @@ module ActiveLdap
528
535
  rescue
529
536
  [self]
530
537
  end
531
- if ActiveRecord::Base.respond_to?(:self_and_descendents_from_active_record)
532
- # ActiveRecord 2.2.2 has a typo. :<
533
- alias_method(:self_and_descendents_from_active_record,
534
- :self_and_descendants_from_active_ldap)
535
- else
536
- alias_method(:self_and_descendants_from_active_record,
537
- :self_and_descendants_from_active_ldap)
538
- end
539
538
 
540
539
  def human_name(options={})
541
540
  defaults = self_and_descendants_from_active_ldap.collect do |klass|
@@ -552,7 +551,7 @@ module ActiveLdap
552
551
 
553
552
  private
554
553
  def inspect_attributes(attributes)
555
- inspected_attribute_names = {}
554
+ inspected_attribute_names = {}
556
555
  attributes.collect do |attribute|
557
556
  if inspected_attribute_names.has_key?(attribute.name)
558
557
  nil
@@ -778,6 +777,13 @@ module ActiveLdap
778
777
  id
779
778
  end
780
779
 
780
+ # Returns this entity’s dn wrapped in an Array or nil if the entity' s dn is not set.
781
+ def to_key
782
+ [dn]
783
+ rescue DistinguishedNameNotSetError
784
+ nil
785
+ end
786
+
781
787
  def dn=(value)
782
788
  set_attribute(dn_attribute_with_fallback, value)
783
789
  end
@@ -794,33 +800,6 @@ module ActiveLdap
794
800
  self.class.default_search_attribute
795
801
  end
796
802
 
797
- # destroy
798
- #
799
- # Delete this entry from LDAP
800
- def destroy
801
- self.class.delete(dn)
802
- @new_entry = true
803
- end
804
-
805
- def delete(options={})
806
- super(dn, options)
807
- end
808
-
809
- # save
810
- #
811
- # Save and validate this object into LDAP
812
- # either adding or replacing attributes
813
- # TODO: Relative DN support
814
- def save
815
- create_or_update
816
- end
817
-
818
- def save!
819
- unless create_or_update
820
- raise EntryNotSaved, _("entry %s can't be saved") % dn
821
- end
822
- end
823
-
824
803
  # method_missing
825
804
  #
826
805
  # If a given method matches an attribute or an attribute alias
@@ -1528,10 +1507,6 @@ module ActiveLdap
1528
1507
  attributes
1529
1508
  end
1530
1509
 
1531
- def create_or_update
1532
- new_entry? ? create : update
1533
- end
1534
-
1535
1510
  def prepare_data_for_saving
1536
1511
  # Expand subtypes to real ldap_data attributes
1537
1512
  # We can't reuse @ldap_data because an exception would leave
@@ -1559,35 +1534,5 @@ module ActiveLdap
1559
1534
 
1560
1535
  success
1561
1536
  end
1562
-
1563
- def create
1564
- prepare_data_for_saving do |data, ldap_data|
1565
- attributes = collect_all_attributes(data)
1566
- add_entry(dn, attributes)
1567
- @new_entry = false
1568
- true
1569
- end
1570
- end
1571
-
1572
- def update
1573
- prepare_data_for_saving do |data, ldap_data|
1574
- new_dn_value, attributes = collect_modified_attributes(ldap_data, data)
1575
- modify_entry(@original_dn, attributes)
1576
- if new_dn_value
1577
- old_dn_base = DN.parse(@original_dn).parent
1578
- new_dn_base = dn.clone.parent
1579
- if old_dn_base == new_dn_base
1580
- new_superior = nil
1581
- else
1582
- new_superior = new_dn_base
1583
- end
1584
- modify_rdn_entry(@original_dn,
1585
- "#{dn_attribute}=#{DN.escape_value(new_dn_value)}",
1586
- true,
1587
- new_superior)
1588
- end
1589
- true
1590
- end
1591
- end
1592
1537
  end # Base
1593
1538
  end # ActiveLdap
@@ -1,25 +1,34 @@
1
- require 'active_record/callbacks'
1
+ require 'active_support/core_ext/array/wrap'
2
2
 
3
3
  module ActiveLdap
4
4
  module Callbacks
5
- def self.append_features(base)
6
- super
7
-
8
- base.class_eval do
9
- include ActiveRecord::Callbacks
10
-
11
- unless respond_to?(:instantiate_with_callbacks)
12
- extend ClassMethods
13
- class << self
14
- alias_method_chain :instantiate, :callbacks
15
- end
16
- alias_method_chain :initialize, :callbacks
17
- end
5
+ extend ActiveSupport::Concern
6
+
7
+ CALLBACKS = [
8
+ :after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
9
+ :before_save, :around_save, :after_save, :before_create, :around_create,
10
+ :after_create, :before_update, :around_update, :after_update,
11
+ :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
12
+ ]
13
+
14
+ included do
15
+ extend ActiveModel::Callbacks
16
+ include ActiveModel::Validations::Callbacks
17
+
18
+ define_model_callbacks :initialize, :find, :touch, :only => :after
19
+ define_model_callbacks :save, :create, :update, :destroy
20
+
21
+ class << self
22
+ alias_method_chain :instantiate, :callbacks
23
+ end
24
+ end
18
25
 
19
- def callback(method)
20
- super
21
- rescue ActiveRecord::ActiveRecordError
22
- raise Error, $!.message
26
+ module ClassMethods
27
+ def method_added(meth)
28
+ super
29
+ if CALLBACKS.include?(meth.to_sym)
30
+ ActiveSupport::Deprecation.warn("Base##{meth} has been deprecated, please use Base.#{meth} :method instead", caller[0,1])
31
+ send(meth.to_sym, meth.to_sym)
23
32
  end
24
33
  end
25
34
  end
@@ -27,26 +36,36 @@ module ActiveLdap
27
36
  module ClassMethods
28
37
  def instantiate_with_callbacks(record)
29
38
  object = instantiate_without_callbacks(record)
39
+ object.send(:_run_find_callbacks)
40
+ object.send(:_run_initialize_callbacks)
41
+ object
42
+ end
43
+ end
30
44
 
31
- if object.respond_to_without_attributes?(:after_find)
32
- object.send(:callback, :after_find)
33
- end
45
+ def initialize(*) #:nodoc:
46
+ run_callbacks(:initialize) { super }
47
+ end
34
48
 
35
- if object.respond_to_without_attributes?(:after_initialize)
36
- object.send(:callback, :after_initialize)
37
- end
49
+ def destroy #:nodoc:
50
+ run_callbacks(:destroy) { super }
51
+ end
38
52
 
39
- object
40
- end
53
+ def touch(*) #:nodoc:
54
+ run_callbacks(:touch) { super }
41
55
  end
42
56
 
43
- def initialize_with_callbacks(attributes = nil) #:nodoc:
44
- initialize_without_callbacks(attributes)
45
- result = yield self if block_given?
46
- if respond_to_without_attributes?(:after_initialize)
47
- callback(:after_initialize)
48
- end
49
- result
57
+ private
58
+
59
+ def create_or_update #:nodoc:
60
+ run_callbacks(:save) { super }
61
+ end
62
+
63
+ def create #:nodoc:
64
+ run_callbacks(:create) { super }
65
+ end
66
+
67
+ def update(*) #:nodoc:
68
+ run_callbacks(:update) { super }
50
69
  end
51
70
  end
52
71
  end
@@ -57,8 +57,8 @@ module ActiveLdap
57
57
  if config.nil?
58
58
  if defined?(LDAP_ENV)
59
59
  config = LDAP_ENV
60
- elsif defined?(RAILS_ENV)
61
- config = RAILS_ENV
60
+ elsif defined?(Rails)
61
+ config = Rails.env
62
62
  else
63
63
  config = {}
64
64
  end
@@ -81,8 +81,8 @@ module ActiveLdap
81
81
  configuration = ActiveLdap::Base.configurations[configuration]
82
82
  end
83
83
  end
84
- if Object.const_defined?(:RAILS_ENV)
85
- rails_configuration = ActiveLdap::Base.configurations[RAILS_ENV]
84
+ if defined?(Rails)
85
+ rails_configuration = ActiveLdap::Base.configurations[Rails.env]
86
86
  configuration = rails_configuration.merge(configuration)
87
87
  end
88
88
  configuration = configuration.symbolize_keys
@@ -6,7 +6,8 @@ module ActiveLdap
6
6
  end
7
7
 
8
8
  module ClassMethods
9
- def human_attribute_name(attribute_or_name)
9
+ def human_attribute_name(attribute_or_name, options={})
10
+ logger.warn("options was ignored.") unless options.empty?
10
11
  msgid = human_attribute_name_msgid(attribute_or_name)
11
12
  msgid ||= human_attribute_name_with_gettext(attribute_or_name)
12
13
  s_(msgid)
@@ -16,10 +17,10 @@ module ActiveLdap
16
17
  if attribute_or_name.is_a?(Schema::Attribute)
17
18
  name = attribute_or_name.name
18
19
  else
19
- attribute = schema.attribute(attribute_or_name)
20
+ attribute = schema.attribute(attribute_or_name.to_s)
20
21
  return nil if attribute.id.nil?
21
22
  if attribute.name == attribute_or_name or
22
- attribute.aliases.include?(attribute_or_name)
23
+ attribute.aliases.include?(attribute_or_name.to_s)
23
24
  name = attribute_or_name
24
25
  else
25
26
  return nil
@@ -38,7 +39,7 @@ module ActiveLdap
38
39
  if attribute_or_name.is_a?(Schema::Attribute)
39
40
  attribute = attribute_or_name
40
41
  else
41
- attribute = schema.attribute(attribute_or_name)
42
+ attribute = schema.attribute(attribute_or_name.to_s)
42
43
  return nil if attribute.nil?
43
44
  end
44
45
  description = attribute.description
@@ -0,0 +1,50 @@
1
+ module ActiveLdap
2
+ class LogSubscriber < ActiveSupport::LogSubscriber
3
+ def self.runtime=(value)
4
+ Thread.current["active_ldap_runtime"] = value
5
+ end
6
+
7
+ def self.runtime
8
+ Thread.current["active_ldap_runtime"] ||= 0
9
+ end
10
+
11
+ def self.reset_runtime
12
+ rt, self.runtime = runtime, 0
13
+ rt
14
+ end
15
+
16
+ def initialize
17
+ super
18
+ @odd_or_even = false
19
+ end
20
+
21
+ def log_info(event)
22
+ self.class.runtime += event.duration
23
+ return unless logger.debug?
24
+
25
+ payload = event.payload
26
+ name = 'LDAP: %s (%.1fms)' % [payload[:name], event.duration]
27
+ info = payload[:info].inspect
28
+
29
+ if odd?
30
+ name_color, dump_color = "4;36;1", "0;1"
31
+ else
32
+ name_color, dump_color = "4;35;1", "0"
33
+ end
34
+
35
+ debug " \e[#{name_color}m#{name}\e[0m: \e[#{dump_color}m#{info}\e[0m"
36
+ end
37
+
38
+ def odd?
39
+ @odd_or_even = !@odd_or_even
40
+ end
41
+
42
+ def logger
43
+ ActiveLdap::Base.logger
44
+ end
45
+ end
46
+ end
47
+
48
+ ActiveLdap::LogSubscriber.attach_to :active_ldap
49
+
50
+
@@ -0,0 +1,65 @@
1
+ module ActiveLdap
2
+ module Persistence
3
+
4
+ # destroy
5
+ #
6
+ # Delete this entry from LDAP
7
+ def destroy
8
+ self.class.delete(dn)
9
+ @new_entry = true
10
+ end
11
+
12
+ def delete(options={})
13
+ super(dn, options)
14
+ end
15
+
16
+ # save
17
+ #
18
+ # Save and validate this object into LDAP
19
+ # either adding or replacing attributes
20
+ # TODO: Relative DN support
21
+ def save(*)
22
+ create_or_update
23
+ end
24
+
25
+ def save!(*)
26
+ unless create_or_update
27
+ raise EntryNotSaved, _("entry %s can't be saved") % dn
28
+ end
29
+ end
30
+
31
+ def create_or_update
32
+ new_entry? ? create : update
33
+ end
34
+
35
+ def create
36
+ prepare_data_for_saving do |data, ldap_data|
37
+ attributes = collect_all_attributes(data)
38
+ add_entry(dn, attributes)
39
+ @new_entry = false
40
+ true
41
+ end
42
+ end
43
+
44
+ def update
45
+ prepare_data_for_saving do |data, ldap_data|
46
+ new_dn_value, attributes = collect_modified_attributes(ldap_data, data)
47
+ modify_entry(@original_dn, attributes)
48
+ if new_dn_value
49
+ old_dn_base = DN.parse(@original_dn).parent
50
+ new_dn_base = dn.clone.parent
51
+ if old_dn_base == new_dn_base
52
+ new_superior = nil
53
+ else
54
+ new_superior = new_dn_base
55
+ end
56
+ modify_rdn_entry(@original_dn,
57
+ "#{dn_attribute}=#{DN.escape_value(new_dn_value)}",
58
+ true,
59
+ new_superior)
60
+ end
61
+ true
62
+ end
63
+ end
64
+ end # Persistence
65
+ end # ActiveLdap
@@ -0,0 +1,40 @@
1
+ require 'active_ldap'
2
+ require 'rails'
3
+
4
+ module ActiveLdap
5
+ class Railtie < Rails::Railtie
6
+ config.app_generators.orm :active_ldap
7
+
8
+ initializer "active_ldap.setup_connection" do
9
+ ldap_configuration_file = Rails.root.join('config', 'ldap.yml')
10
+ if File.exist?(ldap_configuration_file)
11
+ configurations = YAML::load(ERB.new(IO.read(ldap_configuration_file)).result)
12
+ ActiveLdap::Base.configurations = configurations
13
+ ActiveLdap::Base.setup_connection
14
+ else
15
+ ActiveLdap::Base.class_eval do
16
+ format =_("You should run 'rails generator active_ldap:scaffold' to make %s.")
17
+ logger.error(format % ldap_configuration_file)
18
+ end
19
+ end
20
+ end
21
+
22
+ initializer "active_ldap.logger", :before => "active_ldap.setup_connection" do
23
+ ActiveLdap::Base.logger ||= ::Rails.logger
24
+ end
25
+
26
+ initializer "active_ldap.action_view_helper" do
27
+ class ::ActionView::Base
28
+ include ActiveLdap::Helper
29
+ end
30
+ end
31
+
32
+ # Expose Ldap runtime to controller for logging.
33
+ initializer "active_ldap.log_runtime" do |app|
34
+ require "active_ldap/railties/controller_runtime"
35
+ ActiveSupport.on_load(:action_controller) do
36
+ include ActiveLdap::Railties::ControllerRuntime
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,48 @@
1
+ require 'active_support/core_ext/module/attr_internal'
2
+ require 'active_ldap/log_subscriber'
3
+
4
+ module ActiveLdap
5
+ module Railties
6
+ module ControllerRuntime #:nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ protected
10
+
11
+ attr_internal :ldap_runtime
12
+
13
+ def process_action(action, *args)
14
+ # We also need to reset the runtime before each action
15
+ # because of queries in middleware or in cases we are streaming
16
+ # and it won't be cleaned up by the method below.
17
+ ActiveLdap::LogSubscriber.reset_runtime
18
+ super
19
+ end
20
+
21
+ def cleanup_view_runtime
22
+ if ActiveLdap::Base.connected?
23
+ ldap_rt_before_render = ActiveLdap::LogSubscriber.reset_runtime
24
+ runtime = super
25
+ ldap_rt_after_render = ActiveLdap::LogSubscriber.reset_runtime
26
+ self.ldap_runtime = ldap_rt_before_render + ldap_rt_after_render
27
+ runtime - ldap_rt_after_render
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def append_info_to_payload(payload)
34
+ super
35
+ payload[:ldap_runtime] = ldap_runtime
36
+ end
37
+
38
+ module ClassMethods
39
+ def log_process_action(payload)
40
+ messages, ldap_runtime = super, payload[:ldap_runtime]
41
+ messages << ("ActiveLdap: %.1fms" % ldap_runtime.to_f) if ldap_runtime
42
+ messages
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -1,4 +1,5 @@
1
1
  require 'English'
2
+ require 'base64'
2
3
  require 'digest/md5'
3
4
  require 'digest/sha1'
4
5
 
@@ -1,81 +1,29 @@
1
1
  module ActiveLdap
2
2
  module Validations
3
- def self.append_features(base)
4
- super
5
-
6
- base.class_eval do
7
- alias_method :new_record?, :new_entry?
8
- class << self
9
- alias_method :human_attribute_name_active_ldap,
10
- :human_attribute_name
11
- end
12
- include ActiveRecord::Validations
13
- class << self
14
- alias_method :human_attribute_name_active_record,
15
- :human_attribute_name
16
- alias_method :human_attribute_name,
17
- :human_attribute_name_active_ldap
18
- unless method_defined?(:human_attribute_name_with_gettext)
19
- def human_attribute_name_with_gettext(attribute_key_name)
20
- s_("#{self}|#{attribute_key_name.humanize}")
21
- end
3
+ extend ActiveSupport::Concern
4
+ include ActiveModel::Validations
5
+
6
+ included do
7
+ alias_method :new_record?, :new_entry?
8
+ class << self
9
+ unless method_defined?(:human_attribute_name_with_gettext)
10
+ def human_attribute_name_with_gettext(attribute_key_name, options={})
11
+ logger.warn("options was ignored.") unless options.empty?
12
+ s_("#{self}|#{attribute_key_name.to_s.humanize}")
22
13
  end
23
14
  end
15
+ end
24
16
 
25
- class_local_attr_accessor true, :validation_skip_attributes
26
- remove_method :validation_skip_attributes
27
- self.validation_skip_attributes = []
28
-
29
- # Workaround for GetText's ugly implementation
30
- begin
31
- instance_method(:save_without_validation)
32
- rescue NameError
33
- alias_method_chain :save, :validation
34
- alias_method_chain :save!, :validation
35
- alias_method_chain :update_attribute, :validation_skipping
36
- end
37
-
38
- validate_on_create :validate_duplicated_dn_creation
39
- validate_on_update :validate_duplicated_dn_rename
40
- validate :validate_dn
41
- validate :validate_excluded_classes
42
- validate :validate_required_ldap_values
43
- validate :validate_ldap_values
44
-
45
- class << self
46
- if method_defined?(:evaluate_condition)
47
- def evaluate_condition_with_active_ldap_support(condition, entry)
48
- evaluate_condition_without_active_ldap_support(condition, entry)
49
- rescue ActiveRecord::ActiveRecordError
50
- raise Error, $!.message
51
- end
52
- alias_method_chain :evaluate_condition, :active_ldap_support
53
- end
54
- end
55
-
56
- def save_with_active_ldap_support!
57
- save_without_active_ldap_support!
58
- rescue ActiveRecord::RecordInvalid
59
- raise EntryInvalid, $!.message
60
- end
61
- alias_method_chain :save!, :active_ldap_support
17
+ class_local_attr_accessor true, :validation_skip_attributes
18
+ remove_method :validation_skip_attributes
19
+ self.validation_skip_attributes = []
62
20
 
63
- private
64
- def run_validations_with_active_ldap_support(validation_method)
65
- run_validations_without_active_ldap_support(validation_method)
66
- rescue ActiveRecord::ActiveRecordError
67
- raise Error, $!.message
68
- end
69
- if private_method_defined?(:run_validations)
70
- alias_method_chain :run_validations, :active_ldap_support
71
- else
72
- alias_method(:run_callbacks_with_active_ldap_support,
73
- :run_validations_with_active_ldap_support)
74
- alias_method_chain :run_callbacks, :active_ldap_support
75
- alias_method(:run_validations_without_active_ldap_support,
76
- :run_callbacks_without_active_ldap_support)
77
- end
78
- end
21
+ validate :validate_duplicated_dn_creation, :on => :create
22
+ validate :validate_duplicated_dn_rename, :on => :update
23
+ validate :validate_dn
24
+ validate :validate_excluded_classes
25
+ validate :validate_required_ldap_values
26
+ validate :validate_ldap_values
79
27
  end
80
28
 
81
29
  def validation_skip_attributes
@@ -86,6 +34,20 @@ module ActiveLdap
86
34
  @validation_skip_attributes = attributes
87
35
  end
88
36
 
37
+ def valid?(context = nil)
38
+ context ||= (new_entry? ? :create : :update)
39
+ output = super(context)
40
+ errors.empty? && output
41
+ end
42
+
43
+ def save(*)
44
+ valid? ? super: false
45
+ end
46
+
47
+ def save!(*)
48
+ valid? ? super: raise(EntryInvalid.new(self))
49
+ end
50
+
89
51
  private
90
52
  def format_validation_message(format, parameters)
91
53
  format % parameters