|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
use Getopt::Long;
|
|
|
|
use DBI;
|
|
|
|
use esmith::ConfigDB;
|
|
|
|
use esmith::AccountsDB;
|
|
|
|
use Text::Unaccent::PurePerl qw(unac_string);
|
|
|
|
use utf8;
|
|
|
|
|
|
|
|
my $c = esmith::ConfigDB->open_ro or die "Can't open the configuration DB\n";
|
|
|
|
my $a = esmith::AccountsDB->open or die "Can't open the accounts DB\n";
|
|
|
|
|
|
|
|
my $domain = $c->get('DomainName')->value;
|
|
|
|
my $limesurvey = $c->get('limesurvey') or die "No limesurvey entry found in the config DB\n";
|
|
|
|
|
|
|
|
my $host = 'localhost';
|
|
|
|
my $dbname = $limesurvey->prop('DbName') || 'limesurvey';
|
|
|
|
my $dbpass = $limesurvey->prop('DbPassword') || '';
|
|
|
|
my $dbuser = $limesurvey->prop('DbUser') || 'limesurvey';
|
|
|
|
my $survey = '889944';
|
|
|
|
my @notify = ();
|
|
|
|
my $dry = 0;
|
|
|
|
my $ok_cnt = 0;
|
|
|
|
my $ko_cnt = 0;
|
|
|
|
|
|
|
|
GetOptions(
|
|
|
|
'dbname=s' => \$dbname,
|
|
|
|
'dbuser=s' => \$dbuser,
|
|
|
|
'dbpassword=s' => \$dbpass,
|
|
|
|
'survey=s' => \$survey,
|
|
|
|
'notify=s' => \@notify,
|
|
|
|
'dry-run' => \$dry
|
|
|
|
);
|
|
|
|
|
|
|
|
# Allow comma separated multi-argument
|
|
|
|
@notify = split(/,/, join(',', @notify));
|
|
|
|
|
|
|
|
if ($survey !~ m/^\d+$/){
|
|
|
|
die "$survey isn't a valid survey ID\n";
|
|
|
|
}
|
|
|
|
my $survey_table = 'survey_' . $survey;
|
|
|
|
my $new_date = undef;
|
|
|
|
|
|
|
|
my $col2field = {
|
|
|
|
submitdate => 'submitdate',
|
|
|
|
first_name => '889944X91X1181SQ001',
|
|
|
|
last_name => '889944X91X1181SQ002',
|
|
|
|
email => '889944X91X1181SQ003',
|
|
|
|
phone => '889944X91X1181SQ004',
|
|
|
|
end_contract => '889944X91X1189',
|
|
|
|
unit => '889944X90X1191',
|
|
|
|
unit_other => '889944X90X1191other',
|
|
|
|
supervisor_name => '889944X90X1190',
|
|
|
|
supervisor_name_other => '889944X90X1190other',
|
|
|
|
supervisor_email => '889944X90X1203'
|
|
|
|
};
|
|
|
|
|
|
|
|
my $dsn = "DBI:mysql:database=$dbname;host=localhost";
|
|
|
|
my $dbh = DBI->connect($dsn, $dbuser, $dbpass, { mysql_enable_utf8 => 1 });
|
|
|
|
my $last_run;
|
|
|
|
|
|
|
|
# Identify last time the script ran
|
|
|
|
my $sth = $dbh->prepare(
|
|
|
|
'SELECT submitdate FROM ' . $survey_table . ' WHERE token = \'last_run\'')
|
|
|
|
or die "prepare statement failed: $dbh->errstr()";
|
|
|
|
$sth->execute() or die "execution failed: $dbh->errstr()";
|
|
|
|
if ($sth->rows gt 1){
|
|
|
|
die "More than one last_run entry found\n";
|
|
|
|
} elsif ($sth->rows lt 1){
|
|
|
|
die "Last run not found\n";
|
|
|
|
}
|
|
|
|
while (my $ref = $sth->fetchrow_hashref) {
|
|
|
|
$last_run = $ref->{submitdate};
|
|
|
|
}
|
|
|
|
|
|
|
|
# Query all the submission done after last run
|
|
|
|
$sth = $dbh->prepare(
|
|
|
|
'SELECT ' . join(',', map { $col2field->{$_} . ' AS ' . $_ } keys %{$col2field}) . ' FROM ' . $survey_table . ' WHERE submitdate > ?'
|
|
|
|
) or die "prepare statement failed: $dbh->errstr()";
|
|
|
|
$sth->execute($last_run);
|
|
|
|
|
|
|
|
if ($sth->rows > 0){
|
|
|
|
print "Last run was $last_run\n";
|
|
|
|
print "Found " . $sth->rows . " responses to process\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $report = '';
|
|
|
|
while (my $ref = $sth->fetchrow_hashref) {
|
|
|
|
|
|
|
|
# Build info for this new user
|
|
|
|
my $info = {
|
|
|
|
login => unac_string(lc substr($ref->{first_name}, 0, 1) . lc substr($ref->{last_name},0,12)),
|
|
|
|
first_name => $ref->{first_name} || '',
|
|
|
|
last_name => $ref->{last_name} || '',
|
|
|
|
supervisor_name => $ref->{supervisor_name} || '',
|
|
|
|
unit => $ref->{unit} || '',
|
|
|
|
email => $ref->{email} || '',
|
|
|
|
phone => $ref->{phone} || '',
|
|
|
|
end_contract => $ref->{end_contract} || '',
|
|
|
|
};
|
|
|
|
$info->{login} =~ s/[^\da-z]//g;
|
|
|
|
foreach (qw(first_name last_name)){
|
|
|
|
utf8::encode($info->{$_});
|
|
|
|
}
|
|
|
|
# Extract email, as it can be in the form "Foo Bar" <foo.bar@baz.org>
|
|
|
|
$info->{email} = $1 if ($info->{email} =~ m/\<(.+\@.+)\>/);
|
|
|
|
# Blank out the email if not valid
|
|
|
|
$info->{email} = '' if not ($info->{email} =~ m/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/);
|
|
|
|
|
|
|
|
# Keep only the day for the end of contract
|
|
|
|
$info->{end_contract} = $1 if ($info->{end_contract} =~ m/^(\d{4}\-\d{1,2}\-\d{1,2})/);
|
|
|
|
|
|
|
|
# unit and supervisor can be selected from a dropdown, or entered after selecting "other"
|
|
|
|
# So we have to do the lookup
|
|
|
|
my $ansh = $dbh->prepare('SELECT answer FROM answers WHERE code = ? AND qid = ?') or die "prepare statement failed: $dbh->errstr()";
|
|
|
|
foreach my $field (qw(unit supervisor_name)){
|
|
|
|
# We have to extract question ID to query the answers table
|
|
|
|
if ($info->{$field} eq '-oth-'){
|
|
|
|
$info->{$field} = $ref->{$field . '_other'};
|
|
|
|
} else {
|
|
|
|
my $qid = $col2field->{$field};
|
|
|
|
$qid =~ s/.*(\d{4})$/$1/;
|
|
|
|
$ansh->execute($ref->{$field},$qid);
|
|
|
|
if ($ansh->rows == 1){
|
|
|
|
while (my $ansref = $ansh->fetchrow_hashref){
|
|
|
|
$info->{$field} = $ansref->{answer};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
utf8::encode($info->{$field});
|
|
|
|
}
|
|
|
|
|
|
|
|
# Validate data
|
|
|
|
my $msg = '';
|
|
|
|
foreach my $field (qw(login first_name last_name email end_contract unit supervisor_name)){
|
|
|
|
$msg .= "\n$field $info->{$field} contains invalid data\n" if ($info->{$field} !~ m/[\w\-]*/ or length($info->{$field}) > 60);
|
|
|
|
}
|
|
|
|
|
|
|
|
unless (esmith::AccountsDB::validate_account_name($info->{login})){
|
|
|
|
$msg .= "Created login $info->{login} is invalid\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($a->get($info->{login})){
|
|
|
|
$msg .= "A user with login $info->{login} already exists\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
$report .= "-----------------------------------------------------------------------\n";
|
|
|
|
if ($msg ne ''){
|
|
|
|
$ko_cnt++;
|
|
|
|
$report .= "An error occured while processing account for $info->{last_name} $info->{first_name}. " .
|
|
|
|
"The error is : $msg\n";
|
|
|
|
} else {
|
|
|
|
|
|
|
|
# Default expiration is at the end of the current year
|
|
|
|
if ($info->{end_contract} eq ''){
|
|
|
|
$info->{end_contract} = (localtime())[5] + 1900 . '-12-31';
|
|
|
|
}
|
|
|
|
|
|
|
|
print "Creating user account $info->{login} ($info->{first_name} $info->{last_name})\n";
|
|
|
|
|
|
|
|
if (not $dry){
|
|
|
|
$a->new_record($info->{login}, {
|
|
|
|
type => 'user',
|
|
|
|
FirstName => $info->{first_name},
|
|
|
|
LastName => $info->{last_name},
|
|
|
|
Phone => $info->{phone},
|
|
|
|
Dept => $info->{unit},
|
|
|
|
Company => 'Univ de Bordeaux',
|
|
|
|
PasswordSet => 'no',
|
|
|
|
ForwardAddress => $info->{email},
|
|
|
|
PreferredMail => $info->{email},
|
|
|
|
EmailForward => 'forward',
|
|
|
|
ExpireLockOn => $info->{end_contract},
|
|
|
|
ExpireAutoReply => 'enabled',
|
|
|
|
ExpireWarnUser => 'enabled',
|
|
|
|
ExpireDeleteAfterLock => 30,
|
|
|
|
MaxBlocks => 5120000,
|
|
|
|
MaxBlocksSoftLim => 4608000
|
|
|
|
});
|
|
|
|
|
|
|
|
unless ( system("/sbin/e-smith/signal-event", "user-create", $info->{login}) == 0 ){
|
|
|
|
$report .= "Error occured while creating account $info->{login}, please contact your administrator\n";
|
|
|
|
$ko_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$ok_cnt++;
|
|
|
|
$report .= <<_EOF;
|
|
|
|
|
|
|
|
New account created (please, review group membership and set a password)
|
|
|
|
|
|
|
|
* Login : $info->{login}
|
|
|
|
* Last name : $info->{last_name}
|
|
|
|
* First name : $info->{first_name}
|
|
|
|
* Email : $info->{email}
|
|
|
|
* Unit : $info->{unit}
|
|
|
|
* Supervisor : $info->{supervisor_name}
|
|
|
|
* Expiration date : $info->{end_contract}
|
|
|
|
_EOF
|
|
|
|
|
|
|
|
$report .= "\n\n\n";
|
|
|
|
}
|
|
|
|
$new_date = $ref->{submitdate};
|
|
|
|
}
|
|
|
|
|
|
|
|
# Update the last run entry
|
|
|
|
if (defined $new_date and not $dry){
|
|
|
|
$sth = $dbh->prepare(
|
|
|
|
"UPDATE `$survey_table` SET `submitdate` = ? WHERE `token` = 'last_run'")
|
|
|
|
or die "prepare statement failed: $dbh->errstr()";
|
|
|
|
$sth->execute($new_date) or die "execution failed: $dbh->errstr()";
|
|
|
|
}
|
|
|
|
$sth->finish;
|
|
|
|
print $report;
|
|
|
|
|
|
|
|
if ($ok_cnt > 0 or $ko_cnt > 0){
|
|
|
|
foreach my $email (@notify){
|
|
|
|
print "Sending notification to $email\n";
|
|
|
|
open(QMAIL, "|/var/qmail/bin/qmail-inject -fdo-not-reply\@$domain $email")
|
|
|
|
|| die "Could not send mail via qmail-inject!\n";
|
|
|
|
|
|
|
|
print QMAIL <<EOH_;
|
|
|
|
To: $email
|
|
|
|
From: do-not-reply\@$domain
|
|
|
|
Subject: Account creation report
|
|
|
|
EOH_
|
|
|
|
print QMAIL $report;
|
|
|
|
|
|
|
|
close QMAIL;
|
|
|
|
}
|
|
|
|
}
|