#!/usr/bin/perl
#
# AUTHPROTOCOL: STDIN2
#
use strict;
use Carp;
use DBI;
use Digest::MD5;
use lib qw(/usr/share/benno-web);
use Passwords;

if ($ENV{AUTHOK}) {
    print STDERR "Already authenticated, skip $0\n" if $ENV{DEBUG};
    exit 0;
}

if ($ARGV[0]) {
    print STDERR "Keine Argumente erlaubt.\n";
    print STDERR "Aufruf: echo \"USERNAME PASSWORT\" | $0\n";
    exit 1;
}

my $firstline  = <STDIN>;
my $secondline = <STDIN>;
chomp $firstline;
chomp $secondline;

my ($username,$password);
if (!$secondline) {
    # AUTHPROTO: STDIN
    ($username,$password) = split /\s+/,$firstline,2;
}
else {
    # AUTHPROTO: STDIN2
    $username = $firstline;
    $password = $secondline;
}

if (!$password) {
    print "ERROR ERR_NOPASS\n";
    print STDERR "Aufruf: echo -e \"<username>\n<passwort>\" | $0\n";
    exit 1;
}

my $configfile = '/etc/benno-web/benno.conf';
my $config = read_config($configfile);
my $dbh = db_connect($config);

my $sth = $dbh->prepare('SELECT * FROM user WHERE id = ?');
$sth->execute($username); 
my $row = $sth->fetchrow_hashref;
my $passwd_db   = $row->{'password'};

my $ERR = 'ERROR ERR_AUTH';
if ($passwd_db =~ /^\$2y\$10\$/) {
    if (password_verify($password,$passwd_db)) {
        $ERR = '';  # PASSWORD VERIFIED
    }
}
else {
    my $ctx = Digest::MD5->new;
    $ctx->add($password);
    my $passwd_md5= $ctx->hexdigest;

    if ($passwd_md5 eq $passwd_db) {
        $ERR = '';
        # update password
        my $bcrypt = password_hash($password,PASSWORD_BCRYPT,('cost' => 10));
        my $sth = $dbh->prepare('UPDATE user SET password = ? WHERE id = ?');
        $sth->execute($bcrypt,$username);
    }
}
if ($ERR) {
    print "ERROR ERR_AUTH\n";
    print STDERR "Passwort fuer User $username falsch.\n";
    exit 1;
}

print 'DISPLAYNAME '.$row->{'name'}."\n";
print 'ROLE '.$row->{'role'}."\n";

eval {
    my $entrycount = 0;
    my $cnth = $dbh->prepare('SELECT cid,scid FROM container WHERE userid = ?');
    $cnth->execute($username) or die "DB error: $!\n";
    while (my ($cid,$scid) = $cnth->fetchrow_array) {
        print "ARCHIVE $cid";
        print "/$scid" if $scid;
        print "\n";
        $entrycount++;
    }
    die unless $entrycount;
};
if ($@) { # dbversion < 2019121301 or no entries in container table
    foreach my $archive (split /,\s*/, $row->{archive}) {
        print 'ARCHIVE '.$archive."\n";
    }
}

my $sth = $dbh->prepare('SELECT address FROM address WHERE id = ?');
$sth->execute($username); 
my @adresslist;
while (my $row = $sth->fetchrow_hashref) {
    print 'MAIL '.$row->{'address'}."\r\n";
}

print "AUTH OK\n";
print "AUTHPARAM AUTHBY db\n";

### SUBS ######################################################################
# read_config
sub read_config
{
    my $configfile = shift;

    my $config = {};
    open CONF, $configfile or croak "Cannot open config file $configfile. $!\n";
    foreach my $line (<CONF>) {
        next if $line =~ /^$/;
        next if$line  =~ /^#/;
        chomp $line;
        my ($param,$value) = split(/\s*=\s*/,$line,2);
        $config->{$param} = $value;
    }

    return $config;
}


# db_connect
sub db_connect
{   
    my $config = shift;

    my $dbtype = $config->{DBTYPE} || 'sqlite:////var/lib/benno-web/bennoweb.sqlite';
    my $db     = $config->{DATABASE};
    my $dbhost = $config->{DBHOST} || 'localhost';
    my $dbport = $config->{DBPORT} || 3306;
    my $dbuser = $config->{DBUSER};
    my $dbpass = $config->{DBPASS};
    my $DBH;
    if ($dbtype eq 'mysql') {
        eval {
            my $dsn = "DBI:mysql:database=$db;host=$dbhost;port=$dbport";
            $DBH = DBI->connect($dsn,$dbuser,$dbpass);
        };
        if ($@) {
            print STDERR "ERROR: MySQL Driver not installed.\n";
            exit 1;
        }
    }
    else {
        if ($dbtype =~ /^sqlite:\/\/(\/.\S+)$/) {
            my $dsn = "dbi:SQLite:dbname=$1","","";
            $DBH = DBI->connect($dsn);
        }
    }
    return $DBH;
}

