--- lib/A3C/LDAP.pm 2008/03/30 00:02:18 36 +++ lib/A3C/LDAP.pm 2008/03/30 16:58:21 42 @@ -5,24 +5,189 @@ use Net::LDAP; use Data::Dump qw/dump/; -use base 'Jifty::Object'; +use base qw(Jifty::Object Class::Accessor::Fast); +our @config_fields = qw( server dn password base ); +Jifty->log->debug("using fields from configuration: ",dump( @config_fields )); +__PACKAGE__->mk_accessors( qw(ldap current_search), @config_fields ); -my $ldap_config = Jifty->config->app('LDAP'); -Jifty->log->debug( "config->app(LDAP) = ",dump( $ldap_config ) ); +=head1 NAME -my $ldap = Net::LDAP->new( $ldap_config->{Server} ) or die "$@"; +A3C::LDAP -# an anonymous bind -#my $mesg = $ldap->bind; -my $mesg = $ldap->bind( $ldap_config->{DN}, password => $ldap_config->{Password} ); +=head1 DESCRIPTION -Jifty->log->info("Connected to ", $ldap_config->{Server}, " with DN ", $ldap_config->{DN}); +This object turn L into something with looks like +L + +=head1 METHODS + +=head2 new + + my $ldap = A3C::LDAP->new; + +=cut + +sub new { + my $class = shift; + + my $args = { @_ }; + + my $ldap_config = Jifty->config->app('LDAP'); + Jifty->log->debug( "config->app(LDAP) = ",dump( $ldap_config ) ); + + foreach my $f ( @config_fields ) { + if ( my $v = $ldap_config->{$f} ) { + $args->{$f} = $v; + } + } + + my $ldap = Net::LDAP->new( $args->{server} ) or die "$@"; + + # an anonymous bind + #$ldap->bind; + $ldap->bind( $args->{dn}, password => $args->{password} ); + + Jifty->log->info("Connected to ", $args->{server}, " with DN ", $args->{dn}); + + $args->{ldap} = $ldap; + + $class->SUPER::new( $args ); +} + +=head2 search + + my $msg = A3C::LDAP->search( + base => 'dc=skole,dc=hr', + filter => '(objectClass=hrEduOrg)', + sizelimit => 10, + ); + +=cut sub search { my $self = shift; - return $ldap->search( @_ ); + my $search = $self->ldap->search( @_ ); + if ( $search->code != 0 ) { + Jifty->log->error( $search->error, ' for ', dump( @_ ) ); + } + return $self->current_search( $search ); +} + +=head2 next + +Syntaxtic shugar to look more like L + + my $entry = ldap->next; + +=cut + +sub next { + my $self = shift; + + die "no current LDAP search" unless $self->current_search; + + return $self->current_search->shift_entry; +} + +=head2 count + + my $search_results = $ldap->count; + +=cut + +sub count { + my $self = shift; + $self->current_search->count; +} + +=head2 as_collection_of + + my $connection = $ldap->collection('Organization', $limit); + +=cut + +my $collection2filter = { + 'User' => '(objectClass=hrEduPerson)', + 'Organization' => '(objectClass=hrEduOrg)', +}; + +sub collection { + my ( $self, $model, $limit ) = @_; + + $limit ||= 100; # FIXME + + my $filter = $collection2filter->{$model}; + die "unknown model $model" unless $filter; + + $self->search( + base => $self->base, + filter => $filter, + sizelimit => $limit, + ); + + Jifty->log->info("searching LDAP for $model with $filter limit $limit returned ", $self->count, " results"); + + my $class = Jifty->app_class('Model', $model . 'Collection' ) or die "can't create ${model}Collection"; + my $collection = $class->new() or die "can't $class->new"; + + while ( my $entry = $self->next ) { + my $model_obj = Jifty->app_class('Model',$model)->new; + #warn dump( $model_obj ); + my $additional; +# if ( $model eq 'User' ) { +# my $organization = A3C::Model::Organization->new; +# $self->ldap2model( $organization, $entry ); +# $additional->{organization} = $organization; +# } + $self->ldap2model( $model_obj, $entry, %$additional ); + $collection->add_record( $model_obj ); + } + + return $collection; } +=head1 INTERNAL METHODS + +Following methods map directly into L + +=head2 current_search + +Result of last C<< $ldap->search >> request + +=head2 model_to_entry + + $ldap->model_to_entry( $model, $entry, $additional ); + +=cut + +sub ldap2model { + my ( $self, $model, $entry, $additional ) = @_; + my $data; + + my @columns = map { $_->name } $model->columns; + #warn "# columns = ",dump( @columns ); + + foreach my $attr ( $entry->attributes ) { + if ( grep(/^\Q$attr\E$/, @columns ) ) { + $data->{$attr} = $entry->get_value( $attr ); + } elsif ( $attr !~ m/^(objectClass)$/i ) { + Jifty->log->error(ref($model)," doesn't have $attr"); + } + } + + Jifty->log->debug( ref($model), ' = ', dump( $data ) ); + + my ( $id, $message ) = $model->load_or_create( %$data, %$additional ); + + if ( $id ) { + Jifty->log->info( $message || 'Added', ' ', ref($model), ' ', $model->id ); + } else { + Jifty->log->error( ref($model), " ", $message ); + } +} + + + 1;