From 4a0d87e642c4d97ee2a026f1207e25a001518f3a Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sat, 8 Sep 2012 19:49:11 +0200 Subject: Abstracting the LDAP stuff in an OO library. --- lib/Fripost/Schema/Local.pm | 161 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 lib/Fripost/Schema/Local.pm (limited to 'lib/Fripost/Schema/Local.pm') diff --git a/lib/Fripost/Schema/Local.pm b/lib/Fripost/Schema/Local.pm new file mode 100644 index 0000000..79c5420 --- /dev/null +++ b/lib/Fripost/Schema/Local.pm @@ -0,0 +1,161 @@ +package Fripost::Schema::Local; + +=head1 NAME + +Local.pm - + +=head1 DESCRIPTION + +Local.pm abstracts the LDAP schema definition and provides methods to +search for virtual mailboxes, aliases or lists alltogether. + +=cut + +use 5.010_000; +use strict; +use warnings; +use utf8; + +use parent 'Fripost::Schema'; +use Fripost::Schema::Misc 'concat'; + + +=head1 METHODS + +=over 4 + +=item B (I,I, I) + +Returns a hash with all the (visible) attributes for the given entry. An +additional 'type' attribute gives the type of *the* found entry +(possible values are 'mailbox', 'alias', and 'list'). + +=cut + +sub get { + my $self = shift; + my $l = shift; + my $d = shift; + my %options = @_; + my $concat = $options{'-concat'}; + + my $locals = $self->ldap->search( + base => "fvd=$d,".$self->suffix, + scope => 'one', + deref => 'never', + filter => "(|(&(objectClass=FripostVirtualMailbox)(fvu=$l)) + (&(objectClass=FripostVirtualAlias)(fva=$l)) + (&(objectClass=FripostVirtualList)(fvl=$l)))", + attrs => [ qw/fvu description + fripostIsStatusActive + fripostOptionalMaildrop + fripostMailboxQuota + fva fripostMaildrop + fvl fripostListManager/ ] + ); + if ($locals->code) { + die $options{'-die'}."\n" if defined $options{'-die'}; + die $locals->error; + } + + # The following is not supposed to happen. Note that there is + # nothing in the LDAP schema to prevent that, but it's not too + # critical as Postfix search for mailboxes, aliases and lists in + # that order. + die "Error: Multiple matching entries found." if $locals->count > 1; + my $local = $locals->pop_entry; + + unless (defined $local) { + die $options{'-die'}."\n" if defined $options{'-die'}; + die "No such such entry ‘".$l.'@'.$d."‘.\n"; + } + + my %ret; + if ($local->dn =~ /^fvu=/) { + $ret{type} = 'mailbox'; + $ret{user} = $local->get_value('fvu'); + $ret{forwards} = concat($concat, $local->get_value('fripostOptionalMaildrop')) + } + elsif ($local->dn =~ /^fva=/) { + $ret{type} = 'alias'; + $ret{alias} = $local->get_value('fva'); + $ret{maildrop} = concat($concat, $local->get_value('fripostMaildrop')) + } + elsif ($local->dn =~ /^fvl=/) { + $ret{type} = 'list'; + $ret{list} = $local->get_value('fvl'); + } + $ret{isactive} = $local->get_value('fripostIsStatusActive') eq 'TRUE'; + $ret{description} = concat($concat, $local->get_value('description')); + + return %ret; +} + + +=item B (I,I, I) + +Returns 1 if the given I@I exists, and 0 otherwise. +The authenticated user needs to have search access to the 'entry' +attribute. + +=cut + +sub exists { + my $self = shift; + my $l = shift; + my $d = shift; + my %options = @_; + + # We may not have read access to the list commands + # The trick is somewhat dirty, but it's safe enough since postfix + # delivers to mailboxes, aliases, and lists with different + # priorities (and lists have the lowest). +# $l =~ s/(.*)-(admin|bounces|confirm|join|leave|loop|owner|request|subscribe|unsubscribe|bounce|sendkey)$/$1/; + # ^ TODO + + foreach my $t (qw/fvu fva fvl/) { + my $mesg = $self->ldap->search( base => "$t=$l,fvd=$d,".$self->suffix, + scope => 'base', + deref => 'never', + filter => 'objectClass=*' + ); + return 1 unless $mesg->code; # 0 Success + unless ($mesg->code == 32) { # 32 No such object + die $options{'-die'}."\n" if defined $options{'-die'}; + die $mesg->error; + } + } + return 0; +} + +=back + +=head1 GLOBAL OPTIONS + +If the B<-concat> option is present, it will intersperse multi-valued +attributes. Otherwise, an array reference containing every values will +be returned for these attributes. + +The B<-die> option, if present, overides LDAP croaks and errors. + +=cut + + +=head1 AUTHOR + +Guilhem Moulin C<< >> + +=head1 COPYRIGHT + +Copyright 2012 Guilhem Moulin. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify it +under the same terms as perl itself. + +=cut + +1; + +__END__ -- cgit v1.2.3