#!/usr/bin/perl

use strict;
use warnings;

use Fcntl;
use Config::General;
use XML::Simple;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use Sys::Syslog;
use Archive::Tar;
use File::Basename qw/basename/;

# Config
my $config = Config::General->new('/opt/secioss/etc/updaterpconf_api.ini');
my %param = $config->getall;

my $LOG_FACILITY = $param{'logfacility'};
my $URL = $param{'url'};
my $REVERSE_PROXY_URL = $param{'reverse_proxy_url'};

# Open syslog
openlog('CONF', 'pid', $LOG_FACILITY);

# Authentication & Get SESSCIONID
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
my %data = (
	action_login => 'true',
	id => $param{'tenant_admin'},
	password => $param{'tenant_admin_pw'},
);
my $req = POST($URL, \%data);
my $res = $ua->request($req);
if (!$res->is_success) {
	syslog('err', "Error: HTTP ".$res->message, $param{'tenant_admin'});
	exit 1;
}

# Perse XML
my $simple = XML::Simple->new();
my $data = $simple->XMLin($res->content);
my $code = $data->{code};
if ($code) {
	syslog('err', "Error: HTTP($code) ".$data->{message});
	exit 1;
}
my $sessid = $data->{sessid};

# get Config archive file
%data = (
	sessid => $sessid,
	action_saml_AppExport => 'true',
);
$req = POST($URL, \%data);
$res = $ua->request($req);
if (!$res->is_success) {
	syslog('err', "Error: HTTP ".$res->message, $param{'tenant_admin'});
	exit 1;
}
my $arc_file = '/tmp/'.$res->filename;

$_ = sysopen(my $fh, $arc_file, O_WRONLY|O_TRUNC|O_CREAT);
if (! $_) {
	syslog('err', "Error: save tar file($arc_file) $!");
	exit 1;
}
print($fh $res->decoded_content);
close($fh);

# remove old conf file
unlink glob('/etc/httpd/sso-ssl/*.conf*');
foreach my $file (glob('/var/www/conf/*.ini')) {
	if (basename($file) ne 'config.ini') {
		unlink($file);
	}
}

# extract tar
local $Archive::Tar::INSECURE_EXTRACT_MODE = 1;
my $tar = Archive::Tar->new;
$tar->setcwd('/');
if (! $tar->read($arc_file)) {
	syslog('err', "Error: extract tar($arc_file) $!");
	exit 1;
}
my @conf_files = $tar->extract();

unlink $arc_file;

# Create saml20-sp-hosted.php
$_ = sysopen($fh, '/opt/secioss/share/simplesamlphp/metadata/saml20-sp-hosted.php',O_WRONLY|O_TRUNC|O_CREAT);
if (! $_) {
	syslog('err', "Error: can't open file(saml20-sp-hosted.php) $!");
	exit 1;
}

print($fh "<?php\n");
print($fh '$metadata = array('."\n");
foreach my $conf_file (@conf_files) {
	my $file = '/'.$conf_file->{name};
	if ($file !~ /\/sso-ssl\/[^\/]+\.conf[^\/]*$/) {
		next;
	}
	
	my $rproxy_url = $REVERSE_PROXY_URL;
	if ($file =~ /\/[^\/]+\.conf_([^_\/]+)$/) {
                my $host = $1;
		$rproxy_url = "https://$host";
		if (!-d "/etc/httpd/conf.d/ssl-$host.conf") {
			system("sed s/HOST/$host/ /opt/secioss/etc/rp/ssl.conf > /etc/httpd/conf.d/ssl-$host.conf");
		}
	}

	$_ = sysopen(my $fhconf, $file, O_RDONLY);
	if (! $_) {
		syslog('err', "Error: read file($file) $!");
		next;
	}
	
	while (my $line = <$fhconf>){
		if ($line !~ /^<LocationMatch ".*\/\(\?\!sso\|saml\)">/) {
			next;
		}
		my $path = $rproxy_url;
		if ($line =~ /^<LocationMatch "\^\/(.*)\/\(\?\!sso\|saml\)">/) {
		    $path .= "/$1";
		}
		if ($path !~ /^https?:\/\/(.*)/) {
			next;
		}
		my $host = $1;
		
		print($fh "'".$path."' => array(");
		print($fh "'host'  => '".$host."',");
		print($fh "'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',");
		print($fh "),\n");
	}
	
	close($fhconf);
}
print($fh ');');
print($fh "\n?>");

# graceful restart httpd
if (system("systemctl status httpd >/dev/null 2>&1") == 0) {
	my $msg = `apachectl graceful`;
	if ($?) {
		syslog('err', "Error: restart apache graceful($?:$!)");
		exit 1;
	}
}

closelog();
