#!/usr/bin/perl
#
# Benno Web AUTH module
#
# Expects:
#  - <username>\n<password>
#
# Returns:
#  - AUTH OK
#  - ERROR <ERRSYM>
#  - nothing (not affected for domain)

use strict;
use YAML::Tiny;
use HTTP::Tiny;
use JSON;

my $DEBUG       = $ENV{DEBUG};
my $domainconf  = $ENV{restauth_domainconfig} || '/etc/benno-auth-modules/restauth-domains.yml';

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

my $userdomain = (split /\@/, $bennouser, 2)[1];

print STDERR "[RESTAUTH:2] Check $userdomain in domainlist $domainconf\n" if $DEBUG >= 2;
my $yaml   = YAML::Tiny->read($domainconf) or die "Cannot read $domainconf: $!\n";

my $domainconfig = $yaml->[0]->{domains}->{$userdomain};
unless ($domainconfig) {
    $domainconfig = $yaml->[0]->{domains}->{'DEFAULT'};
}

unless ($domainconfig) {
    print STDERR "[RESTAUTH:2] User domain \"$userdomain\" not found in domainlist $domainconf\n" if $DEBUG >= 2;
    exit 0;
}


my $rest_url    = $domainconfig->{url};
my $rest_key    = $domainconfig->{apikey};
my $containers  = $domainconfig->{container};
my $options     = $domainconfig->{options};

unless ($rest_url || $rest_key) {
    print STDERR "[RESTAUTH:2] REST url not found in domainlist $domainconf for $userdomain\n" if $DEBUG >= 2;
    exit 0;
}

my $user_data;
eval {
    my $auth_response = rest_auth($rest_url,$bennouser,$bennopass,$rest_key);

    my $json = JSON->new->allow_nonref;
    $user_data = $json->decode($auth_response)
        or die "Cannot decode auth response: $!".' '.$auth_response;
};
if ($@) {
    print STDERR "ERROR remote error at $rest_url: $@\n";
    print "ERR_INTERN\n";
}

unless ($options->{overwrite_container} eq 'false') {
    delete $user_data->{ARCHIVE};
}

foreach my $container (keys %{$containers}) {
    print "ARCHIVE ".$containers->{$container}."\n";
}

my @retlines;
foreach my $param (keys %{$user_data}) {
    if (ref($user_data->{$param}) eq 'ARRAY') {
        foreach my $avalue(@{$user_data->{$param}}) {
            push @retlines, $param.' '.$avalue;
        }
    }
    else {
        push @retlines, $param.' '.$user_data->{$param};
    }
}


foreach my $rl (@retlines) {
    print "$rl\n";
}

### SUBS ###
sub rest_auth
{
    my ($endpoint_url,$user,$pass,$apikey) = @_;

    my  $credentials = {
        username => $user,
        password => $pass,
    };
    my $default_headers = {
        'Accept'        =>  'application/json',
        'Content-Type'  =>  'application/json',
    };

    if ($apikey) {
        $default_headers->{Authorization} =  'ApiKey '.$apikey;
    }

    my $http = HTTP::Tiny->new(default_headers => $default_headers);

    my $options->{content} = encode_json($credentials);
    my $response = $http->post($endpoint_url,$options);

    if ($response->{status} !~ /^2/) {
        die "$endpoint_url status (HTTP $response->{status})\n";
    }

    if (length $response->{content}) {
        return $response->{content};
    }
    else {
        die "cannot authenticate: no response data\n";
    }

}


sub return_error
{
    my ($msg,$log,$DEBUG) = @_;

    my $errmsg = $msg;
    if ($DEBUG) {
        $errmsg = $errmsg.' ('.$log
    }
    print STDERR "$msg\n";
    exit 1;
}


1; ### EOP ###

