source: admin/WebConsole/rest/remotepc.php @ f838845

918-git-images-111dconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacion
Last change on this file since f838845 was 6a68c4c, checked in by Ramón M. Gómez <ramongomez@…>, 5 years ago

#839: Fix bug when creating database event.

  • Property mode set to 100644
File size: 20.3 KB
RevLine 
[e0b6a5e]1<?php
2/**
3 * @file    remotepc.php
4 * @brief   OpenGnsys Server REST API consumed by UDS Server for Remote PC implementation.
5 * @warning All input and output messages are formatted in JSON.
6 * @note    Some ideas are based on article "How to create REST API for Android app using PHP, Slim and MySQL" by Ravi Tamada, thanx.
7 * @license GNU GPLv3+
8 * @author  Ramón M. Gómez, ETSII Univ. Sevilla
9 * @version 1.1.0 - First version
10 * @date    2017-02-01
11 */
12
[4073d14]13// OGAgent sessions log file.
14define('REMOTEPC_LOGFILE', '/opt/opengnsys/log/remotepc.log');
15
16// Function to write a line into log file.
17function writeRemotepcLog($message = "") {
18        file_put_contents(REMOTEPC_LOGFILE, date(DATE_ISO8601).": $message\n", FILE_APPEND);
19}
20
[e0b6a5e]21
22// REST routes.
23
24/**
[63e439a]25 * @brief    Reserve a client with an installed image and the older reservation time, then send a boot/reboot operation depending on its status.
[9ed6a67]26 * @warning  If "lab" parameter is specified, then choose a client from this lab.
[63e439a]27 * @note     Route: /ous/:ouid/images/:imageid/reserve, Method: POST
[9a39c75]28 * @param    integer ouid      OU identificator
29 * @param    integer imageid   image identificator
[63e439a]30 * @note     Input JSON message: {"labid":int_labid,"maxtime":int_hours}
[e0b6a5e]31 */
[d8b6c70]32$app->post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey',
[e0b6a5e]33    function($ouid, $imageid) use ($app) {
34        global $cmd;
35        global $AMBITO_ORDENADORES;
36        global $EJECUCION_COMANDO;
37        global $ACCION_INICIADA;
[232d1da]38        global $ACCION_FINALIZADA;
[e0b6a5e]39        global $ACCION_SINRESULTADO;
[232d1da]40        global $ACCION_FALLIDA;
[e0b6a5e]41        global $userid;
[6f17d76]42        $response = Array();
43        $ogagent = Array();
[0f21492]44        $repo = Array();
[e0b6a5e]45
[4073d14]46        if ($app->settings['debug'])
47                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[e0b6a5e]48        // Checking parameters.
[d8b6c70]49        try {
[4073d14]50                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
51                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
52                }
[2f11053]53                if (!checkIds($ouid, $imageid)) {
[d8b6c70]54                        throw new Exception("Ids. must be positive integers");
55                }
56                // Reading POST parameters in JSON format.
57                $input = json_decode($app->request()->getBody());
[2f11053]58                // Default: no lab. filter.
59                if (isset($input->labid)) {
60                        $labid = $input->labid != "0" ? $input->labid : '%';
61                } else {
62                        $labid = '%';
63                }
[d8b6c70]64                $maxtime = isset($input->maxtime) ? $input->maxtime : 24;       // Default: 24 h.
[2f11053]65                $opts = Array('options' => Array('min_range' => 1));    // Check for int>0
[4705afe]66                if (filter_var($labid, FILTER_VALIDATE_INT, $opts) === false and $labid !== '%') {
[d8b6c70]67                        throw new Exception("Lab id. must be positive integer");
68                }
[4705afe]69                if (filter_var($maxtime, FILTER_VALIDATE_INT, $opts) === false) {
[d8b6c70]70                        throw new Exception("Time must be positive integer (in hours)");
71                }
72        } catch (Exception $e) {
73                // Communication error.
74                $response["message"] = $e->getMessage();
[4073d14]75                if ($app->settings['debug'])
76                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[d8b6c70]77                jsonResponse(400, $response);
78                $app->stop();
79        }
[4073d14]80
81        if ($app->settings['debug'])
82                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: labid=$labid, maxtime=$maxtime");
[63e439a]83        // Choose older not-reserved client with image installed and get ogAdmServer data.
[e0b6a5e]84        $cmd->texto = <<<EOD
[d7a763b5]85SELECT adm.idusuario, ordenadores.idordenador, ordenadores.nombreordenador, ordenadores.ip,
[0f21492]86       ordenadores.mac, ordenadores.agentkey, par.numdisk, par.numpar,
87       aulas.idaula, aulas.idcentro, repo.ip AS repoip, repo.apikey AS repokey
[d7a763b5]88  FROM ordenadores
[e0b6a5e]89  JOIN aulas USING(idaula)
[e7d47882]90 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]91 RIGHT JOIN usuarios USING(idusuario)
[0f21492]92 RIGHT JOIN ordenadores_particiones AS par USING(idordenador)
[e0b6a5e]93 RIGHT JOIN imagenes USING(idimagen)
[0f21492]94 RIGHT JOIN repositorios AS repo ON repo.idrepositorio = ordenadores.idrepositorio
[6f17d76]95  LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
[9199fc7]96 WHERE adm.idusuario = '$userid'
[9a39c75]97   AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid' AND aulas.inremotepc = 1
98   AND imagenes.idimagen = '$imageid' AND imagenes.inremotepc = 1
[35a63b6]99   AND (remotepc.reserved < NOW() OR ISNULL(reserved))
[63e439a]100 ORDER BY remotepc.reserved ASC LIMIT 1;
[e0b6a5e]101EOD;
102        $rs=new Recordset;
103        $rs->Comando=&$cmd;
104        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]105        // Check if user is admin and client exists.
[e0b6a5e]106        $rs->Primero();
[9199fc7]107        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[2f11053]108                // Read query data.
109                $clntid = $rs->campos["idordenador"];
110                $clntname = $rs->campos["nombreordenador"];
111                $clntip = $rs->campos["ip"];
112                $clntmac = $rs->campos["mac"];
113                $agentkey = $rs->campos["agentkey"];
114                $disk = $rs->campos["numdisk"];
115                $part = $rs->campos["numpar"];
116                $labid = $rs->campos["idaula"];
117                $ouid = $rs->campos["idcentro"];
[0f21492]118                $repoip = $rs->campos["repoip"];
119                $repokey = $rs->campos["repokey"];
[2f11053]120                // Check client's status.
121                $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
[4073d14]122                if ($app->settings['debug'])
123                        writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[$clntip]['url'].".");
[2f11053]124                $result = multiRequest($ogagent);
125                if (empty($result[$clntip]['data'])) {
[d7a763b5]126                        // Client is off, send WOL command to ogAdmServer.
[2f11053]127                        // TODO: if client is busy?????
[4073d14]128                        if ($app->settings['debug'])
[d7a763b5]129                                writeRemotepcLog($app->request()->getResourceUri(). ": Send boot command through ogAdmServer: iph=$clntip,mac=$clntmac.");
130                        wol(1, [$clntmac], [$clntip]);
[0f21492]131                        // Send WOL command to client repository.
132                        $repo[$repoip]['url'] = "https://$repoip/opengnsys/rest/repository/poweron";
133                        $repo[$repoip]['header'] = Array("Authorization: ".$repokey);
134                        $repo[$repoip]['post'] = '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}';
135                        if ($app->settings['debug'])
[d7a763b5]136                                writeRemotepcLog($app->request()->getResourceUri(). ": Send Boot command through repo: repo=$repoip, ip=$clntip,mac=$clntmac.");
[0f21492]137                        $result = multiRequest($repo);
138                        // ... (check response)
139                        //if ($result[$repoip]['code'] != 200) {
140                        // ...
[2f11053]141                } else {
[4073d14]142                        // Client is on, send a rieboot command to its OGAgent.
[2f11053]143                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot";
144                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
[4073d14]145                        if ($app->settings['debug'])
146                                writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[$clntip]['url'].".");
[6f17d76]147                        $result = multiRequest($ogagent);
[2f11053]148                        // ... (check response)
149                        //if ($result[$clntip]['code'] != 200) {
150                        // ...
151                }
152                // DB Transaction: mark choosed client as reserved and
153                // create an init session command into client's actions queue.
154                $cmd->texto = "START TRANSACTION;";
155                $cmd->Ejecutar();
156                $timestamp = time();
157                $cmd->texto = <<<EOD
[e0b6a5e]158INSERT INTO remotepc
[d8b6c70]159   SET id='$clntid', reserved=NOW() + INTERVAL $maxtime HOUR, urllogin=NULL, urllogout=NULL
[6f17d76]160    ON DUPLICATE KEY UPDATE
[e0b6a5e]161       id=VALUES(id), reserved=VALUES(reserved),
[6f17d76]162       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
163EOD;
[2f11053]164                $t1 = $cmd->Ejecutar();
165                $cmd->texto = <<<EOD
[e0b6a5e]166INSERT INTO acciones
167   SET tipoaccion=$EJECUCION_COMANDO,
168       idtipoaccion=9,
169       idcomando=9,
[6f17d76]170       parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
[e0b6a5e]171       descriaccion='RemotePC Session',
[6f17d76]172       idordenador=$clntid,
173       ip='$clntip',
174       sesion=$timestamp,
[e0b6a5e]175       fechahorareg=NOW(),
176       estado=$ACCION_INICIADA,
177       resultado=$ACCION_SINRESULTADO,
178       ambito=$AMBITO_ORDENADORES,
[6f17d76]179       idambito=$clntid,
180       restrambito='$clntip',
[e0b6a5e]181       idcentro=$ouid;
[9a39c75]182EOD;
[2f11053]183                $t2 = $cmd->Ejecutar();
[232d1da]184                // Create event to remove reservation on timeout (15 min.).
[0c9d25a]185                $timeout = "15 MINUTE";
186                $cmd->texto = <<<EOD
187CREATE EVENT e_timeout_$clntid
188       ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL $timeout DO
189       BEGIN
[6a68c4c]190            SET @action_id = NULL;
[0c9d25a]191            UPDATE acciones
192               SET estado = $ACCION_FINALIZADA, resultado = $ACCION_FALLIDA,
193                   descrinotificacion = 'Timeout'
[232d1da]194             WHERE descriaccion = 'RemotePC Session' AND estado = $ACCION_INICIADA
[6a68c4c]195               AND idordenador = '$clntid'
196               AND (SELECT @action_id := idaccion);
197            IF @action_id IS NOT NULL THEN
[0c9d25a]198               UPDATE remotepc
199                  SET reserved=NOW() - INTERVAL 1 SECOND, urllogin=NULL, urllogout=NULL
[6a68c4c]200                WHERE id = '$clntid';
[232d1da]201               DELETE FROM acciones
[6a68c4c]202                WHERE idaccion = @action_id;
[232d1da]203            END IF;
[0c9d25a]204       END
205EOD;
206                $t3 = $cmd->Ejecutar();
[232d1da]207                if ($t1 and $t2 and $t3) {
[2f11053]208                        // Commit transaction on success.
209                        $cmd->texto = "COMMIT;";
210                        $cmd->Ejecutar();
[4073d14]211                        if ($app->settings['debug'])
212                                writeRemotepcLog($app->request()->getResourceUri(). ": DB tables and events updated, clntid=$clntid.");
[2f11053]213                        // Send init session command if client is booted on ogLive.
[4073d14]214                        if ($app->settings['debug'])
215                                writeRemotepcLog($app->request()->getResourceUri(). ": Send Init Session command to ogAdmClient, ido=$clntid,iph=$clntip,dsk=$disk,par=$part.");
[d7a763b5]216                        session($clntip, "$disk\r$part");
[2f11053]217                        // Compose JSON response.
[ffaf580]218                        $response['id'] = (int)$clntid;
[2f11053]219                        $response['name'] = $clntname;
220                        $response['ip'] = $clntip;
221                        $response['mac'] = $clntmac;
222                        $response['lab']['id'] = $labid;
[ffaf580]223                        $response['ou']['id'] = (int)$ouid;
[4073d14]224                        if ($app->settings['debug'])
225                                writeRemotepcLog($app->request()->getResourceUri(). ": Response, ".var_export($response,true).".");
[2f11053]226                        jsonResponse(200, $response);
[232d1da]227                } else {
[2f11053]228                        // Roll-back transaction on DB error.
229                        $cmd->texto = "ROLLBACK;";
230                        $cmd->Ejecutar();
[9a39c75]231                        // Error message.
[4073d14]232                        $response["message"] = "Database error: $t1, $t2, $t3";
233                        if ($app->settings['debug'])
234                                writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[9a39c75]235                        jsonResponse(400, $response);
236                }
[4073d14]237        } else {
238                if ($app->settings['debug'])
239                        writeRemotepcLog($app->request()->getResourceUri(). ": UNASSIGNED");
[9ed6a67]240        }
[e0b6a5e]241        $rs->Cerrar();
[a38cb26]242        $app->stop();
[e0b6a5e]243    }
244);
245
246
247/**
248 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
249 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
250 * @param    string urlLogin   URL to redirect login notification.
251 * @param    string urlLogout  URL to redirect logout notification.
252 * @warning  Events parameters will be stored in a new "remotepc" table.
253 */
254$app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey',
255    function($ouid, $labid, $clntid) use ($app) {
256        global $cmd;
257        global $userid;
[6f17d76]258        $response = Array();
[e0b6a5e]259
[4073d14]260        if ($app->settings['debug'])
261                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[d8b6c70]262        // Checking parameters.
[e0b6a5e]263        try {
[4073d14]264                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
265                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
266                }
[2f11053]267                if (!checkIds($ouid, $labid, $clntid)) {
[d8b6c70]268                        throw new Exception("Ids. must be positive integers");
269                }
270                // Reading JSON parameters.
[e0b6a5e]271                $input = json_decode($app->request()->getBody());
272                $urlLogin = htmlspecialchars($input->urlLogin);
273                $urlLogout = htmlspecialchars($input->urlLogout);
[4705afe]274                if (filter_var($urlLogin, FILTER_VALIDATE_URL) === false) {
[d8b6c70]275                        throw new Exception("Must be a valid URL for login notification");
276                }
[4705afe]277                if (filter_var($urlLogout, FILTER_VALIDATE_URL) === false) {
[d8b6c70]278                        throw new Exception("Must be a valid URL for logout notification");
279                }
[e0b6a5e]280        } catch (Exception $e) {
281                // Error message.
282                $response["message"] = $e->getMessage();
[4073d14]283                if ($app->settings['debug'])
284                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[e0b6a5e]285                jsonResponse(400, $response);
286                $app->stop();
287        }
288
[4073d14]289        if ($app->settings['debug'])
290                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: urlLogin=$urlLogin, urlLogout=$urlLogout");
[e0b6a5e]291        // Select client data for UDS compatibility.
292        $cmd->texto = <<<EOD
[9199fc7]293SELECT adm.idusuario, ordenadores.idordenador, remotepc.*
[e0b6a5e]294  FROM remotepc
295 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
296  JOIN aulas USING(idaula)
[e7d47882]297 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]298 RIGHT JOIN usuarios USING(idusuario)
[9199fc7]299 WHERE adm.idusuario = '$userid'
[e0b6a5e]300   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
301   AND ordenadores.idordenador = '$clntid';
302EOD;
303        $rs=new Recordset;
304        $rs->Comando=&$cmd;
305        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]306        // Check if user is admin and client exists.
[e0b6a5e]307        $rs->Primero();
[9199fc7]308        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[e0b6a5e]309                // Check if client is reserved.
[d8b6c70]310                if (! is_null($rs->campos["reserved"])) {
[9a39c75]311                        // Updating DB if client is reserved.
[d7352ab]312                        $cmd->CreaParametro("@urllogin", $urlLogin, 0);
313                        $cmd->CreaParametro("@urllogout", $urlLogout, 0);
[e0b6a5e]314                        $cmd->texto = <<<EOD
[63e439a]315UPDATE remotepc
316   SET urllogin=@urllogin, urllogout=@urllogout
317 WHERE id='$clntid';
[9a39c75]318EOD;
[d7352ab]319                        if ($cmd->Ejecutar()) {
320                                // Confirm operation.
[ffaf580]321                                $response = "";
322                                jsonResponse(200, $response);
[d7352ab]323                        } else {
324                                // Error message.
325                                $response["message"] = "Database error";
326                                jsonResponse(400, $response);
327                        }
[e0b6a5e]328                } else {
329                        // Error message.
[9a39c75]330                        $response["message"] = "Client is not reserved";
[e0b6a5e]331                        jsonResponse(400, $response);
332                }
333        }
334        $rs->Cerrar();
[a38cb26]335        $app->stop();
[e0b6a5e]336    }
337);
338
339
[4073d14]340/*
341 * @brief    Store session time (in sec).
342 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/session, Method: POST
[61e5ebd]343 * @param    int    deadLine   maximum session time, in seconds (0 for unlimited)
[4073d14]344 * @warning  Parameters will be stored in a new "remotepc" table.
345 */
[e0b6a5e]346$app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey',
[4073d14]347    function($ouid, $labid, $clntid) use ($app) {
348        global $cmd;
349        global $userid;
350        $response = Array();
351
352        if ($app->settings['debug'])
353                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
354        // Checking parameters.
355        try {
356                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
357                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
358                }
359                if (!checkIds($ouid, $labid, $clntid)) {
360                        throw new Exception("Ids. must be positive integers");
361                }
362                // Reading JSON parameters.
363                $input = json_decode($app->request()->getBody());
364                $deadLine = $input->deadLine;
[4705afe]365                if (filter_var($deadLine, FILTER_VALIDATE_INT) === false) {
[4073d14]366                        throw new Exception("Deadline must be integer");
367                }
[61e5ebd]368                if ($deadLine < 0) {
[23b08a8]369                        throw new Exception("Resource unavailable");
370                }
[4073d14]371        } catch (Exception $e) {
372                // Error message.
373                $response["message"] = $e->getMessage();
374                if ($app->settings['debug'])
375                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
376                jsonResponse(400, $response);
377                $app->stop();
378        }
379
380        if ($app->settings['debug'])
381                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: deadLine=$deadLine");
[a38cb26]382        // Get client's data.
383        $cmd->texto = <<<EOD
[9199fc7]384SELECT adm.idusuario, ordenadores.idordenador, remotepc.*
[a38cb26]385  FROM remotepc
386 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
387  JOIN aulas USING(idaula)
388 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[9199fc7]389 WHERE adm.idusuario = '$userid'
[a38cb26]390   AND aulas.idcentro = '$ouid' AND aulas.idaula = '$labid'
391   AND ordenadores.idordenador = '$clntid';
392EOD;
393        $rs=new Recordset;
394        $rs->Comando=&$cmd;
395        if (!$rs->Abrir()) return(false);       // Error opening recordset.
396        // Check if user is admin and client exists.
397        $rs->Primero();
[9199fc7]398        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[a38cb26]399                // Check if client is reserved.
[6c2501e]400                if (! is_null($rs->campos["urllogin"])) {
[a38cb26]401                        // Read query data.
402                        $clntid = $rs->campos["idordenador"];
403                        # Removing previous commands from OGAgent operations queue.
404                        if ($app->settings['debug'])
405                                writeRemotepcLog($app->request()->getResourceUri(). ": Updating database.");
406                        $cmd->texto = <<<EOD
407DELETE FROM ogagent_queue
[9240a63]408 WHERE clientid = '$clntid' AND operation IN ('popup-10', 'popup-5', 'poweroff');
[a38cb26]409EOD;
410                        $cmd->Ejecutar();
411                        # Add new commands to OGAgent operations queue.
[399af4d]412                        $cmd->texto = "INSERT INTO ogagent_queue (clientid, exectime, operation) VALUES";
[a38cb26]413                        if ($deadLine > 600) {
414                                # Add reminder 10 min. before deadline.
415                                $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND - INTERVAL 10 MINUTE, 'popup-10'),";
416                        }
417                        if ($deadLine > 300) {
418                                # Add reminder 5 min. before deadline.
419                                $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND - INTERVAL 5 MINUTE, 'popup-5'),";
420                        }
[23b08a8]421                        # Add power off command at deadline time.
422                        $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND, 'poweroff');";
[61e5ebd]423                        if ($deadLine == 0 or $cmd->Ejecutar()) {
[23b08a8]424                                // Confirm operation.
[61e5ebd]425                                $cmd->texto = "";
[ffaf580]426                                $response = "";
427                                jsonResponse(200, $response);
[61e5ebd]428                        } else {
[23b08a8]429                                // Error message.
430                                $response["message"] = "Database error";
431                                jsonResponse(400, $response);
[a38cb26]432                        }
433                } else {
434                        // Error message.
435                        $response["message"] = "Client is not reserved";
436                        jsonResponse(400, $response);
437                }
[61e5ebd]438        } else {
[a38cb26]439                // Error message.
440                $response["message"] = "Client does not exist";
441                jsonResponse(404, $response);
442        }
443        $rs->Cerrar();
[e0b6a5e]444    }
445);
446
447
[4073d14]448/**
449 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
450 * @brief    Unreserve a client and send a poweroff operation.
451 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/unreserve, Method: DELETE
452 */
[9a39c75]453$app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey',
[4073d14]454    function($ouid, $labid, $clntid) use ($app) {
[e0b6a5e]455        global $cmd;
456        global $userid;
[d7352ab]457        global $ACCION_INICIADA;
[9ed6a67]458        $response = Array();
459        $ogagent = Array();
[e0b6a5e]460
[4073d14]461        if ($app->settings['debug'])
462                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[9ed6a67]463        // Checking parameters.
[d8b6c70]464        try {
[a237bd1]465                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
466                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
467                }
[4073d14]468                if (!checkIds($ouid, $labid, $clntid)) {
469                        throw new Exception("Ids. must be positive integers");
470                }
[d8b6c70]471        } catch (Exception $e) {
472                // Error message.
473                $response["message"] = $e->getMessage();
[4073d14]474                if ($app->settings['debug'])
475                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[d8b6c70]476                jsonResponse(400, $response);
477                $app->stop();
478        }
479
[9ed6a67]480        // Select client data for UDS compatibility.
481        $cmd->texto = <<<EOD
[9199fc7]482SELECT adm.idusuario, ordenadores.idordenador, ordenadores.ip, ordenadores.agentkey, remotepc.reserved
[9ed6a67]483  FROM remotepc
484 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
485  JOIN aulas USING(idaula)
[e7d47882]486 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[9ed6a67]487 RIGHT JOIN usuarios USING(idusuario)
[9199fc7]488 WHERE adm.idusuario = '$userid'
[9ed6a67]489   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
490   AND ordenadores.idordenador = '$clntid';
491EOD;
492        $rs=new Recordset;
493        $rs->Comando=&$cmd;
494        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]495        // Check if user is admin and client exists.
[9ed6a67]496        $rs->Primero();
[9199fc7]497        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[9ed6a67]498                // Check if client is reserved.
[d8b6c70]499                if (! is_null($rs->campos["reserved"])) {
[9ed6a67]500                        // Read query data.
[40db2a3]501                        $clntip = $rs->campos["ip"];
[9ed6a67]502                        $agentkey = $rs->campos["agentkey"];
[90da353]503                        // DB Transaction: set reservation time to the past, remove pending
504                        // boot commands from client's and agent's queues, and drop its event.
[1d76269]505                        if ($app->settings['debug'])
506                                writeRemotepcLog($app->request()->getResourceUri(). ": Updating database.");
[9ed6a67]507                        $cmd->texto = "START TRANSACTION;";
508                        $cmd->Ejecutar();
509                        $cmd->texto = <<<EOD
510UPDATE remotepc
[63e439a]511   SET reserved=NOW() - INTERVAL 1 SECOND, urllogin=NULL, urllogout=NULL
[9ed6a67]512 WHERE id='$clntid';
513EOD;
514                        $cmd->Ejecutar();
515                        $cmd->texto = <<<EOD
516DELETE FROM acciones
517 WHERE idordenador = '$clntid'
[35a63b6]518   AND descriaccion = 'RemotePC Session';
[9ed6a67]519EOD;
520                        $cmd->Ejecutar();
[8182ab14]521                        $cmd->texto = <<<EOD
522DELETE FROM ogagent_queue
523 WHERE clientid = '$clntid' AND command IN ('popup-10', 'popup-5', 'poweroff');
[1b7c102]524EOD;
[8182ab14]525                        $cmd->Ejecutar();
[90da353]526                        $cmd->texto = "DROP EVENT IF EXISTS e_timeout_$clntid;";
527                        $cmd->Ejecutar();
[9ed6a67]528                        $cmd->texto = "COMMIT;";
529                        $cmd->Ejecutar();
530                        // Send a poweroff command to client's OGAgent.
531                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff";
532                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
[23b08a8]533                        if ($app->settings['debug'])
534                                writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[$clntip]['url'].".");
[9ed6a67]535                        $result = multiRequest($ogagent);
536                        // ... (check response)
[357352b]537                        //if ($result[$clntip]['code'] != 200) {
[9ed6a67]538                        // ...
539                        // Confirm operation.
[ffaf580]540                        $response = "";
541                        jsonResponse(200, $response);
[a38cb26]542                } else {
[9ed6a67]543                        // Error message.
544                        $response["message"] = "Client is not reserved";
545                        jsonResponse(400, $response);
546                }
[a38cb26]547        } else {
548                // Error message.
549                $response["message"] = "Client does not exist";
550                jsonResponse(404, $response);
551        }
[9ed6a67]552        $rs->Cerrar();
[e0b6a5e]553    }
554);
555
[b6ec162]556
Note: See TracBrowser for help on using the repository browser.