Browse files

Rename to Ldaptic

  • Loading branch information...
1 parent baf3b89 commit eb3f2abe6a31f9199cfb7c423871c9ae9c22e08b @tpope committed Jan 25, 2011
Showing with 497 additions and 497 deletions.
  1. +7 −7 README.rdoc
  2. +2 −2 Rakefile
  3. +2 −2 ldapter.gemspec → ldaptic.gemspec
  4. +27 −27 lib/{ldapter.rb → ldaptic.rb}
  5. +10 −10 lib/{ldapter → ldaptic}/adapters.rb
  6. +14 −14 lib/{ldapter → ldaptic}/adapters/abstract_adapter.rb
  7. +4 −4 lib/{ldapter → ldaptic}/adapters/active_directory_adapter.rb
  8. 0 lib/{ldapter → ldaptic}/adapters/active_directory_ext.rb
  9. +8 −8 lib/{ldapter → ldaptic}/adapters/ldap_conn_adapter.rb
  10. +4 −4 lib/{ldapter → ldaptic}/adapters/net_ldap_adapter.rb
  11. 0 lib/{ldapter → ldaptic}/adapters/net_ldap_ext.rb
  12. +5 −5 lib/{ldapter → ldaptic}/attribute_set.rb
  13. +28 −28 lib/{ldapter → ldaptic}/dn.rb
  14. +33 −33 lib/{ldapter → ldaptic}/entry.rb
  15. +1 −1 lib/{ldapter → ldaptic}/error_set.rb
  16. +5 −5 lib/{ldapter → ldaptic}/errors.rb
  17. +5 −5 lib/{ldapter → ldaptic}/escape.rb
  18. +32 −32 lib/{ldapter → ldaptic}/filter.rb
  19. +24 −24 lib/{ldapter → ldaptic}/methods.rb
  20. +5 −5 lib/{ldapter → ldaptic}/schema.rb
  21. +10 −10 lib/{ldapter → ldaptic}/syntaxes.rb
  22. +0 −110 test/ldapter_dn_test.rb
  23. +0 −47 test/ldapter_escape_test.rb
  24. +0 −66 test/ldapter_syntaxes_test.rb
  25. +3 −3 test/{ldapter_active_model_test.rb → ldaptic_active_model_test.rb}
  26. +9 −9 test/{ldapter_adapters_test.rb → ldaptic_adapters_test.rb}
  27. +3 −3 test/{ldapter_attribute_set_test.rb → ldaptic_attribute_set_test.rb}
  28. +110 −0 test/ldaptic_dn_test.rb
  29. +3 −3 test/{ldapter_entry_test.rb → ldaptic_entry_test.rb}
  30. +5 −5 test/{ldapter_errors_test.rb → ldaptic_errors_test.rb}
  31. +47 −0 test/ldaptic_escape_test.rb
  32. +8 −8 test/{ldapter_filter_test.rb → ldaptic_filter_test.rb}
  33. +4 −4 test/{ldapter_hierarchy_test.rb → ldaptic_hierarchy_test.rb}
  34. +10 −10 test/{ldapter_schema_test.rb → ldaptic_schema_test.rb}
  35. +66 −0 test/ldaptic_syntaxes_test.rb
  36. +3 −3 test/mock_adapter.rb
View
14 README.rdoc
@@ -1,4 +1,4 @@
-= Ldapter
+= Ldaptic
This is an object-oriented LDAP wrapper library I started back in 2007 but
only recently polished up and released. It's unique in that it creates a
@@ -8,19 +8,19 @@ hierarchy on the server. For example, on a typical server, you'll get an
inherits from +Person+ which inherits from +Top+. You can reopen any of these
classes to add additional client side behavior.
-Ldapter started as mainly a tool to interact with my company's Active
+Ldaptic started as mainly a tool to interact with my company's Active
Directory server, and I lost interest in it when I left that job. Recently,
I've become motivated to work on it again, as some of the blocking issues I
faced are now potentially solvable with Active Model.
== Getting Started
You need to have either the ruby-ldap or net-ldap gem installed. The former
-is preferred because it's faster native C. Ldapter is configured by including
+is preferred because it's faster native C. Ldaptic is configured by including
a dynamically created module into a namespace of your choosing.
module Example
- include Ldapter::Module(
+ include Ldaptic::Module(
:adapter => :ldap_conn,
:base => 'ou=Users,dc=example,dc=com',
:host => 'example.com',
@@ -84,8 +84,8 @@ Entries also implement many of the standard methods you've come to expect in
an Active Record world (save, valid?, errors, to_param, attributes, ...).
In fact, it is fully Active Model compliant.
-For more information, see in particular Ldapter::Methods (for namespace
-methods like search), Ldapter::Entry, and Ldapter::AttributeSet.
+For more information, see in particular Ldaptic::Methods (for namespace
+methods like search), Ldaptic::Entry, and Ldaptic::AttributeSet.
== To Do
@@ -101,4 +101,4 @@ methods like search), Ldapter::Entry, and Ldapter::AttributeSet.
you would find useful, as most are on hold until someone has a real use
case.
-* Pick a better name? Ldapter has an ambiguous spelling.
+* Pick a better name? Ldaptic has an ambiguous spelling.
View
4 Rakefile
@@ -20,12 +20,12 @@ Rake::RDocTask.new do |rdoc|
rdoc.rdoc_dir = 'doc'
rdoc.rdoc_files.add('README.rdoc', 'lib')
rdoc.main = 'README.rdoc'
- rdoc.title = 'Ldapter'
+ rdoc.title = 'Ldaptic'
rdoc.options << '--inline-source'
rdoc.options << '-d' if `which dot` =~ /\/dot/
end
-spec = eval(File.read(File.join(File.dirname(__FILE__), 'ldapter.gemspec')))
+spec = eval(File.read(File.join(File.dirname(__FILE__), 'ldaptic.gemspec')))
Rake::GemPackageTask.new(spec) do |p|
p.gem_spec = spec
end
View
4 ldapter.gemspec → ldaptic.gemspec
@@ -1,12 +1,12 @@
Gem::Specification.new do |s|
- s.name = "ldapter"
+ s.name = "ldaptic"
s.version = "0.1.2"
s.summary = 'Object-oriented schema-aware LDAP wrapper'
s.description = 'Include a parameterized dynamic module in a namespace and get a full LDAP class hierarchy at your disposal.'
s.authors = ["Tim Pope"]
s.email = "ruby@tpope.o"+'rg'
- s.homepage = "http://github.com/tpope/ldapter"
+ s.homepage = "http://github.com/tpope/ldaptic"
s.files = ["Rakefile", "README.rdoc", "LICENSE"]
s.files += Dir.glob("lib/**/*.rb")
s.files += Dir.glob("test/**/*")
View
54 lib/ldapter.rb → lib/ldaptic.rb
@@ -1,25 +1,25 @@
#!/usr/bin/env ruby
-require 'ldapter/dn'
-require 'ldapter/filter'
-require 'ldapter/errors'
-require 'ldapter/schema'
-require 'ldapter/syntaxes'
-require 'ldapter/adapters'
-require 'ldapter/entry'
-require 'ldapter/methods'
+require 'ldaptic/dn'
+require 'ldaptic/filter'
+require 'ldaptic/errors'
+require 'ldaptic/schema'
+require 'ldaptic/syntaxes'
+require 'ldaptic/adapters'
+require 'ldaptic/entry'
+require 'ldaptic/methods'
# = Getting started
#
-# See the methods of the Ldapter module (below) for information on connecting.
+# See the methods of the Ldaptic module (below) for information on connecting.
#
-# See the Ldapter::Methods module for information on searching with your
+# See the Ldaptic::Methods module for information on searching with your
# connection object.
#
-# Search results are Ldapter::Entry objects. See the documentation for this
+# Search results are Ldaptic::Entry objects. See the documentation for this
# class for information on manipulating and updating them, as well as creating
# new entries.
-module Ldapter
+module Ldaptic
SCOPES = {
:base => 0, # ::LDAP::LDAP_SCOPE_BASE,
@@ -46,26 +46,26 @@ def self.logger=(logger)
end
# Returns an object that can be assigned directly to a variable. This allows
- # for an "anonymous" Ldapter object.
- # @my_company = Ldapter::Object(options)
+ # for an "anonymous" Ldaptic object.
+ # @my_company = Ldaptic::Object(options)
# @my_company::User.class_eval do
# alias login sAMAccountName
# end
def self.Object(options={}, &block)
base = ::Module.new do
- include Ldapter::Module(options)
+ include Ldaptic::Module(options)
end
if block_given?
base.class_eval(&block)
end
base
end
- # Similar to Ldapter::Class, accepting the same options. Instead of
+ # Similar to Ldaptic::Class, accepting the same options. Instead of
# returning an anonymous class that activates upon inheritance, it returns an
# anonymous module that activates upon inclusion.
# module MyCompany
- # include Ldapter::Module(options)
+ # include Ldaptic::Module(options)
# # This class and many others are created automatically based on
# # information from the server.
# class User
@@ -76,15 +76,15 @@ def self.Object(options={}, &block)
# me = MyCompany.search(:filter => {:cn => "Name, My"}).first
# puts me.login
def self.Module(options={})
- Ldapter::Module.new(options)
+ Ldaptic::Module.new(options)
end
- # The core constructor of Ldapter. This method returns an anonymous class
+ # The core constructor of Ldaptic. This method returns an anonymous class
# which can then be inherited from.
#
# The new class is not intended to be instantiated, instead serving as a
# namespace. Included in this namespace is a set of class methods, as found
- # in Ldapter::Methods, and a class hierarchy mirroring the object classes
+ # in Ldaptic::Methods, and a class hierarchy mirroring the object classes
# found on the server.
#
# options = {
@@ -94,7 +94,7 @@ def self.Module(options={})
# :password => "mypassword"
# }
#
- # class MyCompany < Ldapter::Class(options)
+ # class MyCompany < Ldaptic::Class(options)
# # This class and many others are created automatically based on
# # information from the server.
# class User
@@ -105,19 +105,19 @@ def self.Module(options={})
# me = MyCompany.search(:filter => {:cn => "Name, My"}).first
# puts me.login
#
- # Options given to this method are relayed to Ldapter::Adapters.for. The
+ # Options given to this method are relayed to Ldaptic::Adapters.for. The
# documentation for this method should be consulted for further information.
def self.Class(options={})
klass = ::Class.new(Class)
- klass.instance_variable_set(:@options, Ldapter::Adapters.for(options))
+ klass.instance_variable_set(:@options, Ldaptic::Adapters.for(options))
klass
end
class << self
alias Namespace Class
end
- # An instance of this subclass of ::Module is returned by the Ldapter::Module
+ # An instance of this subclass of ::Module is returned by the Ldaptic::Module
# method.
class Module < ::Module #:nodoc:
def initialize(options={})
@@ -126,19 +126,19 @@ def initialize(options={})
end
def append_features(base)
base.extend(Methods)
- base.instance_variable_set(:@adapter, Ldapter::Adapters.for(@options))
+ base.instance_variable_set(:@adapter, Ldaptic::Adapters.for(@options))
base.module_eval { build_hierarchy }
end
end
- # The anonymous class returned by the Ldapter::Class method descends from
+ # The anonymous class returned by the Ldaptic::Class method descends from
# this class.
class Class #:nodoc:
class << self
# Callback which triggers the magic.
def inherited(subclass)
if options = @options
- subclass.class_eval { include Ldapter::Module.new(options) }
+ subclass.class_eval { include Ldaptic::Module.new(options) }
else
subclass.instance_variable_set(:@adapter, @adapter)
end
View
20 lib/ldapter/adapters.rb → lib/ldaptic/adapters.rb
@@ -1,4 +1,4 @@
-module Ldapter
+module Ldaptic
# RFC1823 - The LDAP Application Program Interface
module Adapters
@@ -13,11 +13,11 @@ def register(name, mod) #:nodoc:
end
# Returns a new adapter for a given set of options. This method is not
- # for end user use but is instead called by the Ldapter::Class,
- # Ldapter::Module, and Ldapter::Object methods.
+ # for end user use but is instead called by the Ldaptic::Class,
+ # Ldaptic::Module, and Ldaptic::Object methods.
#
# The <tt>:adapter</tt> key of the +options+ hash selects which adapter
- # to use. The following adapters are included with Ldapter.
+ # to use. The following adapters are included with Ldaptic.
#
# * <tt>:ldap_conn</tt>: a Ruby/LDAP LDAP::Conn connection.
# * <tt>:ldap_sslconn</tt>: a Ruby/LDAP LDAP::SSLConn connection.
@@ -38,7 +38,7 @@ def register(name, mod) #:nodoc:
# * <tt>:base</tt>: The default base DN. Derived from the server by
# default.
def for(options)
- require 'ldapter/adapters/abstract_adapter'
+ require 'ldaptic/adapters/abstract_adapter'
# Allow an adapter to be passed directly in for backwards compatibility.
if defined?(::LDAP::Conn) && options.kind_of?(::LDAP::Conn)
options = {:adapter => :ldap_conn, :connection => options}
@@ -52,22 +52,22 @@ def for(options)
end
options[:adapter] ||= default_adapter
unless options[:adapter]
- Ldapter::Errors.raise(ArgumentError.new("No adapter specfied"))
+ Ldaptic::Errors.raise(ArgumentError.new("No adapter specfied"))
end
begin
- require "ldapter/adapters/#{options[:adapter]}_adapter"
+ require "ldaptic/adapters/#{options[:adapter]}_adapter"
rescue LoadError
end
if adapter = @adapters[options[:adapter].to_sym]
adapter.new(options)
else
- Ldapter::Errors.raise(ArgumentError.new("Adapter #{options[:adapter]} not found"))
+ Ldaptic::Errors.raise(ArgumentError.new("Adapter #{options[:adapter]} not found"))
end
else
- if options.kind_of?(::Ldapter::Adapters::AbstractAdapter)
+ if options.kind_of?(::Ldaptic::Adapters::AbstractAdapter)
options
else
- Ldapter::Errors.raise(TypeError.new("#{options.class} is not a valid connection type"))
+ Ldaptic::Errors.raise(TypeError.new("#{options.class} is not a valid connection type"))
end
end
end
View
28 lib/ldapter/adapters/abstract_adapter.rb → lib/ldaptic/adapters/abstract_adapter.rb
@@ -1,7 +1,7 @@
-require 'ldapter/escape'
-require 'ldapter/errors'
+require 'ldaptic/escape'
+require 'ldaptic/errors'
-module Ldapter
+module Ldaptic
module Adapters
# Subclasse must implement search, add, modify, delete, and rename. These
# methods should return 0 on success and non-zero on failure. The failure
@@ -11,14 +11,14 @@ class AbstractAdapter
# When implementing an adapter, +register_as+ must be called to associate
# the adapter with a name. The adapter name must mimic the filename.
- # The following might be found in ldapter/adapters/some_adapter.rb.
+ # The following might be found in ldaptic/adapters/some_adapter.rb.
#
# class SomeAdapter < AbstractAdapter
# register_as(:some)
# end
def self.register_as(name)
- require 'ldapter/adapters'
- Ldapter::Adapters.register(name, self)
+ require 'ldaptic/adapters'
+ Ldaptic::Adapters.register(name, self)
end
def initialize(options)
@@ -30,9 +30,9 @@ def initialize(options)
def root_dse(attrs = nil)
result = search(
:base => "",
- :scope => Ldapter::SCOPES[:base],
+ :scope => Ldaptic::SCOPES[:base],
:filter => "(objectClass=*)",
- :attributes => attrs && [attrs].flatten.map {|a| Ldapter.encode(a)},
+ :attributes => attrs && [attrs].flatten.map {|a| Ldaptic.encode(a)},
:disable_pagination => true
) { |x| break x }
return if result.kind_of?(Fixnum)
@@ -47,7 +47,7 @@ def schema(attrs = nil)
@subschema_dn ||= root_dse(['subschemaSubentry'])['subschemaSubentry'].first
search(
:base => @subschema_dn,
- :scope => Ldapter::SCOPES[:base],
+ :scope => Ldaptic::SCOPES[:base],
:filter => "(objectClass=subschema)",
:attributes => attrs
) { |x| return x }
@@ -69,7 +69,7 @@ def server_default_base_dn
# Returns a hash of attribute types, keyed by both OID and name.
def attribute_types
@attribute_types ||= construct_schema_hash('attributeTypes',
- Ldapter::Schema::AttributeType)
+ Ldaptic::Schema::AttributeType)
end
def attribute_type(key = nil)
@@ -85,23 +85,23 @@ def attribute_type(key = nil)
# Returns a hash of DIT content rules, keyed by both OID and name.
def dit_content_rules
@dit_content_rules ||= construct_schema_hash('dITContentRules',
- Ldapter::Schema::DITContentRule)
+ Ldaptic::Schema::DITContentRule)
end
# Returns a hash of object classes, keyed by both OID and name.
def object_classes
@object_classes ||= construct_schema_hash('objectClasses',
- Ldapter::Schema::ObjectClass)
+ Ldaptic::Schema::ObjectClass)
end
# Default compare operation, emulated with a search.
def compare(dn, attr, value)
- search(:base => dn, :scope => Ldapter::SCOPES[:base], :filter => "(#{attr}=#{Ldapter.escape(value)})") { return true }
+ search(:base => dn, :scope => Ldaptic::SCOPES[:base], :filter => "(#{attr}=#{Ldaptic.escape(value)})") { return true }
false
end
def logger
- @logger || Ldapter.logger
+ @logger || Ldaptic.logger
end
private
View
8 ...pter/adapters/active_directory_adapter.rb → ...ptic/adapters/active_directory_adapter.rb
@@ -1,7 +1,7 @@
-require 'ldapter/adapters/ldap_conn_adapter'
-require 'ldapter/adapters/active_directory_ext'
+require 'ldaptic/adapters/ldap_conn_adapter'
+require 'ldaptic/adapters/active_directory_ext'
-module Ldapter
+module Ldaptic
module Adapters
# ActiveDirectoryAdapter is a LDAPConnAdapter with some Active Directory
# specific behaviors. To help mitigate server timeout issues, this adapter
@@ -48,7 +48,7 @@ def full_username(username)
conn = new_connection(3268)
dn = conn.search2("", 0, "(objectClass=*", ['defaultNamingContext']).first['defaultNamingContext']
if dn
- domain = Ldapter::DN(dn).rdns.map {|rdn| rdn[:dc]}.compact
+ domain = Ldaptic::DN(dn).rdns.map {|rdn| rdn[:dc]}.compact
unless domain.empty?
username = [username, domain.join(".")].join("@")
end
View
0 lib/ldapter/adapters/active_directory_ext.rb → lib/ldaptic/adapters/active_directory_ext.rb
File renamed without changes.
View
16 lib/ldapter/adapters/ldap_conn_adapter.rb → lib/ldaptic/adapters/ldap_conn_adapter.rb
@@ -1,6 +1,6 @@
-require 'ldapter/adapters/abstract_adapter'
+require 'ldaptic/adapters/abstract_adapter'
-module Ldapter
+module Ldaptic
module Adapters
class LDAPConnAdapter < AbstractAdapter
register_as(:ldap_conn)
@@ -65,7 +65,7 @@ def rename(dn, new_rdn, delete_old, new_superior = nil)
if conn.respond_to?(:rename)
conn.rename(dn, new_rdn, new_superior, delete_old)
else
- Ldapter::Errors.raise(NotImplementedError.new("rename unsupported"))
+ Ldaptic::Errors.raise(NotImplementedError.new("rename unsupported"))
end
else
conn.modrdn(dn, new_rdn, delete_old)
@@ -77,9 +77,9 @@ def compare(dn, attr, value)
with_reader do |conn|
conn.compare(dn, attr, value)
end
- rescue Ldapter::Errors::CompareFalse
+ rescue Ldaptic::Errors::CompareFalse
false
- rescue Ldapter::Errors::CompareTrue
+ rescue Ldaptic::Errors::CompareTrue
true
end
@@ -119,7 +119,7 @@ def authenticate(dn, password)
message = exception.message
err = error_for_message(message)
unless err == 49 # Invalid credentials
- Ldapter::Errors.raise_unless_zero(err, message)
+ Ldaptic::Errors.raise_unless_zero(err, message)
end
false
ensure
@@ -198,7 +198,7 @@ def bind_connection(conn, dn, password, &block)
def full_username(username)
if username.kind_of?(Hash)
- base = Ldapter::DN(default_base_dn || "")
+ base = Ldaptic::DN(default_base_dn || "")
base / username
else
username
@@ -231,7 +231,7 @@ def with_conn(conn, &block)
err = conn_err
message = conn.err2string(err) rescue nil
end
- Ldapter::Errors.raise_unless_zero(err, message)
+ Ldaptic::Errors.raise_unless_zero(err, message)
result
end
View
8 lib/ldapter/adapters/net_ldap_adapter.rb → lib/ldaptic/adapters/net_ldap_adapter.rb
@@ -1,14 +1,14 @@
-require 'ldapter/adapters/abstract_adapter'
+require 'ldaptic/adapters/abstract_adapter'
-module Ldapter
+module Ldaptic
module Adapters
class NetLDAPAdapter < AbstractAdapter
register_as(:net_ldap)
def initialize(options)
require 'net/ldap'
- require 'ldapter/adapters/net_ldap_ext'
+ require 'ldaptic/adapters/net_ldap_ext'
if defined?(::Net::LDAP) && options.kind_of?(::Net::LDAP)
options = {:adapter => :net_ldap, :connection => option}
else
@@ -163,7 +163,7 @@ def recapitalize(attribute)
def handle_errors
result = yield if block_given?
err = @connection.get_operation_result
- Ldapter::Errors.raise_unless_zero(err.code, err.message)
+ Ldaptic::Errors.raise_unless_zero(err.code, err.message)
result
end
View
0 lib/ldapter/adapters/net_ldap_ext.rb → lib/ldaptic/adapters/net_ldap_ext.rb
File renamed without changes.
View
10 lib/ldapter/attribute_set.rb → lib/ldaptic/attribute_set.rb
@@ -1,6 +1,6 @@
-require 'ldapter/escape'
+require 'ldaptic/escape'
-module Ldapter
+module Ldaptic
# AttributeSet, like the name suggests, represents a set of attributes. Most
# operations are delegated to an array, so the usual array methods should
# work transparently.
@@ -26,7 +26,7 @@ def each(&block)
def initialize(entry, name, target)
@entry = entry
- @name = Ldapter.encode(name)
+ @name = Ldaptic.encode(name)
@type = @entry.namespace.attribute_type(@name)
@syntax = @entry.namespace.attribute_syntax(@name)
@target = target
@@ -192,7 +192,7 @@ def #{method}(*args, &block)
%w(reverse! shuffle! sort! uniq!).each do |method|
class_eval(<<-EOS, __FILE__, __LINE__.succ)
def #{method}(*args)
- Ldapter::Errors.raise(NotImplementedError.new)
+ Ldaptic::Errors.raise(NotImplementedError.new)
end
EOS
end
@@ -275,7 +275,7 @@ def typecast(value)
def user_modification_guard
if no_user_modification?
- Ldapter::Errors.raise(TypeError.new("read-only attribute #{@name}"))
+ Ldaptic::Errors.raise(TypeError.new("read-only attribute #{@name}"))
end
end
View
56 lib/ldapter/dn.rb → lib/ldaptic/dn.rb
@@ -1,15 +1,15 @@
-require 'ldapter/escape'
+require 'ldaptic/escape'
-module Ldapter
+module Ldaptic
- # Instantiate a new Ldapter::DN object with the arguments given. Unlike
- # Ldapter::DN.new(dn), this method coerces the first argument to a string,
+ # Instantiate a new Ldaptic::DN object with the arguments given. Unlike
+ # Ldaptic::DN.new(dn), this method coerces the first argument to a string,
# unless it is already a string or an array. If the first argument is nil,
# nil is returned.
def self.DN(dn, source = nil)
return if dn.nil?
dn = dn.dn if dn.respond_to?(:dn)
- if dn.kind_of?(::Ldapter::DN)
+ if dn.kind_of?(::Ldaptic::DN)
if source
dn = dn.dup
dn.source = source
@@ -30,36 +30,36 @@ def self.DN(dn, source = nil)
class DN < ::String
OID = '1.3.6.1.4.1.1466.115.121.1.12' unless defined? OID
- # Ldapter::DN[{:dc => 'com'}, {:dc => 'amazon'}]
+ # Ldaptic::DN[{:dc => 'com'}, {:dc => 'amazon'}]
# => "dc=amazon,dc=com"
def self.[](*args)
- Ldapter::DN(args.reverse)
+ Ldaptic::DN(args.reverse)
end
attr_accessor :source
- # Create a new Ldapter::DN object. dn can either be a string, or an array
+ # Create a new Ldaptic::DN object. dn can either be a string, or an array
# of pairs.
#
- # Ldapter::DN([{:cn=>"Thomas, David"}, {:dc=>"pragprog"}, {:dc=>"com"}])
+ # Ldaptic::DN([{:cn=>"Thomas, David"}, {:dc=>"pragprog"}, {:dc=>"com"}])
# # => "CN=Thomas\\, David,DC=pragprog,DC=com"
#
# The optional second object specifies either an LDAP::Conn object or a
- # Ldapter object to be used to find the DN with #find.
+ # Ldaptic object to be used to find the DN with #find.
def initialize(dn, source = nil)
@source = source
dn = dn.dn if dn.respond_to?(:dn)
if dn.respond_to?(:to_ary)
dn = dn.map do |pair|
if pair.kind_of?(Hash)
- Ldapter::RDN(pair).to_str
+ Ldaptic::RDN(pair).to_str
else
pair
end
end * ','
end
if dn.include?(".") && !dn.include?("=")
- dn = dn.split(".").map {|dc| "DC=#{Ldapter.escape(dc)}"} * ","
+ dn = dn.split(".").map {|dc| "DC=#{Ldaptic.escape(dc)}"} * ","
end
super(dn)
end
@@ -93,14 +93,14 @@ def find(source = @source)
# Convert the DN to an array of RDNs.
#
- # Ldapter::DN("cn=Thomas\\, David,dc=pragprog,dc=com").rdns
+ # Ldaptic::DN("cn=Thomas\\, David,dc=pragprog,dc=com").rdns
# # => [{:cn=>"Thomas, David"},{:dc=>"pragprog"},{:dc=>"com"}]
def rdns
rdn_strings.map {|rdn| RDN.new(rdn)}
end
def rdn_strings
- Ldapter.split(self, ?,)
+ Ldaptic.split(self, ?,)
end
def to_a
@@ -114,15 +114,15 @@ def to_a
end
def parent
- Ldapter::DN(rdns[1..-1], source)
+ Ldaptic::DN(rdns[1..-1], source)
end
def rdn
rdns.first
end
def normalize
- Ldapter::DN(rdns, source)
+ Ldaptic::DN(rdns, source)
end
def normalize!
@@ -133,15 +133,15 @@ def normalize!
# RFC4517 - Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules
def ==(other)
if other.respond_to?(:dn)
- other = Ldapter::DN(other)
+ other = Ldaptic::DN(other)
end
normalize = lambda do |hash|
hash.inject({}) do |m, (k, v)|
- m[Ldapter.encode(k).upcase] = v
+ m[Ldaptic.encode(k).upcase] = v
m
end
end
- if other.kind_of?(Ldapter::DN)
+ if other.kind_of?(Ldaptic::DN)
self.rdns == other.rdns
else
super
@@ -154,7 +154,7 @@ def ==(other)
# the same as String#[]
def [](*args)
- if args.first.kind_of?(Hash) || args.first.kind_of?(Ldapter::DN)
+ if args.first.kind_of?(Hash) || args.first.kind_of?(Ldaptic::DN)
send(:/, *args)
else
super
@@ -163,9 +163,9 @@ def [](*args)
# Prepend an RDN to the DN.
#
- # Ldapter::DN(:dc => "com")/{:dc => "foobar"} #=> "DC=foobar,DC=com"
+ # Ldaptic::DN(:dc => "com")/{:dc => "foobar"} #=> "DC=foobar,DC=com"
def /(*args)
- Ldapter::DN(args.reverse + rdns, source)
+ Ldaptic::DN(args.reverse + rdns, source)
end
# With a Hash (and only with a Hash), prepends a RDN to the DN, modifying
@@ -203,8 +203,8 @@ class RDN < Hash
def self.parse_string(string) #:nodoc:
- Ldapter.split(string, ?+).inject({}) do |hash, pair|
- k, v = Ldapter.split(pair, ?=).map {|x| Ldapter.unescape(x)}
+ Ldaptic.split(string, ?+).inject({}) do |hash, pair|
+ k, v = Ldaptic.split(pair, ?=).map {|x| Ldaptic.unescape(x)}
hash[k.downcase.to_sym] = v
hash
end
@@ -227,7 +227,7 @@ def initialize(rdn = {})
end
def /(*args)
- Ldapter::DN([self]).send(:/, *args)
+ Ldaptic::DN([self]).send(:/, *args)
end
def to_rdn
@@ -236,7 +236,7 @@ def to_rdn
def to_str
collect do |k, v|
- "#{k.kind_of?(String) ? k : Ldapter.encode(k).upcase}=#{Ldapter.escape(v)}"
+ "#{k.kind_of?(String) ? k : Ldaptic.encode(k).upcase}=#{Ldaptic.escape(v)}"
end.sort.join("+")
end
@@ -282,7 +282,7 @@ def eql?(other)
if other.respond_to?(:to_str)
to_str.casecmp(other.to_str).zero?
elsif other.kind_of?(Hash)
- eql?(Ldapter::RDN(other)) rescue false
+ eql?(Ldaptic::RDN(other)) rescue false
else
super
end
@@ -353,7 +353,7 @@ def convert_key(key)
elsif key.respond_to?(:to_sym)
key.to_sym.to_s
else
- raise TypeError, "keys in an Ldapter::RDN must be symbols", caller(1)
+ raise TypeError, "keys in an Ldaptic::RDN must be symbols", caller(1)
end.downcase.to_sym
end
View
66 lib/ldapter/entry.rb → lib/ldaptic/entry.rb
@@ -1,10 +1,10 @@
-require 'ldapter/attribute_set'
-require 'ldapter/error_set'
+require 'ldaptic/attribute_set'
+require 'ldaptic/error_set'
-module Ldapter
+module Ldaptic
- # When a new Ldapter namespace is created, a Ruby class hierarchy is
- # contructed that mirrors the server's object classes. Ldapter::Entry
+ # When a new Ldaptic namespace is created, a Ruby class hierarchy is
+ # contructed that mirrors the server's object classes. Ldaptic::Entry
# serves as the base class for this hierarchy.
class Entry
# Constructs a deep copy of a set of LDAP attributes, normalizing them to
@@ -41,7 +41,7 @@ def names
end
def has_attribute?(attribute)
- attribute = Ldapter.encode(attribute)
+ attribute = Ldaptic.encode(attribute)
may.include?(attribute) || must.include?(attribute)
end
@@ -132,7 +132,7 @@ def object_classes
#
# L::User.human_attribute_name(:givenName) #=> "Given name"
def human_attribute_name(attribute, options={})
- attribute = Ldapter.encode(attribute)
+ attribute = Ldaptic.encode(attribute)
if at = namespace.attribute_type(attribute)
attribute = at.verbose_name
end
@@ -154,7 +154,7 @@ def instantiate(attributes) #:nodoc:
logger.warn "#{name}: invalid object class for #{attributes.inspect}"
end
obj = allocate
- obj.instance_variable_set(:@dn, ::Ldapter::DN(Array(attributes.delete('dn')).first, obj))
+ obj.instance_variable_set(:@dn, ::Ldaptic::DN(Array(attributes.delete('dn')).first, obj))
obj.instance_variable_set(:@original_attributes, attributes)
obj.instance_variable_set(:@attributes, {})
obj.instance_eval { common_initializations; after_load }
@@ -172,7 +172,7 @@ def inherited(subclass) #:nodoc:
end
def initialize(data = {})
- Ldapter::Errors.raise(TypeError.new("abstract class initialized")) if self.class.oid.nil? || self.class.abstract?
+ Ldaptic::Errors.raise(TypeError.new("abstract class initialized")) if self.class.oid.nil? || self.class.abstract?
@attributes = {}
data = data.dup
if dn = data.delete('dn') || data.delete(:dn)
@@ -273,9 +273,9 @@ def to_s
# #method_missing delegates to this method, method names with underscores
# map to attributes with hyphens.
def read_attribute(key)
- key = Ldapter.encode(key)
+ key = Ldaptic.encode(key)
@attributes[key] ||= ((@original_attributes || {}).fetch(key, [])).dup
- Ldapter::AttributeSet.new(self, key, @attributes[key])
+ Ldaptic::AttributeSet.new(self, key, @attributes[key])
end
protected :read_attribute
@@ -313,11 +313,11 @@ def write_attribute(key, values)
# Note the values are not typecast and thus must be strings.
def modify_attribute(action, key, *values)
- key = Ldapter.encode(key)
- values.flatten!.map! {|v| Ldapter.encode(v)}
+ key = Ldaptic.encode(key)
+ values.flatten!.map! {|v| Ldaptic.encode(v)}
@original_attributes[key] ||= []
virgin = @original_attributes[key].dup
- original = Ldapter::AttributeSet.new(self, key, @original_attributes[key])
+ original = Ldaptic::AttributeSet.new(self, key, @original_attributes[key])
original.__send__(action, values)
begin
namespace.modify(dn, [[action, key, values]])
@@ -379,7 +379,7 @@ def may(all = true)
end
def may_must(attribute)
- attribute = Ldapter.encode(attribute)
+ attribute = Ldaptic.encode(attribute)
if must.include?(attribute)
:must
elsif may.include?(attribute)
@@ -389,13 +389,13 @@ def may_must(attribute)
def respond_to?(method, *) #:nodoc:
both = may + must
- super || (both + both.map {|x| "#{x}="} + both.map {|x| "#{x}-before-type-cast"}).include?(Ldapter.encode(method.to_sym))
+ super || (both + both.map {|x| "#{x}="} + both.map {|x| "#{x}-before-type-cast"}).include?(Ldaptic.encode(method.to_sym))
end
# Delegates to +read_attribute+ or +write_attribute+. Pops an element out
# of its set if the attribute is marked SINGLE-VALUE.
def method_missing(method, *args, &block)
- attribute = Ldapter.encode(method)
+ attribute = Ldaptic.encode(method)
if attribute[-1] == ?=
attribute.chop!
if may_must(attribute)
@@ -418,7 +418,7 @@ def method_missing(method, *args, &block)
super(method, *args, &block)
end
- # Searches for children. This is identical to Ldapter::Base#search, only
+ # Searches for children. This is identical to Ldaptic::Base#search, only
# the default base is the current object's DN.
def search(options, &block)
if options[:base].kind_of?(Hash)
@@ -467,7 +467,7 @@ def persisted?
end
def errors
- @errors ||= Ldapter::ErrorSet.new(self)
+ @errors ||= Ldaptic::ErrorSet.new(self)
end
def valid?
@@ -532,7 +532,7 @@ def reload
new = search(:scope => :base, :limit => true)
@original_attributes = new.instance_variable_get(:@original_attributes)
@attributes = new.instance_variable_get(:@attributes)
- @dn = Ldapter::DN(new.dn, self)
+ @dn = Ldaptic::DN(new.dn, self)
@children = {}
self
end
@@ -553,11 +553,11 @@ def destroy
def rename(new_rdn, delete_old = nil)
old_rdn = rdn
- if new_rdn.kind_of?(Ldapter::DN)
+ if new_rdn.kind_of?(Ldaptic::DN)
new_root = new_rdn.parent
new_rdn = new_rdn.rdn
else
- new_rdn = Ldapter::RDN(new_rdn)
+ new_rdn = Ldaptic::RDN(new_rdn)
new_root = nil
end
if delete_old.nil?
@@ -571,7 +571,7 @@ def rename(new_rdn, delete_old = nil)
end
end
end
- old_dn = Ldapter::DN(@dn, self)
+ old_dn = Ldaptic::DN(@dn, self)
@dn = nil
if new_root
self.dn = new_root / new_rdn
@@ -592,9 +592,9 @@ def rename(new_rdn, delete_old = nil)
def dn=(value)
if @dn
- Ldapter::Errors.raise(Ldapter::Error.new("can't reassign DN"))
+ Ldaptic::Errors.raise(Ldaptic::Error.new("can't reassign DN"))
end
- @dn = ::Ldapter::DN(value, self)
+ @dn = ::Ldaptic::DN(value, self)
write_attributes_from_rdn(rdn)
end
@@ -610,35 +610,35 @@ def common_initializations
end
def write_attributes_from_rdn(rdn, attributes = @attributes)
- Ldapter::RDN(rdn).each do |k, v|
+ Ldaptic::RDN(rdn).each do |k, v|
attributes[k.to_s.downcase] ||= []
attributes[k.to_s.downcase] |= [v]
end
end
def cached_child(rdn = nil)
return self if rdn.nil? || rdn.empty?
- rdn = Ldapter::RDN(rdn)
+ rdn = Ldaptic::RDN(rdn)
return @children[rdn] if @children.has_key?(rdn)
child = search(:base => rdn, :scope => :base, :limit => true)
child.instance_variable_set(:@parent, self)
@children[rdn] = child
- rescue Ldapter::Errors::NoSuchObject
+ rescue Ldaptic::Errors::NoSuchObject
end
def assign_child(rdn, child)
unless child.respond_to?(:dn)
- Ldapter::Errors.raise(TypeError.new("#{child.class} cannot be a child"))
+ Ldaptic::Errors.raise(TypeError.new("#{child.class} cannot be a child"))
end
if child.dn
- Ldapter::Errors.raise(Ldapter::Error.new("#{child.class} already has a DN of #{child.dn}"))
+ Ldaptic::Errors.raise(Ldaptic::Error.new("#{child.class} already has a DN of #{child.dn}"))
end
- rdn = Ldapter::RDN(rdn)
+ rdn = Ldaptic::RDN(rdn)
if cached_child(rdn)
- Ldapter::Errors.raise(Ldapter::Error.new("child #{[rdn, dn].join(",")} already exists"))
+ Ldaptic::Errors.raise(Ldaptic::Error.new("child #{[rdn, dn].join(",")} already exists"))
end
@children[rdn] = child
- child.dn = Ldapter::DN(dn/rdn, child)
+ child.dn = Ldaptic::DN(dn/rdn, child)
child.instance_variable_set(:@parent, self)
end
View
2 lib/ldapter/error_set.rb → lib/ldaptic/error_set.rb
@@ -1,4 +1,4 @@
-module Ldapter
+module Ldaptic
class ErrorSet < Hash
def initialize(base)
@base = base
View
10 lib/ldapter/errors.rb → lib/ldaptic/errors.rb
@@ -1,4 +1,4 @@
-module Ldapter
+module Ldaptic
class Error < ::RuntimeError
end
@@ -13,7 +13,7 @@ class ServerError < Error
attr_accessor :code
end
- # The module houses all subclasses of Ldapter::ServerError. The methods
+ # The module houses all subclasses of Ldaptic::ServerError. The methods
# contained within are for internal use only.
module Errors
@@ -99,7 +99,7 @@ class CompareTrue < ServerError
class << self
- # Provides a backtrace minus all files shipped with Ldapter.
+ # Provides a backtrace minus all files shipped with Ldaptic.
def application_backtrace
dir = File.dirname(File.dirname(__FILE__))
c = caller
@@ -108,7 +108,7 @@ def application_backtrace
end
# Raise an exception (object only, no strings or classes) with the
- # backtrace stripped of all Ldapter files.
+ # backtrace stripped of all Ldaptic files.
def raise(exception)
exception.set_backtrace(application_backtrace)
Kernel.raise exception
@@ -122,7 +122,7 @@ def for(code, message = nil) #:nodoc:
exception
end
- # Given an error code and a message, raise an Ldapter::ServerError unless
+ # Given an error code and a message, raise an Ldaptic::ServerError unless
# the code is zero. The right subclass is selected automatically if it
# is available.
def raise_unless_zero(code, message = nil)
View
10 lib/ldapter/escape.rb → lib/ldaptic/escape.rb
@@ -1,4 +1,4 @@
-module Ldapter
+module Ldaptic
# Encode an object with LDAP semantics. Generally this is just to_s, but
# dates and booleans get special treatment.
@@ -24,7 +24,7 @@ def self.encode(value)
#
# If the first argument is not a string, it is handed off to LDAP::encode.
def self.escape(string, allow_asterisks = false)
- string = Ldapter.encode(string)
+ string = Ldaptic.encode(string)
enc = lambda { |l| "\\%02X" % l.ord }
string.gsub!(/[()\\\0-\37"+,;<>]/, &enc)
string.gsub!(/\A[# ]| \Z/, &enc)
@@ -74,9 +74,9 @@ def self.unescape(string)
# Split on a given character where it is not escaped. Either an integer or
# string represenation of the character may be used.
#
- # Ldapter.split("a*b", '*') # => ["a","b"]
- # Ldapter.split("a\\*b", '*') # => ["a\\*b"]
- # Ldapter.split("a\\\\*b", ?*) # => ["a\\\\","b"]
+ # Ldaptic.split("a*b", '*') # => ["a","b"]
+ # Ldaptic.split("a\\*b", '*') # => ["a\\*b"]
+ # Ldaptic.split("a\\\\*b", ?*) # => ["a\\\\","b"]
def self.split(string, character)
return [] if string.empty?
array = [""]
View
64 lib/ldapter/filter.rb → lib/ldaptic/filter.rb
@@ -1,14 +1,14 @@
-require 'ldapter/escape'
+require 'ldaptic/escape'
-module Ldapter
+module Ldaptic
- # If the argument is already a valid Ldapter::Filter object, return it
+ # If the argument is already a valid Ldaptic::Filter object, return it
# untouched. Otherwise, pass it to the appropriate constructer of the
# appropriate subclass.
#
- # Ldapter::Filter("(cn=Wu*)").to_s #=> '(cn=Wu*)'
- # Ldapter::Filter({:cn=>"Wu*"}).to_s #=> '(cn=Wu\2A)'
- # Ldapter::Filter(["(cn=?*)","Wu*"]).to_s #=> '(cn=Wu\2A*)'
+ # Ldaptic::Filter("(cn=Wu*)").to_s #=> '(cn=Wu*)'
+ # Ldaptic::Filter({:cn=>"Wu*"}).to_s #=> '(cn=Wu\2A)'
+ # Ldaptic::Filter(["(cn=?*)","Wu*"]).to_s #=> '(cn=Wu\2A*)'
def self.Filter(argument)
case argument
when Filter::Abstract then argument
@@ -18,7 +18,7 @@ def self.Filter(argument)
when String then Filter::String .new(argument)
when Symbol then Filter::Attribute.new(argument)
when Proc, Method
- Ldapter::Filter(if argument.arity > 0
+ Ldaptic::Filter(if argument.arity > 0
argument.call(Filter::Spawner)
elsif Filter::Spawner.respond_to?(:instance_exec)
Filter::Spawner.instance_exec(&argument)
@@ -29,7 +29,7 @@ def self.Filter(argument)
end
end
- # See Ldapter.Filter for the contructor and Ldapter::Filter::Abstract for
+ # See Ldaptic.Filter for the contructor and Ldaptic::Filter::Abstract for
# methods common to all filters.
#
# Useful subclasses include String, Array, and Hash.
@@ -50,7 +50,7 @@ def |(other)
# Negate a filter.
#
- # ~Ldapter::Filter("(a=1)").to_s # => "(!(a=1))"
+ # ~Ldaptic::Filter("(a=1)").to_s # => "(!(a=1))"
def ~
Not.new(self)
end
@@ -64,9 +64,9 @@ def to_s
def inspect
if string = process
- "#<#{Ldapter::Filter.inspect} #{string}>"
+ "#<#{Ldaptic::Filter.inspect} #{string}>"
else
- "#<#{Ldapter::Filter.inspect} invalid>"
+ "#<#{Ldaptic::Filter.inspect} invalid>"
end
end
@@ -106,8 +106,8 @@ def process
# This class is used for raw LDAP queries. Note that the outermost set of
# parentheses *must* be used.
#
- # Ldapter::Filter("a=1") # Wrong
- # Ldapter::Filter("(a=1)") # Correct
+ # Ldaptic::Filter("a=1") # Wrong
+ # Ldaptic::Filter("(a=1)") # Correct
class String < Abstract
def initialize(string) #:nodoc:
@@ -123,23 +123,23 @@ def process
# Does ? parameter substitution.
#
- # Ldapter::Filter(["(cn=?*)", "Sm"]).to_s #=> "(cn=Sm*)"
+ # Ldaptic::Filter(["(cn=?*)", "Sm"]).to_s #=> "(cn=Sm*)"
class Array < Abstract
def initialize(array) #:nodoc:
@template = array.first
@parameters = array[1..-1]
end
def process
parameters = @parameters.dup
- string = @template.gsub('?') { Ldapter.escape(parameters.pop) }
+ string = @template.gsub('?') { Ldaptic.escape(parameters.pop) }
end
end
- # Used in the implementation of Ldapter::Filter::And and
- # Ldapter::Filter::Or. For internal use only.
+ # Used in the implementation of Ldaptic::Filter::And and
+ # Ldaptic::Filter::Or. For internal use only.
class Join < Abstract
def initialize(operator, *args) #:nodoc:
- @array = [operator] + args.map {|arg| Ldapter::Filter(arg)}
+ @array = [operator] + args.map {|arg| Ldaptic::Filter(arg)}
end
def process
"(#{@array*''})" if @array.compact.size > 1
@@ -163,7 +163,7 @@ def initialize(*args)
class Not < Abstract
def initialize(object)
- @object = Ldapter::Filter(object)
+ @object = Ldaptic::Filter(object)
end
def process
process = @object.process and "(!#{process})"
@@ -175,7 +175,7 @@ def to_net_ldap_filter #:nodoc:
# A hash is the most general and most useful type of filter builder.
#
- # Ldapter::Filter(
+ # Ldaptic::Filter(
# :givenName => "David",
# :sn! => "Thomas",
# :postalCode => (70000..80000)
@@ -184,12 +184,12 @@ def to_net_ldap_filter #:nodoc:
# Including :* => true allows asterisks to pass through unaltered.
# Otherwise, they are escaped.
#
- # Ldapter::Filter(:givenName => "Dav*", :* => true).to_s # => "(givenName=Dav*)"
+ # Ldaptic::Filter(:givenName => "Dav*", :* => true).to_s # => "(givenName=Dav*)"
class Hash < Abstract
attr_accessor :escape_asterisks
attr_reader :hash
- # Call Ldapter::Filter(hash) instead of instantiating this class
+ # Call Ldaptic::Filter(hash) instead of instantiating this class
# directly.
def initialize(hash)
@hash = hash.dup
@@ -238,35 +238,35 @@ def process
inverse = @inverse
operator = "=" if operator == "=="
if v.respond_to?(:to_ary)
- q = "(|" + v.map {|e| "(#{Ldapter.encode(k)}=#{Ldapter.escape(e, star)})"}.join + ")"
+ q = "(|" + v.map {|e| "(#{Ldaptic.encode(k)}=#{Ldaptic.escape(e, star)})"}.join + ")"
elsif v.kind_of?(Range)
q = []
if v.first != -1.0/0
- q << "(#{Ldapter.encode(k)}>=#{Ldapter.escape(v.first, star)})"
+ q << "(#{Ldaptic.encode(k)}>=#{Ldaptic.escape(v.first, star)})"
end
if v.last != 1.0/0
if v.exclude_end?
- q << "(!(#{Ldapter.encode(k)}>=#{Ldapter.escape(v.last, star)}))"
+ q << "(!(#{Ldaptic.encode(k)}>=#{Ldaptic.escape(v.last, star)}))"
else
- q << "(#{Ldapter.encode(k)}<=#{Ldapter.escape(v.last, star)})"
+ q << "(#{Ldaptic.encode(k)}<=#{Ldaptic.escape(v.last, star)})"
end
end
q = "(&#{q*""})"
elsif v == true || v == :*
- q = "(#{Ldapter.encode(k)}=*)"
+ q = "(#{Ldaptic.encode(k)}=*)"
elsif !v
- q = "(#{Ldapter.encode(k)}=*)"
+ q = "(#{Ldaptic.encode(k)}=*)"
inverse ^= true
else
- q = "(#{Ldapter.encode(k)}#{operator}#{Ldapter.escape(v, star)})"
+ q = "(#{Ldaptic.encode(k)}#{operator}#{Ldaptic.escape(v, star)})"
end
inverse ? "(!#{q})" : q
end
end
module Conversions #:nodoc:
def to_ldap_filter
- Ldapter::Filter(self)
+ Ldaptic::Filter(self)
end
end
@@ -275,8 +275,8 @@ def to_ldap_filter
end
class Hash
- include Ldapter::Filter::Conversions
+ include Ldaptic::Filter::Conversions
end
class String
- include Ldapter::Filter::Conversions
+ include Ldaptic::Filter::Conversions
end
View
48 lib/ldapter/methods.rb → lib/ldaptic/methods.rb
@@ -1,10 +1,10 @@
-module Ldapter
+module Ldaptic
- # These methods are accessible directly from the Ldapter object.
+ # These methods are accessible directly from the Ldaptic object.
module Methods
# For duck typing.
- def to_ldapter
+ def to_ldaptic
self
end
@@ -15,7 +15,7 @@ def build_hierarchy
hash[k.sup] << k; hash
end
@object_classes = {}
- add_constants(hash, Ldapter::Entry)
+ add_constants(hash, Ldaptic::Entry)
nil
end
private :build_hierarchy
@@ -50,11 +50,11 @@ def add_constants(klasses, superclass)
# Set a new base DN. Generally, the base DN should be set when the
# namespace is created and left unchanged.
def base=(dn)
- @base = Ldapter::DN(dn, self)
+ @base = Ldaptic::DN(dn, self)
end
# Access the base DN.
def base
- @base ||= Ldapter::DN(adapter.default_base_dn, self)
+ @base ||= Ldaptic::DN(adapter.default_base_dn, self)
end
alias dn base
@@ -64,7 +64,7 @@ def logger
# Find an RDN relative to the base. This method is experimental.
#
- # class L < Ldapter::Class(:base => "DC=ruby-lang,DC=org", ...)
+ # class L < Ldaptic::Class(:base => "DC=ruby-lang,DC=org", ...)
# end
#
# (L/{:cn => "Matz"}).dn #=> "CN=Matz,DC=ruby-lang,DC=org"
@@ -86,7 +86,7 @@ def [](*args)
end
end
- # Like Ldapter::Entry#[]= for the root node. Only works for assigning
+ # Like Ldaptic::Entry#[]= for the root node. Only works for assigning
# children. This method is experimental.
#
# MyCompany[:cn=>"New Employee"] = MyCompany::User.new
@@ -114,19 +114,19 @@ def search_options(options = {})
original_scope = options[:scope]
options[:scope] ||= :subtree
if !options[:scope].kind_of?(Integer) && options[:scope].respond_to?(:to_sym)
- options[:scope] = Ldapter::SCOPES[options[:scope].to_sym]
+ options[:scope] = Ldaptic::SCOPES[options[:scope].to_sym]
end
- Ldapter::Errors.raise(ArgumentError.new("invalid scope #{original_scope.inspect}")) unless Ldapter::SCOPES.values.include?(options[:scope])
+ Ldaptic::Errors.raise(ArgumentError.new("invalid scope #{original_scope.inspect}")) unless Ldaptic::SCOPES.values.include?(options[:scope])
options[:filter] ||= "(objectClass=*)"
if [Hash, Proc, Method, Symbol, Array].include?(options[:filter].class)
- options[:filter] = Ldapter::Filter(options[:filter])
+ options[:filter] = Ldaptic::Filter(options[:filter])
end
if options[:attributes].respond_to?(:to_ary)
- options[:attributes] = options[:attributes].map {|x| Ldapter.encode(x)}
+ options[:attributes] = options[:attributes].map {|x| Ldaptic.encode(x)}
elsif options[:attributes]
- options[:attributes] = [Ldapter.encode(options[:attributes])]
+ options[:attributes] = [Ldaptic.encode(options[:attributes])]
end
if options[:attributes]
options[:attributes] |= ["objectClass"]
@@ -145,7 +145,7 @@ def find_one(dn, options)
# For a missing DN, the error will be raised automatically. If the
# DN does exist but is not returned (e.g., it doesn't match the given
# filter), we'll simulate it instead.
- Ldapter::Errors.raise(Ldapter::Errors::NoSuchObject.new("record not found for #{dn}"))
+ Ldaptic::Errors.raise(Ldaptic::Errors::NoSuchObject.new("record not found for #{dn}"))
end
objects.first
end
@@ -187,7 +187,7 @@ def first(options = {})
# the base), and <tt>:subtree</tt> (the base, children, and all
# descendants). The default is <tt>:subtree</tt>.
# * <tt>:filter</tt>: A standard LDAP filter. This can be a string, an
- # Ldapter::Filter object, or parameters for Ldapter::Filter().
+ # Ldaptic::Filter object, or parameters for Ldaptic::Filter().
# * <tt>:limit</tt>: Maximum number of results to return. If the value
# is a literal +true+, the first item is returned directly (or +nil+ if
# nothing was found). For a literal +false+, an array always returned
@@ -197,7 +197,7 @@ def first(options = {})
# Array but rather a String or a Symbol, an array of attributes is
# returned rather than an array of objects.
# * <tt>:instantiate</tt>: If this is false, a raw hash is returned
- # rather than an Ldapter object. Combined with a String or Symbol
+ # rather than an Ldaptic object. Combined with a String or Symbol
# argument to <tt>:attributes</tt>, a +false+ value here causes the
# attribute not to be typecast.
#
@@ -228,7 +228,7 @@ def search(options = {}, &block)
entry = klass.instantiate(entry)
end
if one_attribute
- entry = entry[Ldapter.encode(one_attribute)]
+ entry = entry[Ldaptic.encode(one_attribute)]
entry = entry.one if entry.respond_to?(:one)
end
ary << entry
@@ -241,7 +241,7 @@ def search(options = {}, &block)
def normalize_attributes(attributes)
attributes.inject({}) do |h, (k, v)|
- h.update(Ldapter.encode(k) => v.respond_to?(:before_type_cast) ? v.before_type_cast : Array(v))
+ h.update(Ldaptic.encode(k) => v.respond_to?(:before_type_cast) ? v.before_type_cast : Array(v))
end
end
private :normalize_attributes
@@ -259,7 +259,7 @@ def modify(dn, attributes)
if attributes.kind_of?(Hash)
attributes = normalize_attributes(attributes)
else
- attributes = attributes.map {|(action, key, values)| [action, Ldapter.encode(key), Array(values)]}
+ attributes = attributes.map {|(action, key, values)| [action, Ldaptic.encode(key), Array(values)]}
end
adapter.modify(dn, attributes) unless attributes.empty?
end
@@ -279,7 +279,7 @@ def rename(dn, new_rdn, delete_old, *args)
# Performs an LDAP compare.
def compare(dn, key, value)
log_dispatch(:compare, dn, key, value)
- adapter.compare(dn, Ldapter.encode(key), Ldapter.encode(value))
+ adapter.compare(dn, Ldaptic.encode(key), Ldaptic.encode(value))
end
def dit_content_rule(oid)
@@ -316,14 +316,14 @@ def object_class(klass)
@object_classes[klass.to_s.tr('-', '_').downcase]
end
- # Returns an Ldapter::Schema::AttibuteType object encapsulating server
+ # Returns an Ldaptic::Schema::AttibuteType object encapsulating server
# provided information about an attribute type.
#
# L.attribute_type(:cn).desc #=> "RFC2256: common name..."
def attribute_type(attribute)
- adapter.attribute_type(Ldapter.encode(attribute))
+ adapter.attribute_type(Ldaptic.encode(attribute))
end
- # Returns an Ldapter::Schema::LdapSyntax object encapsulating server
+ # Returns an Ldaptic::Schema::LdapSyntax object encapsulating server
# provided information about the syntax of an attribute.
#
# L.attribute_syntax(:cn).desc #=> "Directory String"
@@ -342,7 +342,7 @@ def authenticate(dn, password)
adapter.authenticate(dn, password)
end
- # Delegated to from Ldapter::Entry for Active Model compliance.
+ # Delegated to from Ldaptic::Entry for Active Model compliance.
def model_name
if defined?(ActiveSupport::ModelName)
ActiveSupport::ModelName.new(name)
View
10 lib/ldapter/schema.rb → lib/ldaptic/schema.rb
@@ -1,4 +1,4 @@
-module Ldapter
+module Ldaptic
# RFC4512 - LDAP: Directory Information Models
module Schema
@@ -197,7 +197,7 @@ def syntax_len
syntax_attribute && syntax_attribute[/\{(.*)\}/, 1].to_i
end
def syntax_object(*args)
- Ldapter::SYNTAXES[syntax_oid]
+ Ldaptic::SYNTAXES[syntax_oid]
end
alias syntax syntax_object
end
@@ -215,9 +215,9 @@ class MatchingRuleUse < NameDescObsoleteDefiniton
class LdapSyntax < AbstractDefinition
attr_ldap_qdstring :desc
- # Returns the appropriate parser from the Ldapter::Syntaxes module.
+ # Returns the appropriate parser from the Ldaptic::Syntaxes module.
def object
- Ldapter::Syntaxes.for(desc.delete(" "))
+ Ldaptic::Syntaxes.for(desc.delete(" "))
end
end
@@ -243,4 +243,4 @@ class NameForm < NameDescObsoleteDefiniton
end
end
-require 'ldapter/syntaxes'
+require 'ldaptic/syntaxes'
View
20 lib/ldapter/syntaxes.rb → lib/ldaptic/syntaxes.rb
@@ -1,7 +1,7 @@
-require 'ldapter/schema'
-require 'ldapter/errors'
+require 'ldaptic/schema'
+require 'ldaptic/errors'
-module Ldapter
+module Ldaptic
# RFC2252. Second column is "Human Readable"
syntax_string = <<-EOF
@@ -72,7 +72,7 @@ module Ldapter
if h == "N"
hash[:x_not_human_readable] = "TRUE"
end
- syntax = Ldapter::Schema::LdapSyntax.allocate
+ syntax = Ldaptic::Schema::LdapSyntax.allocate
syntax.instance_variable_set(:@oid, oid)
syntax.instance_variable_set(:@attributes, hash)
SYNTAXES[oid] = syntax
@@ -84,8 +84,8 @@ module Ldapter
module Syntaxes
# Returns the class for a given syntax name. Falls back to
# OctetString if there is not a more specific handler.
- # Ldapter::Syntaxes.for("Generalized Time")
- # #=> Ldapter::Syntaxes::GeneralizedTime
+ # Ldaptic::Syntaxes.for("Generalized Time")
+ # #=> Ldaptic::Syntaxes::GeneralizedTime
def self.for(string)
string = string.delete(' ')
if const_defined?(string)
@@ -111,7 +111,7 @@ def printable?(string)
end
def format(value)
- Ldapter.encode(value.kind_of?(Symbol) ? value.to_s : value)
+ Ldaptic.encode(value.kind_of?(Symbol) ? value.to_s : value)
end
def error(value)
@@ -171,7 +171,7 @@ def error(string)
class DN < Abstract
def parse(string)
- ::Ldapter::DN(string, @object).freeze
+ ::Ldaptic::DN(string, @object).freeze
end
end
@@ -240,7 +240,7 @@ def error(string)
class LDAPSyntaxDescription < Abstract
def parse(string)
- Ldapter::Schema::LdapSyntax.new(string)
+ Ldaptic::Schema::LdapSyntax.new(string)
end
end
@@ -298,7 +298,7 @@ class TelexNumber < FacsimileTelephoneNumber
class_eval(<<-EOS, __FILE__, __LINE__.succ)
class #{syntax}Description < Abstract
def parse(string)
- Ldapter::Schema::#{syntax}.new(string)
+ Ldaptic::Schema::#{syntax}.new(string)
end
end
EOS
View
110 test/ldapter_dn_test.rb
@@ -1,110 +0,0 @@
-$:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
-require 'ldapter/dn'
-require 'test/unit'
-
-class LdapterDNTest < Test::Unit::TestCase
-
- class FakeSearch
- def search(options)
- [options] end
- end
-
- class FakeSearch2
- def search2(*args)
- [args]
- end
- alias search2_ext search2
- end
-
- def test_constructor
- assert_equal "dc=foo,ba=\\23#\\20,zy=x", Ldapter::DN([{"dc"=>"foo"},{"ba"=>"## "},{"zy"=>"x"}]).downcase
- assert_equal %w(BA=bar DC=foo), Ldapter::DN([{:dc=>"foo",:ba=>"bar"}]).split('+').sort
- assert_equal "DC=pragprog,DC=com", Ldapter::DN("pragprog.com")
- assert_equal "DC=com", Ldapter::DN(:dc=>"com")
- assert_equal nil, Ldapter::DN(nil)
- end
-
- def test_rdns
- assert_equal [{:dc=>"pragprog"},{:dc=>"com"}], Ldapter::DN("dc=pragprog,dc=com").rdns
- assert_equal [{:a=>",",:b=>"+"},{:c=>"\\"}], Ldapter::DN("a=\\,+b=\\+,c=\\\\").rdns
- assert_equal [{:a=>" #"}], Ldapter::DN("a=\\20\\#").rdns
- assert_equal [{:a=>"bcdefg"}], Ldapter::DN("a=#626364656667").rdns
- assert Ldapter::DN("DC=foo").include?(:dc=>"Foo")
- assert !Ldapter::DN("dc=foo").include?(:dc=>"Bar")
- end
-
- def test_parent
- assert_equal Ldapter::DN("dc=com"), Ldapter::DN("dc=pragprog,dc=com").parent
- assert_instance_of Ldapter::RDN, Ldapter::DN("dc=pragprog,dc=com").rdn
- end
-
- def test_children
- assert_equal Ldapter::DN("dc=pragprog,dc=com"), Ldapter::DN("dc=com")/"dc=pragprog"
- assert_equal Ldapter::DN("DC=pragprog,DC=com"), Ldapter::DN([:dc=>"com"])/{:dc=>"pragprog"}
- assert_equal Ldapter::DN("DC=pragprog,DC=com"), Ldapter::DN([:dc=>"com"])[:dc=>"pragprog"]
- dn = Ldapter::DN("DC=com")
- dn << {:dc=>"pragprog"}
- assert_equal Ldapter::DN("DC=pragprog,DC=com"), dn
- end
-
- def test_equality
- assert_equal Ldapter::DN("dc=foo"), Ldapter::DN("DC=foo")
- assert_equal Ldapter::RDN(:dc => "com"), Ldapter::RDN('DC' => 'COM')
- assert Ldapter::RDN(:dc => "com") != {Object.new => true}
- assert Ldapter::RDN(:dc => "com") != 42
- end
-
- def test_still_acts_like_a_string
- dn = Ldapter::DN("a=b")
- assert_equal ?a, dn[0]
- assert_equal dn, "a=b"
- assert_kind_of String, Array(dn).first
- assert_raise(NoMethodError) { dn.unknown_method }
- assert dn.include?("=")
- assert_equal "a=bc", (Ldapter::DN("a=b") << "c")
- end
-
- def test_should_search
- dn = Ldapter::DN("a=b", FakeSearch.new)
- assert_equal "a=b", dn.find[:base]
- dn = Ldapter::DN(dn, FakeSearch2.new)
- assert_equal "a=b", dn.find.first
- end
-
- def test_rdn
- rdn = Ldapter::RDN.new("street=Main+cn=Doe, John")
- assert_kind_of Ldapter::RDN, rdn.dup
- assert_kind_of Ldapter::RDN, rdn.clone
- assert_equal "CN=Doe\\2C John+STREET=Main", rdn.to_str
- assert_equal "MAIN", rdn.upcase.street
- assert_equal "Main", rdn["Street"]
- rdn.downcase!
- assert_equal "main", rdn.street
- assert_equal "main", rdn.delete(:Street)
- assert_equal "CN=doe\\2C john+STREET=Main", rdn.merge(:street=>"Main").to_str
- end
-
- def test_rdn_lookup
- rdn = Ldapter::RDN.new(:street=>"Main", :cn=>"Doe, John")
- assert_equal "OU=Corporate,CN=Doe\\2C John+STREET=Main", rdn[:ou=>"Corporate"].to_str
- assert rdn.has_key?(:street)
- assert rdn.include?('Street')
- assert_equal "CN=", rdn[(0..2)]
- assert_equal ["Main", "Doe, John"], rdn.values_at(:street, 'CN')
- error_class = {}.fetch(1) rescue $!.class
- assert_raise(error_class) { rdn.fetch(:uid) }
- assert_nothing_raised { rdn.fetch("STREET") }
- end
-
- def test_rdn_as_key
- hash = {}
- hash[Ldapter::RDN(:cn => "Doe, John")] = true
- assert hash[Ldapter::RDN("Cn=doe\\, john")]
- end
-
- def test_rdn_should_raise_type_error
- assert_raise(TypeError) { Ldapter::RDN(Object.new) }
- assert_raise(TypeError) { Ldapter::RDN(Object.new => "whee") }
- end
-
-end
View
47 test/ldapter_escape_test.rb
@@ -1,47 +0,0 @@
-$:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
-require 'ldapter/escape'
-require 'test/unit'
-
-class LdapterEscapeTest < Test::Unit::TestCase
-
- PAIRS = [
- ["\\28Hello\\5C\\2Aworld!\\29", "(Hello\\*world!)"],
- ["\\23Good-bye\\2C world\\20", "#Good-bye, world "]
- ]
-
- def test_encode
- assert_equal "FALSE", Ldapter.encode(false)
- assert_equal "20000101123456.000000Z", Ldapter.encode(Time.utc(2000,1,1,12,34,56))
- assert_equal "foo-bar", Ldapter.encode(:foo_bar)
- end
-
- def test_escape
- PAIRS.each do |escaped, unescaped|
- assert_equal escaped, Ldapter.escape(unescaped)
- end
- assert_equal "a*b\\2Ac\\00", Ldapter.escape("a*b**c\0", true)
- assert_equal "TRUE", Ldapter.escape(true)
- assert_equal "foo-bar", Ldapter.escape(:foo_bar)
- end
-
- def test_should_not_mutate
- x = ","
- assert_equal "\\2C", Ldapter.escape(x).upcase
- assert_equal ",", x
- end
-
- def test_unescape
- PAIRS.each do |escaped, unescaped|
- assert_equal unescaped, Ldapter.unescape(escaped)
- end
- assert_equal " whitespace!", Ldapter.unescape(" \\20whitespace\\! ")
- assert_equal "abcde", Ldapter.unescape("#6162636465")
- end
-
- def test_split
- assert_equal ["a","b"], Ldapter.split("a*b", '*')
- assert_equal ["a\\*b"], Ldapter.split("a\\*b", '*')
- assert_equal ["a\\\\","b"], Ldapter.split("a\\\\*b", ?*)
- end
-
-end
View
66 test/ldapter_syntaxes_test.rb
@@ -1,66 +0,0 @@
-require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
-require 'ldapter/syntaxes'
-
-class LdapterSyntaxesTest < Test::Unit::TestCase
-
- def test_for
- assert_equal Ldapter::Syntaxes::GeneralizedTime, Ldapter::Syntaxes.for("Generalized Time")
- end
-
- def test_bit_string
- assert_nil Ldapter::Syntaxes::BitString.new.error("'01'B")
- assert_not_nil Ldapter::Syntaxes::BitString.new.error("01'B")
- end
-
- def test_boolean
- assert_equal true, Ldapter::Syntaxes::Boolean.parse("TRUE")
- assert_equal false, Ldapter::Syntaxes::Boolean.parse("FALSE")
- assert_equal "TRUE", Ldapter::Syntaxes::Boolean.format(true)
- assert_equal "FALSE", Ldapter::Syntaxes::Boolean.format(false)
- end
-
- def test_postal_address
- assert_not_nil Ldapter::Syntaxes::PostalAddress.new.error('\\a')
- end
-
- def test_generalized_time
- assert_equal Time.utc(2000,1,1,12,34,56), Ldapter::Syntaxes::GeneralizedTime.parse("20000101123456.0Z")
- assert_equal Time.utc(2000,1,1,12,34,56), Ldapter::Syntaxes::GeneralizedTime.parse("20000101123456.0Z")
- assert_equal 1601, Ldapter::Syntaxes::GeneralizedTime.parse("16010101000001.0Z").year
- assert_equal "20000101123456.000000Z", Ldapter::Syntaxes::GeneralizedTime.format(Time.utc(2000,1,1,12,34,56))
- end
-
- def test_ia5_string
- assert_nil Ldapter::Syntaxes::IA5String.new.error('a')
- end
-
- def test_integer
- assert_equal 1, Ldapter::Syntaxes::INTEGER.parse("1")
- assert_equal "1", Ldapter::Syntaxes::INTEGER.format(1)
- end
-
- def test_printable_string
- assert_nil Ldapter::Syntaxes::PrintableString.new.error("Az0'\"()+,-./:? =")
- assert_not_nil Ldapter::Syntaxes::PrintableString.new('$')
- assert_not_nil Ldapter::Syntaxes::PrintableString.new("\\")
- assert_not_nil Ldapter::Syntaxes::PrintableString.new("\t")
- end
-
- def test_country_string
- assert_nil Ldapter::Syntaxes::CountryString.new.error('ab')
- assert_not_nil Ldapter::Syntaxes::CountryString.new.error('a')
- assert_not_nil Ldapter::Syntaxes::CountryString.new.error('abc')
- assert_not_nil Ldapter::Syntaxes::CountryString.new.error('a_')
- end
-
- def test_delivery_method
- assert_not_nil Ldapter::Syntaxes::DeliveryMethod.new.error('')
- end
-
- def test_facsimile_telephone_number
- assert_nil Ldapter::Syntaxes::FacsimileTelephoneNumber.new.error("911")
- assert_nil Ldapter::Syntaxes::FacsimileTelephoneNumber.new.error("911$b4Length")
- assert_not_nil Ldapter::Syntaxes::FacsimileTelephoneNumber.new("\t")
- end
-
-end
View
6 test/ldapter_active_model_test.rb → test/ldaptic_active_model_test.rb
@@ -1,12 +1,12 @@
require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
-require 'ldapter'
+require 'ldaptic'
require File.join(File.dirname(File.expand_path(__FILE__)),'/mock_adapter')
require 'active_model'
-class LdapterActiveModelTest < Test::Unit::TestCase
+class LdapticActiveModelTest < Test::Unit::TestCase
include ActiveModel::Lint::Tests
- class Mock < Ldapter::Class(:adapter => :mock)
+ class Mock < Ldaptic::Class(:adapter => :mock)
end
def setup
View
18 test/ldapter_adapters_test.rb → test/ldaptic_adapters_test.rb
@@ -1,12 +1,12 @@
require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
-require 'ldapter/adapters'
-require 'ldapter/adapters/net_ldap_adapter'
-require 'ldapter/adapters/ldap_conn_adapter'
+require 'ldaptic/adapters'
+require 'ldaptic/adapters/net_ldap_adapter'
+require 'ldaptic/adapters/ldap_conn_adapter'
-class LdapterAdaptersTest < Test::Unit::TestCase
+class LdapticAdaptersTest < Test::Unit::TestCase
def setup
- @ldap_conn = Ldapter::Adapters::LDAPConnAdapter.allocate
- @net_ldap = Ldapter::Adapters::NetLDAPAdapter.allocate
+ @ldap_conn = Ldaptic::Adapters::LDAPConnAdapter.allocate
+ @net_ldap = Ldaptic::Adapters::NetLDAPAdapter.allocate
end
def test_should_parameterize_search_options
@@ -27,9 +27,9 @@ def test_should_recapitalize
end
def test_should_reject_invalid_adapter_options
- assert_raise(ArgumentError) { Ldapter::Adapters.for(:adapter => "fake") }
- assert_raise(TypeError) { Ldapter::Adapters.for(Object.new) }
- assert_not_nil Ldapter::Adapters.for(@ldap_conn)
+ assert_raise(ArgumentError) { Ldaptic::Adapters.for(:adapter => "fake") }
+ assert_raise(TypeError) { Ldaptic::Adapters.for(Object.new) }
+ assert_not_nil Ldaptic::Adapters.for(@ldap_conn)
end
end
View
6 test/ldapter_attribute_set_test.rb → test/ldaptic_attribute_set_test.rb
@@ -1,9 +1,9 @@
require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
-require 'ldapter'
+require 'ldaptic'
require File.join(File.dirname(File.expand_path(__FILE__)),'/mock_adapter')
-class LdapterAttributeSetTest < Test::Unit::TestCase
- class Mock < Ldapter::Class(:adapter => :mock)
+class LdapticAttributeSetTest < Test::Unit::TestCase
+ class Mock < Ldaptic::Class(:adapter => :mock)
end
def setup
View
110 test/ldaptic_dn_test.rb
@@ -0,0 +1,110 @@
+$:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
+require 'ldaptic/dn'
+require 'test/unit'
+
+class LdapticDNTest < Test::Unit::TestCase
+
+ class FakeSearch
+ def search(options)
+ [options] end
+ end
+
+ class FakeSearch2
+ def search2(*args)
+ [args]
+ end
+ alias search2_ext search2
+ end
+
+ def test_constructor
+ assert_equal "dc=foo,ba=\\23#\\20,zy=x", Ldaptic::DN([{"dc"=>"foo"},{"ba"=>"## "},{"zy"=>"x"}]).downcase
+ assert_equal %w(BA=bar DC=foo), Ldaptic::DN([{:dc=>"foo",:ba=>"bar"}]).split('+').sort
+ assert_equal "DC=pragprog,DC=com", Ldaptic::DN("pragprog.com")
+ assert_equal "DC=com", Ldaptic::DN(:dc=>"com")
+ assert_equal nil, Ldaptic::DN(nil)
+ end
+
+ def test_rdns
+ assert_equal [{:dc=>"pragprog"},{:dc=>"com"}], Ldaptic::DN("dc=pragprog,dc=com").rdns
+ assert_equal [{:a=>",",:b=>"+"},{:c=>"\\"}], Ldaptic::DN("a=\\,+b=\\+,c=\\\\").rdns
+ assert_equal [{:a=>" #"}], Ldaptic::DN("a=\\20\\#").rdns
+ assert_equal [{:a=>"bcdefg"}], Ldaptic::DN("a=#626364656667").rdns
+ assert Ldaptic::DN("DC=foo").include?(:dc=>"Foo")
+ assert !Ldaptic::DN("dc=foo").include?(:dc=>"Bar")
+ end
+
+ def test_parent
+ assert_equal Ldaptic::DN("dc=com"), Ldaptic::DN("dc=pragprog,dc=com").parent
+ assert_instance_of Ldaptic::RDN, Ldaptic::DN("dc=pragprog,dc=com").rdn
+ end
+
+ def test_children
+ assert_equal Ldaptic::DN("dc=pragprog,dc=com"), Ldaptic::DN("dc=com")/"dc=pragprog"
+ assert_equal Ldaptic::DN("DC=pragprog,DC=com"), Ldaptic::DN([:dc=>"com"])/{:dc=>"pragprog"}
+ assert_equal Ldaptic::DN(