Apache-Sling

 view release on metacpan or  search on metacpan

lib/Apache/Sling/LDAPSynch.pm  view on Meta::CPAN

#!/usr/bin/perl -w

package Apache::Sling::LDAPSynch;

use 5.008001;
use strict;
use warnings;
use Carp;
use Getopt::Long qw(:config bundling);
use Apache::Sling;
use Apache::Sling::Authn;
use Apache::Sling::Content;
use Apache::Sling::User;
use Data::Dumper;
use Fcntl ':flock';
use File::Temp;
use Net::LDAP;

require Exporter;

use base qw(Exporter);

our @EXPORT_OK = qw(command_line);

our $VERSION = '0.27';

#{{{sub new

sub new {
    my (
        $class, $ldap_host, $ldap_base, $filter,  $dn,
        $pass,  $authn,     $disabled,  $verbose, $log
    ) = @_;
    if ( !defined $authn ) { croak 'no authn provided!'; }
    $disabled = ( defined $disabled ? $disabled : q(sling:disabled) );
    $filter   = ( defined $filter   ? $filter   : q(uid) );
    $verbose  = ( defined $verbose  ? $verbose  : 0 );

    # Directory containing the cache and user_list files:
    my $synch_cache_path =
      q(_user/a/ad/admin/private/ldap_synch_cache_system_files);

    # Directory containing backups of the cache and user_list files:
    my $synch_cache_backup_path =
      q(_user/a/ad/admin/private/ldap_synch_cache_system_files_backup);

# List of specific users previously ingested in to the sling system and their status:
    my $synch_cache_file = q(cache.txt);

   # List of specific ldap users that are to be ingested in to the sling system:
    my $synch_user_list = q(user_list.txt);
    my $ldap;
    my $content = Apache::Sling::Content->new( $authn, $verbose, $log )
      or croak q(Problem creating Sling content object!);
    my $user = Apache::Sling::User->new( $authn, $verbose, $log )
      or croak q(Problem creating Sling user object!);
    my $ldap_synch = {
        CacheBackupPath => $synch_cache_backup_path,
        CachePath       => $synch_cache_path,
        CacheFile       => $synch_cache_file,
        Content         => \$content,
        Disabled        => $disabled,
        LDAP            => \$ldap,
        LDAPbase        => $ldap_base,
        LDAPDN          => $dn,
        LDAPHost        => $ldap_host,
        LDAPPass        => $pass,
        Filter          => $filter,
        Log             => $log,
        Message         => q(),
        User            => \$user,
        UserList        => $synch_user_list,
        Verbose         => $verbose
    };
    bless $ldap_synch, $class;
    return $ldap_synch;
}

#}}}

#{{{sub ldap_connect

sub ldap_connect {
    my ($class) = @_;
    $class->{'LDAP'} = Net::LDAP->new( $class->{'LDAPHost'} )
      or croak 'Problem opening a connection to the LDAP server!';
    if ( defined $class->{'LDAPDN'} && defined $class->{'LDAPPASS'} ) {
        my $mesg = $class->{'LDAP'}->bind(
            $class->{'LDAPDN'},
            password => $class->{'LDAPPASS'},
            version  => '3'
        ) or croak 'Problem with authenticated bind to LDAP server!';
    }
    else {
        my $mesg = $class->{'LDAP'}->bind( version => '3' )
          or croak 'Problem with anonymous bind to LDAP server!';
    }
    return 1;
}

#}}}

#{{{sub ldap_search

sub ldap_search {
    my ( $class, $search, $attrs ) = @_;
    $class->ldap_connect;
    return $class->{'LDAP'}->search(
        base   => $class->{'LDAPbase'},
        scope  => 'sub',
        filter => "$search",
        attrs  => $attrs
    )->as_struct;
}

#}}}

#{{{sub init_synch_cache

sub init_synch_cache {
    my ($class) = @_;
    if ( !${ $class->{'Content'} }
        ->check_exists( $class->{'CachePath'} . q(/) . $class->{'CacheFile'} ) )
    {
        my ( $tmp_cache_file_handle, $tmp_cache_file_name ) =
          File::Temp::tempfile();
        my %synch_cache;
        print {$tmp_cache_file_handle}
          Data::Dumper->Dump( [ \%synch_cache ], [qw( synch_cache )] )
          or croak q(Unable to print initial data dump of synch cache to file!);
        close $tmp_cache_file_handle
          or croak
q(Problem closing temporary file handle when initializing synch cache);
        ${ $class->{'Content'} }
          ->upload_file( $tmp_cache_file_name, $class->{'CachePath'},
            $class->{'CacheFile'} )
          or croak q(Unable to initialize LDAP synch cache file!);
        unlink $tmp_cache_file_name
          or croak
          q(Problem clearing up temporary file after init of synch cache!);
    }
    return 1;
}

#}}}

#{{{sub get_synch_cache

sub get_synch_cache {
    my ($class) = @_;
    $class->init_synch_cache();
    if ( !${ $class->{'Content'} }
        ->check_exists( $class->{'CachePath'} . q(/) . $class->{'CacheFile'} ) )
    {
        croak q(No synch cache file present - initialization must have failed!);
    }
    ${ $class->{'Content'} }
      ->view_file( $class->{'CachePath'} . q(/) . $class->{'CacheFile'} )
      or croak q(Problem viewing synch cache file);
    my $synch_cache;
    my $success = eval ${ $class->{'Content'} }->{'Message'};
    if ( !defined $success ) {
        croak q{Error parsing synchronized cache dump.};
    }
    return $synch_cache;
}

#}}}

#{{{sub update_synch_cache

sub update_synch_cache {
    my ( $class, $synch_cache ) = @_;
    my ( $tmp_cache_file_handle, $tmp_cache_file_name ) =
      File::Temp::tempfile();
    print {$tmp_cache_file_handle}
      Data::Dumper->Dump( [$synch_cache], [qw( synch_cache )] )
      or croak q(Unable to print data dump of synch cache to file!);
    close $tmp_cache_file_handle
      or croak
      q(Problem closing temporary file handle when updating synch cache);
    ${ $class->{'Content'} }
      ->upload_file( $tmp_cache_file_name, $class->{'CachePath'},
        $class->{'CacheFile'} )
      or croak q(Unable to update LDAP synch cache file!);
    my $time = time;
    ${ $class->{'Content'} }
      ->upload_file( $tmp_cache_file_name, $class->{'CacheBackupPath'},
        "cache$time.txt" )
      or croak q(Unable to create LDAP synch cache backup file!);
    unlink $tmp_cache_file_name
      or croak
      q(Problem clearing up temporary file after updating synch cache!);
    return 1;
}

#}}}

#{{{sub get_synch_user_list

sub get_synch_user_list {
    my ($class) = @_;
    if ( !${ $class->{'Content'} }
        ->check_exists( $class->{'CachePath'} . q(/) . $class->{'UserList'} ) )
    {
        croak q(No user list file present - you need to create one!);
    }
    ${ $class->{'Content'} }
      ->view_file( $class->{'CachePath'} . q(/) . $class->{'UserList'} )
      or croak q(Problem viewing synch user list);
    my $synch_user_list;
    my $success = eval ${ $class->{'Content'} }->{'Message'};
    if ( !defined $success ) {
        croak q{Error parsing synchronized user list dump.};
    }
    return $synch_user_list;
}

#}}}

#{{{sub update_synch_user_list

sub update_synch_user_list {
    my ( $class, $synch_user_list ) = @_;
    my ( $tmp_user_list_file_handle, $tmp_user_list_file_name ) =
      File::Temp::tempfile();
    print {$tmp_user_list_file_handle}
      Data::Dumper->Dump( [$synch_user_list], [qw( synch_user_list )] )
      or croak q(Unable to print data dump of synch user list to file!);
    close $tmp_user_list_file_handle
      or croak
      q(Problem closing temporary file handle when writing synch user list);
    ${ $class->{'Content'} }
      ->upload_file( $tmp_user_list_file_name, $class->{'CachePath'},
        $class->{'UserList'} )
      or croak
      q(Unable to upload LDAP synch user list file into sling instance!);
    Apache::Sling::Print::print_result( ${ $class->{'Content'} } );
    my $time = time;
    ${ $class->{'Content'} }
      ->upload_file( $tmp_user_list_file_name, $class->{'CacheBackupPath'},
        "user_list$time.txt" )
      or croak q(Unable to create LDAP synch user list backup file!);
    unlink $tmp_user_list_file_name
      or croak
      q(Problem clearing up temporary file after updating synch user list!);
    return 1;
}

#}}}

#{{{sub download_synch_user_list

sub download_synch_user_list {
    my ( $class, $user_list_file ) = @_;
    my $synch_user_list = $class->get_synch_user_list;
    foreach my $user ( sort keys %{$synch_user_list} ) {
        if ( open my $out, '>>', $user_list_file ) {
            flock $out, LOCK_EX;
            print {$out} $user . "\n"
              or croak
              q(Problem printing when downloading synchronized user list!);
            flock $out, LOCK_UN;
            close $out
              or croak
q(Problem closing file handle when downloading synchronized user list!);
        }
        else {
            croak q(Could not open file to download synchronized user list to!);
        }
    }
    $class->{'Message'} =
      "Successfully downloaded user list to $user_list_file!";
    return 1;
}

#}}}

#{{{sub upload_synch_user_list

sub upload_synch_user_list {
    my ( $class, $user_list_file ) = @_;
    my %user_list_hash;
    if ( open my ($input), '<', $user_list_file ) {
        while (<$input>) {
            chomp;
            $user_list_hash{$_} = 1;
        }



( run in 1.783 second using v1.01-cache-2.11-cpan-0d23b851a93 )