#!/usr/bin/perl
# Update IPDB users table with user/password data from 5-minute cron'ed
# push from billing
##
# $Id$
# Copyright (C) 2007-2010,2017,2022 - Kris Deugau <kdeugau@deepnet.cx>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
##

use strict;
use warnings;
use DBI;
use Getopt::Long;

# don't remove!  required for GNU/FHS-ish install from tarball
##uselib##

# Taint-safe (ish) voodoo to push "the directory the script is in" into @INC.
use File::Spec ();
use File::Basename ();
my $path;
BEGIN {
    $path = File::Basename::dirname(File::Spec->rel2abs($0));
    if ($path =~ /(.*)/) {
        $path = $1;
    }
}
use lib $path;

# Watch for longstanding senior staff deletes;  these should make waves when removed
my %seniorstaff = map { $_ => 1 } qw ();

my $doadd = 0;
my $dodel = 0;
GetOptions(
	"add|a" => \$doadd,
	"delete|d" => \$dodel,
);

use MyIPDB;

my $ip_dbh;
my $errstr;
($ip_dbh,$errstr) = connectDB_My;
if (!$ip_dbh) {
  die "Database error: $errstr\n";
}
initIPDBGlobals($ip_dbh);

my %userhash;
my $passfile = "/var/www/ipdb.example.com/ip/.htpasswd";

die ".htpasswd error:  file is empty!\n"
	if -z $passfile;

die ".htpasswd error:  file seems too small: ".(-s $passfile)."\n"
	if (-s $passfile <500);

open HTPASS, "<$passfile";

my $sth = $ip_dbh->prepare("SELECT count(*) FROM users WHERE username = ?");
my $insert_user = $ip_dbh->prepare("INSERT INTO users (username) VALUES (?)");
my $del_user = $ip_dbh->prepare("DELETE FROM users WHERE username = ?");

while (<HTPASS>) {
  chomp;
  my ($user,undef) = split /:/;
  $sth->execute($user);
  my @data = $sth->fetchrow_array();
  if ($data[0] == 0) {
    if ($doadd) {
      $insert_user->execute($user) or print "error inserting $user: ".$DBI::errstr."\n";
      print "new user: $user\n";
    } else {
      print "pending new user: $user\n";
    }
  }
  $userhash{$user} = '!';
}

# and now to delete users that have been removed
$sth = $ip_dbh->prepare("SELECT username,acl FROM users ORDER BY username");
$sth->execute;
while (my @data = $sth->fetchrow_array()) {
  if (!$userhash{$data[0]}) {
    # safety net for senior key staff
    if ($seniorstaff{$data[0]}) {
      print "skipping delete of $data[0], update access-pwd-update.pl if they've really left\n";
      next;
    }
    if ($dodel) {
      $del_user->execute($data[0]) or print "error deleting $data[0]: ".$DBI::errstr."\n";
      print "deleting $data[0] (acl $data[1])\n";
    } else {
      print "pending user delete '$data[0]'\n";
    }
  }
}
