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