activeldap 1.2.4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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