lib/activeldap/base.rb in ruby-activeldap-debug-0.5.9 vs lib/activeldap/base.rb in ruby-activeldap-debug-0.6.0

- old
+ new

@@ -78,11 +78,18 @@ # # An exception raised when an objectClass is not defined in the schema class ObjectClassError < RuntimeError end + # AttributeAssignmentError + # + # An exception raised when there is an issue assigning a value to + # an attribute + class AttributeAssignmentError < RuntimeError + end + # 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. @@ -406,11 +413,12 @@ matches = [] tries = 0 begin # Get some attributes - @@conn.search(base(), LDAP::LDAP_SCOPE_ONELEVEL, "(#{attr}=#{val})") do |m| + @@conn.search(base(), LDAP::LDAP_SCOPE_ONELEVEL, + "(#{attr}=#{val})") do |m| # Extract the dnattr value dnval = m.dn.split(/,/)[0].split(/=/)[1] if objects matches.push(real_klass.new(m)) @@ -486,11 +494,12 @@ # exist for dnattr, the first one put here will be authoritative # TODO: Add # support for relative distinguished names # val can be a dn attribute value, a full DN, or a LDAP::Entry. The use # with a LDAP::Entry is primarily meant for internal use by find and # find_all. - def initialize(val='') + def initialize(val) + @exists = false # Try a default connection if none made explicitly unless Base.connection # Use @@config if it has been prepopulated and the conn is down. if @@config ActiveLDAP::Base.connect(@@config) @@ -524,21 +533,23 @@ @@logger.info "initialize: Changing val from '#{val}' to '' because it doesn't match the DN." val = '' end # Do a search - if it exists, pull all data and parse schema, if not, just set the hierarchical data - if val.empty? - @exists = false - # Setup what should eb authoritative + if val.class != String or val.empty? + raise TypeError, 'a dn attribute String must be supplied ' + + 'on initialization' + else + # Create what should be the authoritative DN @dn = "#{dnattr()}=#{val},#{base()}" - send(:apply_objectclass, required_classes()) - else # do a search then + # Search for the existing entry tries = 0 begin # Get some attributes Base.connection.search(base(), LDAP::LDAP_SCOPE_ONELEVEL, "(#{dnattr()}=#{val})") do |m| + @exists = true # Save DN @dn = m.dn # Load up data into tmp @@logger.debug("loading entry: #{@dn}") m.attrs.each do |attr| @@ -554,47 +565,45 @@ else @ldap_data[safe_attr] = value end end end - @exists = true - # Populate schema data - send(:apply_objectclass, @ldap_data['objectClass']) - - # Populate real data now that we have the schema with aliases - @ldap_data.each do |pair| - send(:attribute_method=, pair[0], pair[1].dup) - end rescue RuntimeError => detail #todo# check for 'no message' when retrying # the connection may have gone stale. let's reconnect and retry. - if tries > @@config[:retries] - @exists = false - # Create what should be the authoritative DN - @dn = "#{dnattr()}=#{val},#{base()}" - send(:apply_objectclass, required_classes()) - - # Setup dn attribute (later rdn too!) - attr_sym = "#{dnattr()}=".to_sym - @@logger.debug("new: setting dnattr: #{dnattr()} = #{val}") - send(attr_sym, val) + if tries <= @@config[:retries] + tries += 1 + # reconnect and rebind. + do_connect() + retry + else + @@logger.error('new: unable to search for entry') + raise detail end - tries += 1 - # reconnect and rebind. - do_connect() - retry rescue LDAP::ResultError - @exists = false - # Create what should be the authoritative DN - @dn = "#{dnattr()}=#{val},#{base()}" - send(:apply_objectclass, required_classes()) + end + end - # Setup dn attribute (later rdn too!) - attr_sym = "#{dnattr()}=".to_sym - @@logger.debug("new: setting dnattr: #{dnattr()} = #{val}") - send(attr_sym, val) + # Do the actual object setup work. + if @exists + # Populate schema data + send(:apply_objectclass, @ldap_data['objectClass']) + + # Populate real data now that we have the schema with aliases + @ldap_data.each do |pair| + real_attr = @attr_methods[pair[0]] + @@logger.debug("new: #{pair[0].inspect} method maps to #{real_attr}") + @data[real_attr] = pair[1].dup + @@logger.debug("new: #{real_attr} set to #{pair[1]}") end + else + send(:apply_objectclass, required_classes()) + + # Setup dn attribute (later rdn too!) + real_dnattr = @attr_methods[dnattr()] + @data[real_dnattr] = val + @@logger.debug("new: setting dnattr: #{real_dnattr} = #{val}") end end # initialize # Hide new in Base private_class_method :new @@ -959,11 +968,14 @@ # Populate schema data send(:apply_objectclass, @ldap_data['objectClass']) # Populate real data now that we have the schema with aliases @ldap_data.each do |pair| - send(:attribute_method=, pair[0], pair[1].dup) + real_attr = @attr_methods[pair[0]] + @@logger.debug("new: #{pair[0].inspect} method maps to #{real_attr}") + @data[real_attr] = pair[1].dup + @@logger.debug("new: #{real_attr} set to #{pair[1]}") end end # import # enforce_types # @@ -1288,9 +1300,14 @@ def attribute_method=(method, value) @@logger.debug("stub: called attribute_method=(#{method.inspect}, #{value.inspect})") # Get the attr and clean up the input attr = @attr_methods[method] @@logger.debug("attribute_method=(#{method.inspect}, #{value.inspect}): method maps to #{attr}") + + # Check if it is the DN attribute + if dnattr() == attr + raise AttributeAssignmentError, 'cannot modify the DN attribute value' + end # Assign the value @data[attr] = value # Return the passed in value