#!/usr/bin/perl
#
#
use strict;
use Carp;
use CGI::Simple;
use IPC::Open3;
use lib qw(/usr/share/benno-auth-modules/);
use Benno::Config;

my $configfile = $ENV{rest_auth_configfile} || '/etc/benno-auth-modules/restauth.conf';
my $DEBUG = $ENV{DEBUG};


my $accept_type = 'text/plain';

my $q = CGI::Simple->new;
$q->charset('UTF-8');

my $accept_header = $q->http('Accept');
my $auth_string   = $q->param('POSTDATA');
my $request_key   = $q->url_param('apikey');

my $Conf;
eval {
    $Conf  = Benno::Config->new($configfile);
    $DEBUG = $DEBUG || $Conf->get('DEBUG');

    $Conf->get('REST_AUTH_APIKEY')  || die "ERROR apikey \"REST_AUTH_APIKEY\" not defined\n";
};
if ($@) {
    print STDERR "[REST_AUTH:0] configuration error: $@";
    return_error($q,'500 Internal Server Error',$accept_type);
}

return_error($q,'400 Bad Request', $accept_type) if ($accept_header ne $accept_type);
return_error($q,'403 Forbidden', $accept_type, 'URL PARAM apikey missing') unless $request_key;
return_error($q,'401 Unauthorized', $accept_type, 'API KEY mismatch') if ($request_key ne $Conf->get('REST_AUTH_APIKEY'));

# OK
print $q->header(
    -type   => 'text/plain',
    -status => 200,
);

my $auth_program = $Conf->get('REST_AUTH_PROGRAM') || '/usr/sbin/benno_auth.d';

my($wtr, $rdr, $err);
use Symbol 'gensym'; $err = gensym;
my $pid = open3($wtr, $rdr, $err, $auth_program);
foreach my $line (split /\\n/, $auth_string) {
    print $wtr "$line\n";
}
close $wtr;
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

# Log errors
foreach my $errline (<$err>) {
    print STDERR "$errline\n";
}

# Return lines
my $auth_status = 'AUTH ERROR';
foreach my $line (<$rdr>) {
    $auth_status = 'AUTH OK' if $line =~ /^AUTH\sOK/;
    print STDERR "[REST_AUTH:2] RETURN $line" if $DEBUG >= 2;
    print $line;
}

# AUTH LAST switch
my $auth_last = $Conf->get('AUTH_LAST');    # ALWAYS OK ERROR
if ($auth_last eq 'ALWAYS') {
    print "AUTH LAST\n";
}
elsif ($auth_last eq $auth_status) {        # OK || ERROR
    print "AUTH LAST\n";
}


### SUBS ###

# return_error
sub return_error
{
    my ($q,$status,$type,$errmsg) = @_;

    print $q->header(
        -type   => $accept_type,
        -status => $status,
    );
    print STDERR "[REST_AUTH:0] $status";
    print STDERR ": $errmsg" if $errmsg;
    print STDERR "\n";
    print "ERR_INTERN\n";
    exit;
}

1; ### EOP ###

