#!/usr/bin/perl

# -----------------------COMENTARIO GLOBAL-----------------------
# ---------------------------------------------------------------
# PROPOSITO
# ---------
# Obtener keys para decriptación de tokens desde un provider de openid connect.
# ---------------------------------------------------------------
# INVOCACIONES ACEPTADAS.
# ------------------------
# Desde CLI exclusivamente.
#
# Retorna:
#
# Ejemplo:
# perl /[webroot]/cgi-cpn/sso/prontus_oidc_get_keys.pl [nombre_prontus]
# ---------------------------------------------------------------
#
#--------------------BEGIN SCRIPT--------------------
use strict;
use utf8;

BEGIN {
    use FindBin qw($Bin);
    my $pathLibsProntus = $Bin;
    unshift(@INC,$pathLibsProntus);
    $pathLibsProntus =~ s/\/[^\/]+\/?$//;
    unshift(@INC,$pathLibsProntus); # Para dejar disponibles las librerias de prontus
}

# ---------------------------------------------------------------
# DECLARACIONES GLOBALES.
# ---------------------------------------------------------------
use lib_stdlog;
&lib_stdlog::set_stdlog($0, 51200);

use prontus_varglb; &prontus_varglb::init();
use lib_prontus;
use LWP::UserAgent ();
use JSON;
use MIME::Base64;
use URI::Escape;
use glib_str_03; #para random_string
use lib_cookies;
use glib_fildir_03;

main: {
    &lib_prontus::setUtf8();

    my $STATE = 'state-'.&glib_str_03::random_string(30);

    my $PRONTUS_ID = $ARGV[0];
    $prontus_varglb::PRONTUS_ID = $PRONTUS_ID;

    # Valida datos de entrada
    if (scalar @ARGV < 1) {
        print STDERR "Intento de invocación sin los parámetros indispensables.\n";
        print "Uso: perl $0 {prontus_id}\n";
        exit;
    }

    $prontus_varglb::PRONTUS_ID = $ARGV[0];

    my $msg_load = &lib_prontus::load_config_by_id($prontus_varglb::PRONTUS_ID);
    if ($msg_load ne '') {
        print STDERR "Ha ocurrido un error: $msg_load\n";
        print "Ha ocurrido un error al ejecutar el script. Revise el log de errores.";
        exit;
    }

    if ($prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'OIDC_HABILITADO'} ne 'SI') {
        print STDERR "ERROR: [", scalar localtime, "] No está habilitada la funcionalidad de Single Sign-On con OpenID Connect en este Prontus.\n";
        print "ERROR: No está habilitada la funcionalidad de Single Sign-On con OpenID Connect en este Prontus.\n";
        exit;
    }

    my $CLIENT_ID = $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'OIDC_CLIENT_ID'};
    my $ISSUER = $prontus_varglb::CONFIG{$prontus_varglb::PRONTUS_ID}{'OIDC_ENDPOINT_URI'};

    if ($CLIENT_ID eq '' or $ISSUER eq '') {
        print STDERR "ERROR: [", scalar localtime, "] No están ingresados los parámetros OIDC_CLIENT_ID u OIDC_ENDPOINT_URI en la configuración de Prontus.\n";
        print "ERROR: No están ingresados los parámetros OIDC_CLIENT_ID u OIDC_ENDPOINT_URI en la configuración de Prontus.\n";
        exit;
    }

    # creamos el directorio para guardar el archivo de keys, si no existe.
    my $base_dir = "$prontus_varglb::DIR_SERVER/$prontus_varglb::PRONTUS_ID/cpan/data/";
    my $keys_dir = 'oidc_keys';
    &glib_fildir_03::crea_dir($base_dir, $keys_dir) if ! -d $keys_dir;

    my $ua = LWP::UserAgent->new;
    $ua->agent();
    $ua->timeout(10);
    $ua->env_proxy;

    # conseguimos las keys para validar los tokens.
    my $response = $ua->get("$ISSUER/v1/keys?client_id=$CLIENT_ID");
    my $content = decode_json($response->decoded_content);

    if (!defined ($content->{'keys'}) or defined ($content->{'errorCode'})) {
        print STDERR "Error: [", scalar localtime, "] no recibimos las keys de decriptación: [$content->{'errorCode'}], mensaje: [$content->{'errorSummary'}]\n";
        print "Error: no recibimos las keys de decriptación: [$content->{'errorCode'}], mensaje: [$content->{'errorSummary'}]\n";
        exit;
    }

    my $key = $content->{'keys'}[0];
    $key = encode_json($key);
    &glib_fildir_03::write_file("$base_dir$keys_dir/key_file.json", $key);
    exit;
}
