Class: ActiveLdap::Base
- Inherits:
-
Object
- Object
- ActiveLdap::Base
- Includes:
- GetTextSupport, Enumerable, Reloadable::Deprecated, Reloadable::Subclasses
- Defined in:
- lib/active_ldap/base.rb
Overview
Base
Base is the primary class which contains all of the core ActiveLdap functionality. It is meant to only ever be subclassed by extension classes.
Constant Summary collapse
- VALID_LDAP_MAPPING_OPTIONS =
[:dn_attribute, :prefix, :scope, :classes, :recommended_classes, :excluded_classes, :sort_by, :order]
- @@colorize_logging =
true
- @@configurations =
{}
Class Method Summary collapse
-
.base ⇒ Object
Base.base.
- .base=(value) ⇒ Object
- .base_class ⇒ Object
- .base_inheritable ⇒ Object
- .base_without_parsed_cache_clear= ⇒ Object
- .class_local_attr_accessor(search_ancestors, *syms) ⇒ Object
- .create(attributes = nil, &block) ⇒ Object
- .default_search_attribute ⇒ Object
-
.establish_connection(config = nil) ⇒ Object
Connect and bind to LDAP creating a class variable for use by all ActiveLdap objects.
-
.ldap_mapping(options = {}) ⇒ Object
This class function is used to setup all mappings between the subclass and ldap for use in activeldap.
- .parsed_base ⇒ Object
- .scope=(scope) ⇒ Object
- .scope_without_validation= ⇒ Object
- .validate_scope(scope) ⇒ Object
Instance Method Summary collapse
-
#==(comparison_object) ⇒ Object
Returns true if the
comparison_object
is the same object, or is of the same type and has the same dn. - #[](name, force_array = false) ⇒ Object
- #[]=(name, value) ⇒ Object
-
#attribute_names(normalize = false) ⇒ Object
attributes.
- #attribute_present?(name) ⇒ Boolean
-
#attributes ⇒ Object
This returns the key value pairs in @data with all values cloned.
-
#attributes=(new_attributes) ⇒ Object
This allows a bulk update to the attributes of a record without forcing an immediate save or validation.
- #base ⇒ Object
- #base=(object_local_base) ⇒ Object
- #base_of_class ⇒ Object
- #bind(config_or_password = {}, config_or_ignore = nil, &block) ⇒ Object
- #clear_connection_based_cache ⇒ Object
- #clear_object_class_based_cache ⇒ Object
- #default_search_attribute ⇒ Object
- #delete(options = {}) ⇒ Object
-
#destroy ⇒ Object
destroy.
-
#dn ⇒ Object
dn.
- #dn=(value) ⇒ Object (also: #id=)
- #dn_attribute ⇒ Object
- #dn_attribute_of_class ⇒ Object
- #each ⇒ Object
-
#eql?(comparison_object) ⇒ Boolean
Delegates to ==.
-
#exist? ⇒ Boolean
(also: #exists?)
exist?.
-
#hash ⇒ Object
Delegates to id in order to allow two records of the same type and id to work with something like: [ User.find(“a”), User.find(“b”), User.find(“c”) ] & [ User.find(“a”), User.find(“d”) ] # => [ User.find(“a”) ].
- #have_attribute?(name, except = []) ⇒ Boolean (also: #has_attribute?)
- #id ⇒ Object
-
#initialize(attributes = nil) {|_self| ... } ⇒ Base
constructor
new.
- #inspect ⇒ Object
- #may ⇒ Object
-
#method_missing(name, *args, &block) ⇒ Object
method_missing.
-
#methods(inherited_too = true) ⇒ Object
Add available attributes to the methods.
- #must ⇒ Object
-
#new_entry? ⇒ Boolean
new_entry?.
- #pretty_print(q) ⇒ Object
- #reload ⇒ Object
- #respond_to?(name, include_priv = false) ⇒ Boolean
- #respond_to_without_attributes? ⇒ Object
-
#save ⇒ Object
save.
- #save! ⇒ Object
- #schema ⇒ Object
- #scope ⇒ Object
- #scope=(scope) ⇒ Object
- #scope_of_class ⇒ Object
- #to_ldif ⇒ Object
- #to_param ⇒ Object
- #to_xml(options = {}) ⇒ Object
-
#update_attribute(name, value) ⇒ Object
Updates a given attribute and saves immediately.
-
#update_attributes(attrs) ⇒ Object
This performs a bulk update of attributes and immediately calls #save.
- #update_attributes!(attrs) ⇒ Object
Methods included from GetTextSupport
Constructor Details
#initialize(attributes = nil) {|_self| ... } ⇒ Base
new
Creates a new instance of Base initializing all class and all initialization. Defines local defaults. See examples If multiple values exist for dn_attribute, the first one put here will be authoritative
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/active_ldap/base.rb', line 495 def initialize(attributes=nil) init_base @new_entry = true initial_classes = required_classes | recommended_classes case attributes when nil self.classes = initial_classes when String, Array, DN self.classes = initial_classes self.dn = attributes when Hash classes, attributes = extract_object_class(attributes) self.classes = classes | initial_classes normalized_attributes = {} attributes.each do |key, value| real_key = to_real_attribute_name(key) || key normalized_attributes[real_key] = value end self.dn = normalized_attributes.delete(dn_attribute) self.attributes = normalized_attributes else format = _("'%s' must be either nil, DN value as ActiveLdap::DN, " \ "String or Array or attributes as Hash") raise ArgumentError, format % attributes.inspect end yield self if block_given? assert_dn_attribute end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
method_missing
If a given method matches an attribute or an attribute alias then call the appropriate method. TODO: Determine if it would be better to define each allowed method
using class_eval instead of using method_missing. This would
give tab completion in irb.
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 |
# File 'lib/active_ldap/base.rb', line 650 def method_missing(name, *args, &block) key = name.to_s case key when /=$/ real_key = $PREMATCH if have_attribute?(real_key, ['objectClass']) if args.size != 1 raise ArgumentError, _("wrong number of arguments (%d for 1)") % args.size end return set_attribute(real_key, *args, &block) end when /(?:(_before_type_cast)|(\?))?$/ real_key = $PREMATCH before_type_cast = !$1.nil? query = !$2.nil? if have_attribute?(real_key, ['objectClass']) if args.size > 1 raise ArgumentError, _("wrong number of arguments (%d for 1)") % args.size end if before_type_cast return get_attribute_before_type_cast(real_key, *args)[1] elsif query return get_attribute_as_query(real_key, *args) else return get_attribute(real_key, *args) end end end super end |
Class Method Details
.base ⇒ Object
Base.base
This method when included into Base provides an inheritable, overwritable configuration setting
This should be a string with the base of the ldap server such as ‘dc=example,dc=com’, and it should be overwritten by including configuration.rb into this class. When subclassing, the specified prefix will be concatenated.
378 379 380 381 382 383 384 385 |
# File 'lib/active_ldap/base.rb', line 378 def base _base = base_inheritable _base = configuration[:base] if _base.nil? and configuration _base ||= base_inheritable(true) [prefix, _base].find_all do |component| !component.blank? end.join(",") end |
.base=(value) ⇒ Object
388 389 390 391 |
# File 'lib/active_ldap/base.rb', line 388 def base=(value) self.base_without_parsed_cache_clear = value @parsed_base = nil end |
.base_class ⇒ Object
410 411 412 413 414 415 416 |
# File 'lib/active_ldap/base.rb', line 410 def base_class if self == Base or superclass == Base self else superclass.base_class end end |
.base_inheritable ⇒ Object
367 |
# File 'lib/active_ldap/base.rb', line 367 alias_method :base_inheritable, :base |
.base_without_parsed_cache_clear= ⇒ Object
387 |
# File 'lib/active_ldap/base.rb', line 387 alias_method :base_without_parsed_cache_clear=, :base= |
.class_local_attr_accessor(search_ancestors, *syms) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/active_ldap/base.rb', line 260 def self.class_local_attr_accessor(search_ancestors, *syms) syms.flatten.each do |sym| class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym}(search_superclasses=#{search_ancestors}) @#{sym} ||= nil return @#{sym} if @#{sym} if search_superclasses target = superclass value = nil loop do break nil unless target.respond_to?(:#{sym}) value = target.#{sym} break if value target = target.superclass end value else nil end end def #{sym}; self.class.#{sym}; end def self.#{sym}=(value); @#{sym} = value; end def #{sym}=(value); self.class.#{sym} = value; end EOS end end |
.create(attributes = nil, &block) ⇒ Object
334 335 336 337 338 339 340 341 342 |
# File 'lib/active_ldap/base.rb', line 334 def create(attributes=nil, &block) if attributes.is_a?(Array) attributes.collect {|attrs| create(attrs, &block)} else object = new(attributes, &block) object.save object end end |
.default_search_attribute ⇒ Object
418 419 420 |
# File 'lib/active_ldap/base.rb', line 418 def default_search_attribute dn_attribute end |
.establish_connection(config = nil) ⇒ Object
Connect and bind to LDAP creating a class variable for use by all ActiveLdap objects.
config
config
must be a hash that may contain any of the following fields: :password_block, :logger, :host, :port, :base, :bind_dn, :try_sasl, :allow_anonymous :bind_dn specifies the DN to bind with. :password_block specifies a Proc object that will yield a String to
be used as the password when called.
:logger specifies a logger object (Logger, Log4r::Logger and s on) :host sets the LDAP server hostname :port sets the LDAP server port :base overwrites Base.base - this affects EVERYTHING :try_sasl indicates that a SASL bind should be attempted when binding
to the server (default: false)
:sasl_mechanisms is an array of SASL mechanism to try
(default: ["GSSAPI", "CRAM-MD5", "EXTERNAL"])
:allow_anonymous indicates that a true anonymous bind is allowed when
trying to bind to the server (default: true)
:retries - indicates the number of attempts to reconnect that will be
undertaken when a stale connection occurs. -1 means infinite.
:sasl_quiet - if true, sets @sasl_quiet on the Ruby/LDAP connection :method - whether to use :ssl, :tls, or :plain (unencrypted) :retry_wait - seconds to wait before retrying a connection :scope - dictates how to find objects. ONELEVEL by default to
avoid dn_attr collisions across OUs. Think before changing.
:timeout - time in seconds - defaults to disabled. This CAN interrupt
search() requests. Be warned.
:retry_on_timeout - whether to reconnect when timeouts occur. Defaults
to true
See lib/configuration.rb for defaults for each option
328 329 330 331 332 |
# File 'lib/active_ldap/base.rb', line 328 def establish_connection(config=nil) super ensure_logger nil end |
.ldap_mapping(options = {}) ⇒ Object
This class function is used to setup all mappings between the subclass and ldap for use in activeldap
Example:
ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=People',
:classes => ['top', 'posixAccount'],
:scope => :sub
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/active_ldap/base.rb', line 351 def ldap_mapping(={}) = .symbolize_keys () self.dn_attribute = [:dn_attribute] || default_dn_attribute self.prefix = [:prefix] || default_prefix self.scope = [:scope] self.required_classes = [:classes] self.recommended_classes = [:recommended_classes] self.excluded_classes = [:excluded_classes] self.sort_by = [:sort_by] self.order = [:order] public_class_method :new end |
.parsed_base ⇒ Object
393 394 395 |
# File 'lib/active_ldap/base.rb', line 393 def parsed_base @parsed_base ||= DN.parse(base) end |
.scope=(scope) ⇒ Object
398 399 400 401 |
# File 'lib/active_ldap/base.rb', line 398 def scope=(scope) validate_scope(scope) self.scope_without_validation = scope end |
.scope_without_validation= ⇒ Object
397 |
# File 'lib/active_ldap/base.rb', line 397 alias_method :scope_without_validation=, :scope= |
.validate_scope(scope) ⇒ Object
403 404 405 406 407 408 |
# File 'lib/active_ldap/base.rb', line 403 def validate_scope(scope) scope = scope.to_sym if scope.is_a?(String) return if scope.nil? or scope.is_a?(Symbol) raise ConfigurationError, _("scope '%s' must be a Symbol") % scope.inspect end |
Instance Method Details
#==(comparison_object) ⇒ Object
Returns true if the comparison_object
is the same object, or is of the same type and has the same dn.
526 527 528 529 530 531 |
# File 'lib/active_ldap/base.rb', line 526 def ==(comparison_object) comparison_object.equal?(self) or (comparison_object.instance_of?(self.class) and comparison_object.dn == dn and !comparison_object.new_entry?) end |
#[](name, force_array = false) ⇒ Object
799 800 801 802 803 804 805 |
# File 'lib/active_ldap/base.rb', line 799 def [](name, force_array=false) if name == "dn" array_of(dn, force_array) else get_attribute(name, force_array) end end |
#[]=(name, value) ⇒ Object
807 808 809 |
# File 'lib/active_ldap/base.rb', line 807 def []=(name, value) set_attribute(name, value) end |
#attribute_names(normalize = false) ⇒ Object
attributes
Return attribute methods so that a program can determine available attributes dynamically without schema awareness
558 559 560 |
# File 'lib/active_ldap/base.rb', line 558 def attribute_names(normalize=false) entry_attribute.names(normalize) end |
#attribute_present?(name) ⇒ Boolean
562 563 564 565 |
# File 'lib/active_ldap/base.rb', line 562 def attribute_present?(name) values = get_attribute(name, true) !values.empty? or values.any? {|x| not (x and x.empty?)} end |
#attributes ⇒ Object
This returns the key value pairs in @data with all values cloned
722 723 724 |
# File 'lib/active_ldap/base.rb', line 722 def attributes Marshal.load(Marshal.dump(@data)) end |
#attributes=(new_attributes) ⇒ Object
This allows a bulk update to the attributes of a record without forcing an immediate save or validation.
It is unwise to attempt objectClass updates this way. Also be sure to only pass in key-value pairs of your choosing. Do not let URL/form hackers supply the keys.
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
# File 'lib/active_ldap/base.rb', line 732 def attributes=(new_attributes) return if new_attributes.nil? _schema = _local_entry_attribute = nil targets = remove_attributes_protected_from_mass_assignment(new_attributes) targets.each do |key, value| setter = "#{key}=" unless respond_to?(setter) _schema ||= schema attribute = _schema.attribute(key) next if attribute.id.nil? _local_entry_attribute ||= local_entry_attribute _local_entry_attribute.register(attribute) end send(setter, value) end end |
#base ⇒ Object
858 859 860 |
# File 'lib/active_ldap/base.rb', line 858 def base [@base, base_of_class].compact.join(",") end |
#base=(object_local_base) ⇒ Object
863 864 865 866 |
# File 'lib/active_ldap/base.rb', line 863 def base=(object_local_base) @dn = nil @base = object_local_base end |
#base_of_class ⇒ Object
857 |
# File 'lib/active_ldap/base.rb', line 857 alias_method :base_of_class, :base |
#bind(config_or_password = {}, config_or_ignore = nil, &block) ⇒ Object
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 |
# File 'lib/active_ldap/base.rb', line 817 def bind(config_or_password={}, config_or_ignore=nil, &block) if config_or_password.is_a?(String) config = (config_or_ignore || {}).merge(:password => config_or_password) else config = config_or_password end config = {:bind_dn => dn, :allow_anonymous => false}.merge(config) config[:password_block] ||= block if block_given? establish_connection(config) before_connection = @connection begin @connection = nil connection.connect @connection = connection clear_connection_based_cache clear_association_cache rescue ActiveLdap::Error remove_connection @connection = before_connection raise end true end |
#clear_connection_based_cache ⇒ Object
842 843 844 845 846 |
# File 'lib/active_ldap/base.rb', line 842 def clear_connection_based_cache @schema = nil @local_entry_attribute = nil clear_object_class_based_cache end |
#clear_object_class_based_cache ⇒ Object
848 849 850 851 |
# File 'lib/active_ldap/base.rb', line 848 def clear_object_class_based_cache @entry_attribute = nil @real_names = {} end |
#default_search_attribute ⇒ Object
608 609 610 |
# File 'lib/active_ldap/base.rb', line 608 def default_search_attribute self.class.default_search_attribute end |
#delete(options = {}) ⇒ Object
624 625 626 |
# File 'lib/active_ldap/base.rb', line 624 def delete(={}) super(dn, ) end |
#destroy ⇒ Object
destroy
Delete this entry from LDAP
615 616 617 618 619 620 621 622 |
# File 'lib/active_ldap/base.rb', line 615 def destroy begin self.class.delete(dn) @new_entry = true rescue Error raise DeleteError.new(_("Failed to delete LDAP entry: %s") % dn) end end |
#dn ⇒ Object
dn
Return the authoritative dn
585 586 587 |
# File 'lib/active_ldap/base.rb', line 585 def dn @dn ||= compute_dn end |
#dn=(value) ⇒ Object Also known as: id=
597 598 599 600 |
# File 'lib/active_ldap/base.rb', line 597 def dn=(value) set_attribute(dn_attribute, value) @dn = nil end |
#dn_attribute ⇒ Object
604 605 606 |
# File 'lib/active_ldap/base.rb', line 604 def dn_attribute @dn_attribute || dn_attribute_of_class end |
#dn_attribute_of_class ⇒ Object
603 |
# File 'lib/active_ldap/base.rb', line 603 alias_method(:dn_attribute_of_class, :dn_attribute) |
#each ⇒ Object
811 812 813 814 815 |
# File 'lib/active_ldap/base.rb', line 811 def each @data.each do |key, values| yield(key.dup, values.dup) end end |
#eql?(comparison_object) ⇒ Boolean
Delegates to ==
534 535 536 |
# File 'lib/active_ldap/base.rb', line 534 def eql?(comparison_object) self == (comparison_object) end |
#exist? ⇒ Boolean Also known as: exists?
exist?
Return whether the entry exists in LDAP or not
570 571 572 |
# File 'lib/active_ldap/base.rb', line 570 def exist? self.class.exists?(dn) end |
#hash ⇒ Object
Delegates to id in order to allow two records of the same type and id to work with something like:
[ User.find("a"), User.find("b"), User.find("c") ] &
[ User.find("a"), User.find("d") ] # => [ User.find("a") ]
542 543 544 |
# File 'lib/active_ldap/base.rb', line 542 def hash dn.hash end |
#have_attribute?(name, except = []) ⇒ Boolean Also known as: has_attribute?
776 777 778 779 |
# File 'lib/active_ldap/base.rb', line 776 def have_attribute?(name, except=[]) real_name = to_real_attribute_name(name) real_name and !except.include?(real_name) end |
#id ⇒ Object
589 590 591 |
# File 'lib/active_ldap/base.rb', line 589 def id get_attribute(dn_attribute) end |
#inspect ⇒ Object
879 880 881 882 883 |
# File 'lib/active_ldap/base.rb', line 879 def inspect abbreviate_instance_variables do super end end |
#may ⇒ Object
546 547 548 |
# File 'lib/active_ldap/base.rb', line 546 def may entry_attribute.may end |
#methods(inherited_too = true) ⇒ Object
Add available attributes to the methods
684 685 686 687 688 689 690 |
# File 'lib/active_ldap/base.rb', line 684 def methods(inherited_too=true) target_names = entry_attribute.all_names target_names -= ['objectClass', Inflector.underscore('objectClass')] super + target_names.uniq.collect do |x| [x, "#{x}=", "#{x}?", "#{x}_before_type_cast"] end.flatten end |
#must ⇒ Object
550 551 552 |
# File 'lib/active_ldap/base.rb', line 550 def must entry_attribute.must end |
#new_entry? ⇒ Boolean
new_entry?
Return whether the entry is new entry in LDAP or not
578 579 580 |
# File 'lib/active_ldap/base.rb', line 578 def new_entry? @new_entry end |
#pretty_print(q) ⇒ Object
885 886 887 888 889 |
# File 'lib/active_ldap/base.rb', line 885 def pretty_print(q) abbreviate_instance_variables do q.pp_object(self) end end |
#reload ⇒ Object
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
# File 'lib/active_ldap/base.rb', line 782 def reload clear_association_cache _, attributes = search(:value => id).find do |_dn, _attributes| dn == _dn end if attributes.nil? raise EntryNotFound, _("Can't find DN '%s' to reload") % dn end @ldap_data.update(attributes) classes, attributes = extract_object_class(attributes) self.classes = classes self.attributes = attributes @new_entry = false self end |
#respond_to?(name, include_priv = false) ⇒ Boolean
693 694 695 696 697 698 699 700 |
# File 'lib/active_ldap/base.rb', line 693 def respond_to?(name, include_priv=false) return true if super name = name.to_s return true if have_attribute?(name) return false if /(?:=|\?|_before_type_cast)$/ !~ name have_attribute?($PREMATCH) end |
#respond_to_without_attributes? ⇒ Object
692 |
# File 'lib/active_ldap/base.rb', line 692 alias_method :respond_to_without_attributes?, :respond_to? |
#save ⇒ Object
save
Save and validate this object into LDAP either adding or replacing attributes TODO: Relative DN support
633 634 635 |
# File 'lib/active_ldap/base.rb', line 633 def save create_or_update end |
#save! ⇒ Object
637 638 639 640 641 |
# File 'lib/active_ldap/base.rb', line 637 def save! unless create_or_update raise EntryNotSaved, _("entry %s can't be saved") % dn end end |
#schema ⇒ Object
853 854 855 |
# File 'lib/active_ldap/base.rb', line 853 def schema @schema ||= super end |
#scope ⇒ Object
869 870 871 |
# File 'lib/active_ldap/base.rb', line 869 def scope @scope || scope_of_class end |
#scope=(scope) ⇒ Object
874 875 876 877 |
# File 'lib/active_ldap/base.rb', line 874 def scope=(scope) self.class.validate_scope(scope) @scope = scope end |
#scope_of_class ⇒ Object
868 |
# File 'lib/active_ldap/base.rb', line 868 alias_method :scope_of_class, :scope |
#to_ldif ⇒ Object
749 750 751 |
# File 'lib/active_ldap/base.rb', line 749 def to_ldif super(dn, @data) end |
#to_param ⇒ Object
593 594 595 |
# File 'lib/active_ldap/base.rb', line 593 def to_param id end |
#to_xml(options = {}) ⇒ Object
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 |
# File 'lib/active_ldap/base.rb', line 753 def to_xml(={}) root = [:root] || Inflector.underscore(self.class.name) result = "<#{root}>\n" result << " <dn>#{dn}</dn>\n" normalize_data(@data).sort_by {|key, values| key}.each do |key, values| targets = [] values.each do |value| if value.is_a?(Hash) value.each do |option, real_value| targets << [real_value, " #{option}=\"true\""] end else targets << [value] end end targets.sort_by {|value, attr| value}.each do |value, attr| result << " <#{key}#{attr}>#{value}</#{key}>\n" end end result << "</#{root}>\n" result end |
#update_attribute(name, value) ⇒ Object
Updates a given attribute and saves immediately
703 704 705 706 |
# File 'lib/active_ldap/base.rb', line 703 def update_attribute(name, value) send("#{name}=", value) save end |
#update_attributes(attrs) ⇒ Object
This performs a bulk update of attributes and immediately calls #save.
710 711 712 713 |
# File 'lib/active_ldap/base.rb', line 710 def update_attributes(attrs) self.attributes = attrs save end |
#update_attributes!(attrs) ⇒ Object
715 716 717 718 |
# File 'lib/active_ldap/base.rb', line 715 def update_attributes!(attrs) self.attributes = attrs save! end |