#!/usr/bin/perl

#################################################################
#								#
# Author:	TJ Maciak, Rob Nass, Craig Patterson		#
# Filename:	RT-LDAP-Cron-Cleanup.pl				#
# Purpose:	Compare RT Profile to info thats in LDAP Record #
#								#
# History    Vers  Description					#
# 07-28-2006 1.0.0 First version of this program     		#
# 08-07-2006 1.0.1 Updated DB connection, check for disabled    #
#		   users and display of Warn / Error messages   #
# 12-06-2006 1.0.2 Removed extra disabled check, and filter the #
#		   disabled from sql statement instead, we do	#
#		   not need to check a disabled user everyweek. #
# 10-04-2007 2.0.0 Pretty much rewrote from scratch.  We now    #
#	   	   get our db connection info from 		#
#		   RTSite_config.  We also use RT's libraries.  #
#		   Specifically, we call CanonicalizeUserInfo   #
#		   to grab the user data, and we also not just  #
#		   go ahead and update the record directly if   #
#		   was more recently updated in LDAP than in RT #    
#		   Logging goes directly to RT's log		#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Future Goals:							#
#---------------------------------------------------------------#
# - Compare the custom field Department for the user	       	#
# - Automatic update of RT Profile based on changes from LDAP   #
#################################################################

no warnings qw(redefine);

use strict;
use DBI;

package USER_LOCAL;
use lib '/opt/rt3/local/lib/RT';
use User_Local;

package RT;
use lib '/opt/rt3/lib';
use RT;

RT:LoadConfig();
RT::Init();

$RT::Logger->info("COGR - Begin:  RT-LDAP-Cron-Cleanup");

my %ARGS = {
    id => undef,
    Name  => undef,
    Comments  => undef,
    Signature  => undef,
    EmailAddress  => undef,
    FreeformContactInfo => undef,
    Organization  => undef,
    RealName  => undef,
    NickName  => undef,
    Privileged => undef,
    SetPrivileged => undef,
    Enabled => undef,
    SetEnabled => undef,
    Lang  => undef,
    EmailEncoding  => undef,
    WebEncoding => undef,
    ExternalContactInfoId  => undef,
    ContactInfoSystem  => undef,
    Gecos => undef,
    ExternalAuthId  => undef,
    AuthSystem  => undef,
    HomePhone => undef,
    WorkPhone  => undef,
    MobilePhone  => undef,
    PagerPhone  => undef,
    Address1 => undef,
    Address2  => undef,
    City  => undef,
    State  => undef,
    Zip  => undef,
    Country => undef,
    WhenChanged=>undef
};

my $dbh = DBI->connect( "DBI:Oracle:$RT::DatabaseName", "$RT::DatabaseUser", "$RT::DatabasePassword" )
  or die "Error: no DBH connection";
my $sth = $dbh->prepare(
	qq{
  select users.id
    from rt.users
      	 , rt.principals
   where users.id = principals.objectid
     and principals.disabled=0
     and organization = 'City of Grand Rapids'
   order by users.id
	}
);
$sth->execute() or die "Error: Can not complete Select from RT.USERS statement";

while ( my ( $userid ) = $sth->fetchrow_array ){
	CHECK_LDAP_RECORD( $userid );    
}

$sth->finish;
$dbh->disconnect;

$RT::Logger->info("COGR - End:  RT-LDAP-Cron-Cleanup");

exit;

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

sub CHECK_LDAP_RECORD {
	my $userid  = shift;

	unless ($userid){
	   	print LOG qq {no user passed in time to bail!};
		exit;
	}
	
    my $UserObj = RT::User->new($RT::SystemUser);
    $UserObj->Load($userid);

    $ARGS{'Name'} = $UserObj->Name;    
    $UserObj->USER_LOCAL::CanonicalizeUserInfo(\%ARGS);
    
    #Let's make sure CanonicalizeUserInfo is working...    
   
    $RT::Logger->debug("User's email: " . $UserObj->EmailAddress);

    my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo 
		    Organization RealName NickName Lang EmailEncoding WebEncoding 
		    ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId 
		    AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
		    Address2 City State Zip Country 
	);

    # ADChangeDate is in format YYYYMMDDMMSSSS.OZ
    my $ADChangeDate = substr($ARGS{'WhenChanged'}, 0, 8);
    # LastUpdated Format is  YYYY-MM-DD HH:mm:ss
    my $RTChangeDate = substr($UserObj->LastUpdated, 0, 10);
    $RTChangeDate =~ s/-//g;

    if ($ADChangeDate > $RTChangeDate){
	$RT::Logger->info("COGR - RT-LDAP-Cron-Cleanup Script:  Updating -> " . $UserObj->Name);
	   	
	# Save the Record!
	my ($method_success, $method_msg) =  $UserObj->Update( 
	    	AttributesRef => \@fields,
			ARGSRef => \%ARGS 
		) or die "Cant update record\n";

	if (!$method_success){
	    $RT::Logger->debug("update failed. '$method_msg'");
	}else {
	    $RT::Logger->debug("======  Update Succeeded =====");
	}

	# now deal with the custom field department		
	# but only update if it's changed
		
	if ($ARGS{'Department'} ne $UserObj->FirstCustomFieldValue('Department')){
		my $CFObj = new RT::CustomField($RT::SystemUser);
		$CFObj->Load('Department');
		
		if ($CFObj->id ){
			$UserObj->AddCustomFieldValue(
				Field => $CFObj->id,
				Value => $ARGS{'Department'},
				RecordTransaction => 1
			);
		}else {
			$RT::Logger->error("Could find department custom field for  " . $UserObj->Name );
		}

	} 

    }else {
	$RT::Logger->debug("User not updated " . $UserObj->Name);
    }
}
