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

configure-oglivelgromero-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 7965580 was 9831706, checked in by Natalia Serrano <natalia.serrano@…>, 19 months ago

Return a random computer

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