/[A3C]/lib/A3C/LDAP.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /lib/A3C/LDAP.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 36 by dpavlin, Sun Mar 30 00:02:18 2008 UTC revision 106 by dpavlin, Thu May 1 17:06:02 2008 UTC
# Line 5  use warnings; Line 5  use warnings;
5    
6  use Net::LDAP;  use Net::LDAP;
7  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
8  use base 'Jifty::Object';  use base qw(Jifty::Object Class::Accessor::Fast);
9    our @config_fields = keys %{ Jifty->config->app('LDAP') };
10    Jifty->log->debug("using fields from configuration: ",dump( @config_fields ));
11    __PACKAGE__->mk_accessors( qw(ldap current_search), @config_fields );
12    
 my $ldap_config = Jifty->config->app('LDAP');  
13    
14  Jifty->log->debug( "config->app(LDAP) = ",dump( $ldap_config ) );  =head1 NAME
15    
16  my $ldap = Net::LDAP->new( $ldap_config->{Server} ) or die "$@";  A3C::LDAP
17    
18  # an anonymous bind  =head1 DESCRIPTION
 #my $mesg = $ldap->bind;  
 my $mesg = $ldap->bind( $ldap_config->{DN}, password => $ldap_config->{Password} );  
19    
20  Jifty->log->info("Connected to ", $ldap_config->{Server}, " with DN ", $ldap_config->{DN});  This object turn L<Net::LDAP> into something with looks like
21    L<Jifty::Collection>
22    
23    =head1 METHODS
24    
25    =head2 new
26    
27      my $ldap = A3C::LDAP->new;
28    
29    =cut
30    
31    sub new {
32            my $class = shift;
33    
34            my $args = { @_ };
35    
36            my $ldap_config = Jifty->config->app('LDAP');
37            Jifty->log->debug( "config->app(LDAP) = ",dump( $ldap_config ) );
38    
39            foreach my $f ( @config_fields ) {
40                    if ( my $v = $ldap_config->{$f} ) {
41                            $args->{$f} = $v;
42                    }
43            }
44    
45            # configuration sanity testing
46            foreach ( qw/server dn password base objectClass link/ ) {
47                    die "missing required field $_ in LDAP from etc/config.yaml" unless $args->{$_};
48            }
49            foreach ( qw/person organization/ ) {
50                    die "missing required field $_ in LDAP.objectClass.$_ from etc/config.yaml" unless $args->{objectClass}->{$_};
51            }
52            foreach ( qw/person_filter display_from value_from/ ) {
53                    die "missing required field $_ in LDAP.link.$_ from etc/config.yaml" unless $args->{link}->{$_};
54            }
55    
56            my $ldap = Net::LDAP->new( $args->{server} ) or die "$@";
57    
58            # an anonymous bind
59            #$ldap->bind;
60            $ldap->bind( $args->{dn}, password => $args->{password} );
61    
62            Jifty->log->info("Connected to ", $args->{server}, " with DN ", $args->{dn});
63    
64            $args->{ldap} = $ldap;
65    
66            $class->SUPER::new( $args );
67    }
68    
69    =head2 search
70    
71      my $msg = A3C::LDAP->search(
72            base    => 'dc=skole,dc=hr',
73            filter  => '(objectClass=hrEduOrg)',
74            sizelimit => 10,
75      );
76    
77    =cut
78    
79  sub search {  sub search {
80          my $self = shift;          my $self = shift;
81    
82          return $ldap->search( @_ );          my $search = $self->ldap->search( @_ );
83            if ( $search->code != 0 ) {
84                    Jifty->log->error( $search->error, ' for ', dump( @_ ) );
85            }
86            return $self->current_search( $search );
87    }
88    
89    =head2 next
90    
91    Syntaxtic shugar to look more like L<Jifty::DBI::Collection>
92    
93      my $entry = ldap->next;
94    
95    =cut
96    
97    sub next {
98            my $self = shift;
99    
100            die "no current LDAP search" unless $self->current_search;
101    
102            return $self->current_search->shift_entry;
103  }  }
104    
105    =head2 count
106    
107      my $search_results = $ldap->count;
108    
109    =cut
110    
111    sub count {
112            my $self = shift;
113            $self->current_search->count;
114    }
115    
116    =head2 collection
117    
118      my $connection = $ldap->collection(
119            # name of model to use
120            $ldap->objectClass->{organization},
121            # optional params
122            limit => $limit,
123            filter => '(uid=foobar)',
124      );
125    
126    =cut
127    
128    my $collection2filter = {
129            'Person'                => '(objectClass=hrEduPerson)',
130            'Organization'  => '(objectClass=hrEduOrg)',
131    };
132    
133    sub collection {
134            my $self = shift;
135            my $model = shift or die "no model?";
136            my $args = {@_};
137    
138            $args->{limit} ||= 0;   # unlimited by default
139    
140            my $filter = $collection2filter->{$model};
141    #       die "unknown model $model" unless $filter;
142            # fallback to model named as objectClass
143            $filter ||= "(objectClass=$model)";
144    
145            # add user filter
146            $filter = '(&' . $filter . $args->{filter} . ')' if $args->{filter};
147    
148            $self->search(
149                    base => $self->base,
150                    filter => $filter,
151                    sizelimit => $args->{limit},
152            );
153    
154            Jifty->log->info(
155                    "Searching LDAP for $model with $filter ",
156                    $args->{limit} ? 'limit ' . $args->{limit} . ' ' : '',
157                    'returned ', $self->count, ' results'
158            );
159    
160            my $class = Jifty->app_class('Model', $model . 'Collection' ) or die "can't create ${model}Collection";
161            my $collection = $class->new() or die "can't $class->new";
162    
163            while ( my $entry = $self->next ) {
164                    my $model_obj = Jifty->app_class('Model',$model)->new;
165                    #warn dump( $model_obj );
166                    my $additional;
167                    $self->model_from_entry( $model_obj, $entry, %$additional );
168                    $collection->add_record( $model_obj );
169            }
170    
171            return $collection;
172    }
173    
174    =head1 INTERNAL METHODS
175    
176    Following methods map directly into L<Net::LDAP>
177    
178    =head2 current_search
179    
180    Result of last C<< $ldap->search >> request
181    
182    =head2 model_from_entry
183    
184      $ldap->model_from_entry( $model, $entry, $additional );
185    
186    =cut
187    
188    sub model_from_entry {
189            my ( $self, $model, $entry, $additional ) = @_;
190            my $data;
191    
192            my @columns = map { $_->name } $model->columns;
193            #warn "# columns = ",dump( @columns );
194    
195            foreach my $attr ( $entry->attributes ) {
196                    if ( grep(/^\Q$attr\E$/, @columns ) ) {
197                            $data->{$attr} = $entry->get_value( $attr );
198    #               } elsif ( $attr !~ m/^(objectClass)$/i ) {
199                    } else {
200                            Jifty->log->warn(ref($model)," doesn't have $attr");
201                    }
202            }
203    
204            Jifty->log->debug( ref($model), ' = ', dump( $data ) );
205    
206            my ( $id, $message ) = $model->load_or_create( %$data, %$additional );
207    
208            if ( $id ) {
209                    Jifty->log->info( $message || 'Added', ' ', ref($model), ' ', $model->id, ' ', $model->name );
210            } else {
211                    Jifty->log->error( ref($model), " ", $message );
212            }
213    }
214    
215    
216    
217  1;  1;

Legend:
Removed from v.36  
changed lines
  Added in v.106

  ViewVC Help
Powered by ViewVC 1.1.26