NAME
SPOPS::LDAP - Implement object persistence in an LDAP datastore
SYNOPSIS
use strict;
use SPOPS::Initialize;
# Normal SPOPS configuration
my $config = {
class => 'My::LDAP',
isa => [ qw/ SPOPS::LDAP / ],
field => [ qw/ cn sn givenname displayname mail
telephonenumber objectclass uid ou / ],
id_field => 'uid',
ldap_base_dn => 'ou=People,dc=MyCompany,dc=com',
multivalue => [ qw/ objectclass / ],
creation_security => {
u => undef,
g => { 3 => 'WRITE' },
w => 'READ',
},
track => { create => 0, update => 1, remove => 1 },
display => { url => '/Person/show/' },
name => 'givenname',
object_name => 'Person',
};
# Minimal connection handling...
sub My::LDAP::global_datasource_handle {
my $ldap = Net::LDAP->new( 'localhost' );
$ldap->bind;
return $ldap;
}
# Create the class
SPOPS::Initialize->process({ config => $config });
# Search for a group of objects and display information
my $ldap_filter = '&(objectclass=inetOrgPerson)(mail=*cwinters.com)';
my $list = My::LDAP->fetch_group({ where => $ldap_filter });
foreach my $object ( @{ $list } ) {
print "Name: $object->{givenname} at $object->{mail}\n";
}
# The same thing, but with an iterator
my $ldap_filter = '&(objectclass=inetOrgPerson)(mail=*cwinters.com)';
my $iter = My::LDAP->fetch_iterator({ where => $ldap_filter });
while ( my $object = $iter->get_next ) {
print "Name: $object->{givenname} at $object->{mail}\n";
}
DESCRIPTION
This class implements object persistence in an LDAP datastore. It is similar to SPOPS::DBI but with some important differences -- LDAP gurus can certainly find more:
LDAP supports multiple-valued properties.
Rather than tables, LDAP supports a hierarchy of data information, stored in a tree. An object can be at any level of a tree under a particular branch.
LDAP supports referrals, or punting a query off to another server. (SPOPS does not support referrals yet, but we fake it with SPOPS::LDAP::MultiDatasource.)
CONFIGURATION
See SPOPS::Manual::Configuration for the configuration fields used and LDAP-specific issues.
METHODS
Configuration Methods
See relevant discussion for each of these items under CONFIGURATION (configuration key name is the same as the method name).
base_dn (Returns: $)
ldap_objectclass (Returns: \@) (optional)
id_value_field (Returns: $) (optional)
Datasource Methdods
global_datasource_handle( [ $connect_key ] )
You need to create a method to return a datasource handle for use by the various methods of this class. You can also pass in a handle directory using the parameter 'ldap':
# This object has a 'global_datasource_handle' method
my $object = My::Object->fetch( 'blah' );
# This object does not
my $object = Your::Object->fetch( 'blah', { ldap => $ldap });
Should return: Net::LDAP (or compatible) connection object that optionally maps to $connect_key
.
You can configure your objects to use multiple datasources when certain conditions are found. For instance, you can configure the fetch()
operation to cycle through a list of datasources until an object is found -- see SPOPS::LDAP::MultiDatasource for an example.
Class Initialization
class_initialize()
Just create the 'field_list' configuration parameter.
Object Information
dn( [ $new_dn ] )
Retrieves and potentially sets the DN (distinguished name) for a particular object. This is done automatically when you call fetch()
or fetch_group()
to retrieve objects so you can always access the DN for an object. If the DN is empty the object has not yet been serialized to the LDAP datastore. (You can also call the SPOPS method is_saved()
to check this.)
Returns: DN for this object
build_dn()
Builds a DN from an object -- you should never need to call this and it might disappear in future versions, only to be used internally.
Object Serialization
Note that you can pass in the following parameters for any of these methods:
ldap: A Net::LDAP connection object.
connect_key: A connection key to use for a particular LDAP connection.
fetch( $id, \%params )
Retrieve an object with ID $id
or matching other specified parameters.
Parameters:
filter ($)
Use the given filter to find an object. Note that the method will die if you get more than one entry back as a result.
(Synonym: 'where')
fetch_by_dn( $dn, \%params )
Retrieve an object by a full DN ($dn
).
fetch_group( \%params )
Retrieve a group of objects
fetch_iterator( \%params )
Instead of returning an arrayref of results, return an object of class SPOPS::Iterator::LDAP.
Parameters are the same as fetch_group()
.
save( \%params )
Save an LDAP object to the datastore. This is quite straightforward.
remove( \%params )
Remove an LDAP object to the datastore. This is quite straightforward.
BUGS
Renaming of DNs not supported
Moving an object from one DN to another is not currently supported.
TO DO
More Usage
I have only tested this on an OpenLDAP (version 2.0.11) server. Since we are using Net::LDAP for the interface, we should (in theory) have no problems connecting to other LDAP servers such as iPlanet Directory Server, Novell NDS or Microsoft Active Directory.
It would also be good to test with a wider variety of schemas and objects.
Expand LDAP Interfaces
Currently we use Net::LDAP to interface with the LDAP directory, but Perl/C libraries may be faster and provide different features. Once this is needed, we will probably need to create implementation-specific subclasses. This should not be very difficult -- the actual calls to Net::LDAP
are minimal and straightforward.
SEE ALSO
COPYRIGHT
Copyright (c) 2001-2002 MSN Marketing Service Nordwest, GmbH. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
AUTHORS
Chris Winters <chris@cwinters.com>