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

Last change on this file since b1ef135 was fe3a254, checked in by OpenGnSys Support Team <soporte-og@…>, 5 years ago

#990 Fix WOL call for RemotePC

This patch fixes the call to the WOL rest function by adapting it to the
new API.

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