<%@language = "javascript" %>
<% /*
    $Revision$
    $Id$

    File:           fac_scan_cust.asp
    Description:    FACILITOR remote support
                    API om omgevings data op te halen
                    In het bijzonder alle CUST folders en de SHA-check van
                    bestanden.
                    Wordt incidenteel aangeroepen als iemand op de FACWS001
                    portal 'refresh' klikt.
    Context:        Je moet ingelogd zijn als FACFAC bij een bepaalde klant
                    maar eigenlijk maakt het niet uit bij welke: de hele
                    CUST folder wordt gescanned
*/
var JSON_Result = true;
Server.ScriptTimeout=300; // in 5 minuten moet lukken
%>
<!-- #include file="../Shared/common.inc"-->
<!-- #include file="./fac_verify_sha.inc" -->
<%

user.checkAutorisation("WEB_FACFAC");

var alluser = {};
var sql = "SELECT username, created" // Dit vindt @Work alleen FCLT en niet AAXX
        + "  FROM all_users"
        + " WHERE length(username) = 4" // ik zou graag controleren of het een echte Facilitor user is maar daar kan ik niet bij
        + "    OR (length(username) = 9 AND username LIKE '%_TEST')"; // dan maar matchen op LOGC/XXXX of LOGC_TEST/XXXX_TEST
var oRs = Oracle.Execute(sql);
while (!oRs.Eof)
{
    alluser[oRs("username").Value] = new Date(oRs("created").Value); // nog niet gevonden in een oracle.udl
    oRs.MoveNext()
}
var ProviderVersion = String(Oracle.RealConnection.Properties("Provider Version"));
var ProviderName = String(Oracle.RealConnection.Properties("Provider Name"));

Oracle.RealConnection.Close();
Oracle = null; // Voorkom dat je per ongeluk 'gewoon' Oracle aanroept: hier moet je xdOracle gebruiken

var fullPath = Server.MapPath("../../CUST");

var fso = Server.CreateObject("Scripting.FileSystemObject")

var startFolder = fso.GetFolder(fullPath)
var fc1 = new Enumerator(startFolder.SubFolders);
var xdOracle = Server.CreateObject("ADODB.Connection");
var aFCLT = [];
var tmStartAll = new Date();

for (; !fc1.atEnd(); fc1.moveNext())
{
    var fldr = fc1.item();
    filename = fldr.Path.toUpperCase();

    var udl = fldr.Path + "\\oracle.udl";
    result = { cust: fldr.Name.toUpperCase()
             };
    if (!fso.FileExists(udl))
    {
        result.error = "No Oracle.udl";
        aFCLT.push(result);
        continue;
    }

    try
    {
        var str = "File Name=" + udl;
        xdOracle.Open(str);
        var realuser = 'fac_scan_cust';
        if (rooturl)
            realuser += "@" + rooturl;

        xdOracle.Execute("BEGIN dbms_application_info.SET_CLIENT_INFO({0}); END;".format(safe.quoted_sql(realuser)));

        result.datasource = xdOracle.Properties("Data source").Value;
        result.uname = xdOracle.Properties("User Name").Value;
        result.created = alluser[result.uname];
        delete alluser[result.uname];

        var sql = "SELECT fac_version_schema,"
                + "       fac_version_group,"
                + "       fac_version_putorders_date,"
                + "       fac_version_notify_date,"
                + "       fac_version_scheduler_date,"
                + "       fac_version_cleanup_date"
                + "  FROM fac_version";
        var oRs = xdOracle.Execute(sql);
        result.schemaversion = 'DB' + oRs("fac_version_schema").Value;
        result.custgroep = oRs("fac_version_group").Value;
        result.putorders_date = oRs("fac_version_putorders_date").Value!=null?new Date(oRs("fac_version_putorders_date").Value):null;
        result.notify_date = oRs("fac_version_notify_date").Value!=null?new Date(oRs("fac_version_notify_date").Value):null;
        result.scheduler_date = oRs("fac_version_scheduler_date").Value!=null?new Date(oRs("fac_version_scheduler_date").Value):null;
        result.cleanup_date = oRs("fac_version_cleanup_date").Value!=null?new Date(oRs("fac_version_cleanup_date").Value):null;
        oRs.Close();

        var sql = "SELECT fac_setting_pvalue"
                + "  FROM fac_setting"
                + " WHERE fac_setting_name = 'tsk_master_schema'";
        var oRs = xdOracle.Execute(sql);
        result.tsk_master_schema = oRs("fac_setting_pvalue").Value;
        oRs.Close();

        var sql = "SELECT user, created, expiry_date FROM user_users";
        var oRs = xdOracle.Execute(sql);
        result.created = new Date(oRs("created").Value);
        if (oRs("expiry_date").Value != null)
            result.expiry_date = new Date(oRs("created").Value);
        var txt = "Database user {0} was created on {1}".format(oRs("user").Value, toDateTimeString(new Date(oRs("created").Value)));
        oRs.Close();

        var sql = "SELECT aut_idp_audience"
                + "  FROM aut_idp"
                + " WHERE aut_idp_type = 4" // JWT
                + "   AND aut_idp_code = 'FACILITORSUPPORT'";
        var oRs = xdOracle.Execute(sql);
        if (!oRs.Eof)
            result.support_idp_audience = oRs("aut_idp_audience").Value;
        oRs.Close();

        // Deze fac_notificatie_systeemadres zijn 'ernstig', er wordt misschien niet gesynchroniseerd
        var sql = "SELECT count(*) FROM fac_notificatie"
                + " WHERE (fac_notificatie_systeemadres IS NOT NULL"
                + "        OR prs_bedrijfadres_key IS NOT NULL)"
                + "   AND fac_notificatie_datum < SYSDATE - 1/2/24"; // minstens half uur oud
        var oRs = xdOracle.Execute(sql);
        result.notisysqueue = oRs(0).Value;
        oRs.Close();

        var puo_const = { STATUS_PORTAL: 1 // Niet via Putorders.exe
                        , STATUS_EMAIL: 2
                        , STATUS_SMS:  4
                        , STATUS_POPUP: 8 // Niet via Putorders.exe
                        , STATUS_SUMMARY_XSL: 16 // SMS/Email subject via XSL?
                        , STATUS_APPPUSH: 32 // Naar Azure app
                        };
        // Putorders draait mogelijk niet
        var sql = "SELECT count(*) cnt, MIN(fac_notificatie_datum) fac_notificatie_datum"
                + "  FROM fac_notificatie"
                + " WHERE (   BITAND (fac_notificatie_status, " + (puo_const.STATUS_EMAIL | puo_const.STATUS_SMS| puo_const.STATUS_APPPUSH) + ") > 0"
                + "        OR fac_notificatie_systeemadres IS NOT NULL"
                + "        OR prs_bedrijfadres_key IS NOT NULL)"
        if (Application("otap_environment") != "O")
            sql += "   AND fac_notificatie_datum < SYSDATE - 1/2/24"; // minstens half uur oud
        var oRs = xdOracle.Execute(sql);
        result.notiqueue = oRs("cnt").Value;
        if (result.notiqueue)
            result.notidate = new Date(oRs("fac_notificatie_datum").Value);
        oRs.Close();

        // prs_perslid met logging aan is (op de langere termijn) onwenselijk
        var sql = "SELECT prs_perslid_key, "
                + "       prs_perslid_naam, "
                + "       prs_perslid_oslogin, "
                + "       prs_perslid_email, "
                + "       prs_perslid_aanmaak,"
                + "       prs_perslid_login"
                + "  FROM prs_perslid"
                + " WHERE prs_perslid_loglevel > 0"
                + "   AND prs_perslid_verwijder IS NULL";
        var oRs = xdOracle.Execute(sql);
        result.prs_logging = [];
        while (!oRs.Eof)
        {
            result.prs_logging.push({ key: oRs("prs_perslid_key").Value,
                                      naam: oRs("prs_perslid_naam").Value,
                                      email: oRs("prs_perslid_email").Value,
                                      oslogin: oRs("prs_perslid_oslogin").Value,
                                      aanmaak: new Date(oRs("prs_perslid_aanmaak").Value),
                                      login: oRs("prs_perslid_login").Value != null? new Date(oRs("prs_perslid_login").Value): null
                                     });
            oRs.MoveNext();
        }
        oRs.Close();

        if (Application("otap_environment") == "O")
        {
            var sql = "SELECT adm_tracking_date, "
                    + "       adm_tracking_osuser "
                    + "  FROM adm_tracking "
                    + " WHERE LOWER(adm_tracking_name) = 'anonymize.sql' "
                    + "    OR LOWER(adm_tracking_name) LIKE 'anonimiseer%.sql'";
            var oRs = xdOracle.Execute(sql);
            if (!oRs.Eof)
            {
                result.anonymized = { "date": new Date(oRs("adm_tracking_date").Value),
                                      "by": oRs("adm_tracking_osuser").Value
                                    };
            }
            else
            {
                oRs.Close()
                var sql = "SELECT 1"
                        + "  FROM prs_perslid"
                        + " WHERE prs_perslid_oslogin IS NULL"
                        + "    OR SUBSTR (prs_perslid_oslogin, 1, 1) <> '_'";
                var oRs = xdOracle.Execute(sql);
                if (oRs.Eof)
                {
                    result.anonymized = { "date": new Date(),
                                          "by": "Only '_' users found"
                                        };
                }
            }
            oRs.Close();
        }

        xdOracle.Close();
    }
    catch (e)
    {   // database user Afwezig of geen record in fac_version
        try
        {
            oRs.Close()
        } catch (e2) {};
        try
        {
            xdOracle.Close();
        } catch (e2) {};

        var ForReading = 1;
        var tsUnicode = -1;

        var fso = new ActiveXObject("Scripting.FileSystemObject");
        var f = fso.OpenTextFile(udl, ForReading, true, tsUnicode);
        var s = f.ReadLine();
        s = f.ReadLine();
        s = f.ReadLine(); //3e regel is interessant
        // Provider=OraOLEDB.xdOracle.1;Password=xxxxx;Persist Security Info=True;User ID=hcas;Data Source=fclt
        var sa = s.split(";");
        var data = ["UDL=" + fso.GetAbsolutePathName(udl)];
        for (var i = 0; i < sa.length; i++)
        {
            var itma = sa[i].split("=");
            if (itma.length == 2)
            {
                if (itma[0] == 'Provider' || itma[0] == 'User ID' || itma[0] == 'Data Source')
                    data.push(sa[i]);
            }
        }
        f.Close();

        result.error = e.description + "\n" + data.join("\n");
    }
    var offlinefile = fldr.Path + "\\offline.html";
    if (fso.FileExists(offlinefile))
        result.FCLToffline = offlinefile;
    var offlinefile = fldr.Path + "\\..\\offline.html";
    if (fso.FileExists(offlinefile))
        result.FCLToffline = offlinefile;

    aFCLT.push(result);
}

result = { aFCLT: aFCLT,
           retrieved: new Date(),
           duration : new Date().getTime() - tmStartAll,
           svnrevision: parseInt("$Revision$".replace(/\D/g,'')),
           extrauser: alluser,
           local_addr: String(Request.ServerVariables("LOCAL_ADDR")),
           remote_addr: String(Request.ServerVariables("REMOTE_ADDR")),
           ProviderVersion: ProviderVersion,
           ProviderName: ProviderName
         };

var oAbout = new ActiveXObject("SLNKDWF.About");
result.DLLPath = oAbout.DLLPath;
result.Buildtime = oAbout.Buildtime;
result.VersionString = oAbout.VersionString;
var msec = oAbout.usTimer/1e3;
result.upsince = new Date(new Date().getTime() - msec);

try
{
    var WshShell = new ActiveXObject("WScript.Shell");
    result.computername = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
}
catch (e)
{
    result.computername = "???";
}

var SHAinfo = findSHAinfo();
if (SHAinfo) // niet @Trunk
{
    delete SHAinfo["ok"]; // die geloven we wel
    result.SHAinfo = SHAinfo;
}


result.certificates = [];
//CertStore is "no license required", geen lockcode nodig
//oChilglob = new ActiveXObject("Chilkat_9_5_0.Global");
//var txt ="Version: " + oChilglob.Version;
//var success = oChilglob.UnlockBundle(S("puo_chilkat_secret"));
//if (success != 1)
//    result.certificate = "Chilkat_9_5_0 Unlock failed:\n" + oChilglob.LastErrorText;
function findCertificates(storeName)
{
    try
    {
        var certStore = new ActiveXObject("Chilkat_9_5_0.CertStore");
        certStore.AvoidWindowsPkAccess = 1;
        var success = certStore.OpenWindowsStore("LocalMachine", storeName, 1);
        if (success == 0)
        {
            result.certificatesMsg = "Failed to open certificate Store, Certificates not checked\n" + certStore.LastErrorHtml;
        }
        else
        {
            var nr = certStore.NumCertificates;
            for (var i = 0; i < certStore.NumCertificates; i++)
            {
                var cert = certStore.GetCertificate(i);
                if (!cert.ForServerAuthentication)
                    continue;
                var dtFrom = new Date(cert.ValidFromStr);
                var dtTo = new Date(cert.ValidToStr);
                result.certificates.push({
                                           storeName: storeName,
                                           IssuerCN: cert.IssuerCN,
                                           IssuerDN: cert.IssuerDN,
                                           Rfc822Name: cert.Rfc822Name, // bevat bij LetsEncrypt de SAN
                                           SubjectCN: cert.SubjectCN,
                                           SubjectDN: cert.SubjectDN,
                                           // altijd leeg? SubjectAlternativeName: cert.SubjectAlternativeName,
                                           validFrom: new Date(cert.ValidFromStr),
                                           validTo: new Date(cert.ValidToStr)
                                         });
            }
        }
    }
    catch(e)
    {
        result.certificatesMsg = "Chilkat_9_5_0 not installed. Certificates not checked\n" + e.description;
    }
}
// The key difference between Web Hosting store and Personal store is that
// Web Hosting store is designed to scale to higher numbers of certificates.
findCertificates("WebHosting");
findCertificates("My");

Response.Write(JSON.stringify(result));

// Oracle en xdOracle zijn beide al gesloten
// ASPPAGE_END();
%>
