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

     File:          bez_admitcheck.asp
     Description:   Controleer de legitimiteit van toegang tot het gebouw/locatie/organisatie op basis van het huidige tijdstip
     Context:       Via een gescande QR-code
     Parameters:    een goede key. Welke key wordt meegegeven bepaalt tegen welk interval er wordt gecontroleerd.

     NOTE:          HMAC bescherming is op de min(fac_tracking_key)|min(fac_tracking_key)
                    Dat is niet waterdicht maar goed genoeg

                    Voor de veiligheid/privacy laten we niet meer zien dan nodig/handig is, tenzij verbose (todo)
                    Uitbreidingen zijn denkbaar in de richting van: tonen van pasfoto van de user om visueel te checken of de QRC bij de persoon hoort.

                    In de bon bijvoorbeeld

                    Toegangscode: http://uwva.facws001.sg.nl/trunk/fclttoegang(reservering,<xsl:value-of select="key"/>)<p/>
                    <xsl:element name="img">
                        <xsl:attribute name="style">height: 3.25cm; width: 3.25cm; margin:0cm; padding:0; border:none</xsl:attribute>
                        <xsl:attribute name="qrc">http://uwva.facws001.sg.nl/trunk/fclttoegang(reservering,<xsl:value-of select="key"/>)</xsl:attribute>
                    </xsl:element>

    Status:         POC

*/ %>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/iface.inc" -->
<%

var key = getQParamInt("k"); // parameter naam op 'k=' houden voor hmac check
var xmlnode = getQParamSafe("xmlnode"); // reservering, afspraak, opdracht

// Eerst hmac/tampercheck
var sql = "SELECT MIN(fac_tracking_key) fac_tracking_key,"
        + "       MIN(fac_tracking_datum) fac_tracking_datum"
        + "  FROM fac_tracking ft, fac_srtnotificatie fsn"
        + " WHERE ft.fac_srtnotificatie_key = fsn.fac_srtnotificatie_key"
        + "   AND fac_srtnotificatie_xmlnode = " + safe.quoted_sql(xmlnode)
        + "   AND fac_tracking_refkey = " + key;
var oRs = Oracle.Execute(sql)
if (oRs.Eof)
{
    Response.Write("<h1>Dit is een ongeldige code (1)<br>This is an invalid code (1)</h1>");
    Response.End;
}
var locksecret = String(oRs("fac_tracking_key").Value) + "|" + toISODateTimeString(new Date(oRs("fac_tracking_datum").Value));
__Log("Checking with secret {0}".format(locksecret));

protectQS.verify({ sleutel: locksecret,
                   expire: 90 * 24 * 60, // maximaal 90 dagen?
                   checkpath: "/", // altijd tegen de root zonder default.asp
                   no_user_key: true }); // tamper check

// For optional closer scoping
// gebouw_key: aanvullende eis dat de reservering in dit gebouw moet zijn ("bij de voordeur")
// locatie_key: aanvullende eis dat de reservering op deze locatie moet zijn ("bij de slagboom")
var gebouw_key = getQParamInt("geb_key", -1);
var locatie_key = getQParamInt("loc_key", -1);

var g_marge = getQParamInt("marge", 30); // minuten
var g_checkonly = true;

// Extensions, optional
// verbose=1 (of quiet=0) om toch wel info te tonen (supervisormode)

// Souplesse:
// day: de juiste dag is al goed genoeg
// marge: tijd dat je eerder of later mag zijn


var sql = "";
var entityname = "";
switch (xmlnode)
{
    case "reservering":
        sql = "SELECT res_reservering_key||'/'||res_rsv_ruimte_volgnr id, "
            + "       res_rsv_ruimte_van van, "
            + "       res_rsv_ruimte_tot tot"
            + "  FROM res_rsv_ruimte"
            + " WHERE res_rsv_ruimte_key = " + key
            + "   AND res_rsv_ruimte_verwijder IS NULL";
        //( locatie_key is not too trivial to add)
        entityname = L("lcl_reservation");
        break;
    case "afspraak":
        sql = "SELECT bez_afspraak_key id, "
            + "       bez_afspraak_datum van, "
            + "       bez_afspraak_eind tot"
            + "  FROM bez_afspraak"
            + " WHERE bez_afspraak_key = " + key
            + (locatie_key > 0 ? " AND alg_locatie_key = " + locatie_key : "");
        entityname = L("lcl_vis_appointment");
        break;
    case "opdracht":
        sql = "SELECT COALESCE(mld_opdr_id, mld_melding_key||'/'||mld_opdr_bedrijfopdr_volgnr) id, "
            + "       COALESCE(mld_opdr_plandatum, mld_opdr_datumbegin) van, "
            + "       COALESCE(mld_opdr_plandatum2, mld_opdr_einddatum) tot"
            + "  FROM mld_opdr"
            + " WHERE mld_opdr_key = " + key
            + (locatie_key > 0 ? " AND mld_alg_locatie_key = " + locatie_key : "");
        entityname = L("lcl_shared_order");
        break;
    default:
        Response.Write("<h1>Dit is een ongeldige code (2)<br>This is an invalid code (2)</h1>");
        Response.End;
}


// What we might do depends on who i am, what authorisations i have.
// And also the timing with respect to the event (future, now, past)

// Something like this:
//
// if identified-user
//  if future-event
//   if owner-of-entity
//      access to entity (directe link om te tonen/editen)
//   else
//      general info related to event (online version of the form, plus details about visit, parking, travels etc)
//  else if current-event
//   check relevant autorisation in order of specificy
//   BEZBOF: check admittance and register it
//   XXXXXX: ..... (optional other functions/roles, like RESBOF for "paying" the restaurant
//  else -- past-event
//   [CODE IS INVALID]
//  end if
// else --unidentified user (maybe the visitor, or just some anonymous scanner)
//  show some harmless maybe specific but very safe info, maybe http://<customersite>
// end if
//

var authparams = user.checkAutorisation("WEB_BEZBOF", true);

// ongeldige key
var oRs = Oracle.Execute(sql);
if (oRs.Eof)
{
    Response.Write("<h1>Dit is een ongeldige code (3)<br>This is an invalid code (3)</h1>");
}
else
{
%>
<html>
  <head>
<%
    FCLTHeader.Generate();
%></head><%
    var id = oRs("id").value;
    var van  = new Date(oRs("van").value);
    var tot  = new Date(oRs("tot").value);
    var nu = new Date();
    var early = new Date(van); early.setMinutes(early.getMinutes() - g_marge);
    //var late = new Date(); // laatste seconde mag je nog binnenkomen

    oRs.Close();

    var admitted = false;
    if (nu < early)
    {
        Response.Write("<body class='admitscreen nok'><h3>U bent te vroeg</h3>{0} {1}<br><div class='interval'>{2} - {3}</div>".format(entityname, id, toDateTimeString(van, false, false, true), toTimeString(tot, false)));
    }
    else if (tot < nu)
    {
        Response.Write("<body class='admitscreen nok'><h3>U bent te laat</h3>{0} {1}<br><div class='interval'>{2} - {3}</div>".format(entityname, id, toDateTimeString(van, false, false, true), toDateTimeString(tot, false)));
    }
    else
    {
        Response.Write("<body class='admitscreen ok'><h3>Welkom!</h3><br><div class='interval'>{2} - {3}</div>".format(entityname, id, toDateTimeString(van, false, false, true), toTimeString(tot, false)));
        admitted = true;
    }
    Response.Write("<br><div class='admitfooter'>Facilitor scanner {0}</div>".format(toDateTimeString(nu, true, true)));
    Response.Write("</body>");


    // Process admittance
    // Let op: iemand kan 'voor de gein' een (/zijn eigen) bon scannen om te zien wat de QR-code doet.
    //         dat mag echt niet zo maar tot actie leiden! Daarom even if (false)
    if (false && admitted && !g_checkonly)
    {
        var sql = "";
        if (rsv_ruimte_key >-1)
        {
            sql = ""; // iets tegen de noshow?
        }
        else if (bez_afspraak_key > -1)
        {
            sql = "UPDATE bez_bezoeker .."; // bezoeker is binnen? Oeps, we weten niet welke bezoeker, slechts welke afspraak
        }
        else if (mld_opdr_key > -1)
        {
            sql = "";  // een ORDUP-tracking dat de uitvoerder binnen is?
        }

        if (sql != "")
        {
            Oracle.Execute(sql);
        }

    }
}

%>
<% ASPPAGE_END(); %>
