#!/usr/bin/perl -w

#------------------------------------------------------------
#This action creates an Active Directory user 
#
#Command format:
#
# user-create-AD event username data:  
#
#  event    : calling event name
#  username : unique username
#  data     : Hash reference to user data to populate the AD 
#             with. See the note below for 
#
#Note:  This action uses the samba-tool utility to add a new
#       user the the Active Directory. Samba-tool does not exit 
#       very gracefully if it has a problem, so this action may 
#       throw some really funky error messages.
#
#Copyright 2016 Koozali Foundation, Inc.
#06/23/2016: G.Zartman <gzartman@koozali.org>
#
#The code contained herein can be distributed under the same
#license as Perl
#
#TODO
#
#- For the hash reference, let's scrub it with the 
#   esmith::AD::User::ValidData method
#- Consider setting the displayName attribute as well, otherwise
#  Active Directory does it automatically to
#  given-name initials surname.  In some cases, this looks goofy.
#
#------------------------------------------------------------
package esmith::thisaction;

use strict;
use warnings;
use esmith::AccountsDB;
use esmith::ConfigDB;
use esmith::AD::User;
use esmith::AD::Group;

use Data::Dumper;  #For debugging

#Pull arguments
my $event       = $ARGV [0] || '';
my $userName    = $ARGV [1] || '';
my $dataRef	= $ARGV [2] || {}; #Hash ref

print "Ref = " . ref($dataRef); 
print "Ref = $dataRef"; 

die "Username not found in action arguments\n"
  unless ($userName);
die "User data not found in action arguments\n"
  unless ($dataRef);

#Check AD to see if username exists.  If username already exists, then
#bail out. 
my $ad = esmith::AD::User->new();
die "User $userName already exists in Active Directory.\n"
    if ($ad->doesUserExist($userName));

#Validate the user data
print "Reference =" . ref($dataRef); 
my %data = %$dataRef;
print "Reference =" . ref($dataRef); 
exit;
foreach my $key (keys %data) 
{
    if ($key eq 'groups') {delete $data{$key};}
    unless ($ad->validData->{$key}) 
    {
        warn "Ignoring $key attribute for update -- Not supported.\n";
        delete $data{$key};
    }
}

#Build Active Directory user create command
my $homeDirectory = '/home/e-smith/files/users/' . $userName . '/home/';
die ("Home directory for $userName already exists on the server. " . 
     "Remove to create user") if (-d $homeDirectory); 
my $shell = '/usr/bin/rssh';
if ($data{'loginShell'}) 
{
   $shell = $data{'loginShell'};
   delete $data{'loginShell'};
}

#Create AD User
my $adPassword = $ad->getADPass();
my $addUser = "/usr/bin/samba-tool user create $userName " .
              "--home-directory=$homeDirectory " .
              "--login-shell=$shell " .
              '--random-password ' .
              '--description="Koozali User:" ' .
              "-U ad_admin\%$adPassword";
system ($addUser);
die ("Unable to add user $userName to Active Directory\n") if ($? == -1);

#Make user a Posix User
unless ($ad->setPosixUser($userName)) 
{
    warn ("Unable to set posix objectClass in AD for $userName.\n");
}

#Build Unix Attributes
my $UID = $ad->createUID($userName) || '';
my %posix = ('uidNumber'         => $UID,
             'gidNumber'         => '513',
             'unixHomeDirectory' => $homeDirectory);

#Set groups
my $adG = esmith::AD::Group->new();
if (ref($data{'groups'}) eq 'ARRAY') 
{
    foreach my $group (@{$data{'groups'}}) 
    {
        $adG->addUserToGroup($group,$userName);
    }
    delete $data{'groups'};  
}

#Merge Unix Attributes with any Extended Attributes and save to AD
my $mergedData = {%posix,%data};
$ad->setManyAttr($userName,$mergedData) ||
  warn("Unable update attributes for user $userName.\n");

#Setup Auto Pseudonyms
$ad->createAutoPseudonyms($userName); 

exit(0);
