source: admin/WebConsole/rest/server.php @ 1d1e06d

Last change on this file since 1d1e06d was a9a6da5e, checked in by Ramón M. Gómez <ramongomez@…>, 5 years ago

#839: Fix index overflow in REST route GET /ous/{ouid}/labs/{labid}/clients/status

  • Property mode set to 100644
File size: 31.4 KB
Line 
1<?php
2/**
3 * @file    index.php
4 * @brief   OpenGnsys Server REST API manager.
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    2016-09-19
11 */
12
13
14// Auxiliar functions.
15
16/**
17 * @brief    Check if user is administrator and print error messages if not.
18 * @param    int adminid  Administrator id.
19 * @return   boolean      "true" if admin id. is equals to global user id., otherwise "false".
20 */
21function checkAdmin($adminid) {
22        global $userid;
23
24        if ($adminid == $userid) {
25                return true;
26        } else {
27                // Print error message.
28                $response['message'] = 'Cannot access this resource';
29                jsonResponse(401, $response);
30                return false;
31        }
32}
33
34/**
35 * @fn    addClassroomGroup(&$classroomGroups, $rs)
36 * @brief Funcion privada usada para añadir grupos de aulas recursivamente
37 * @param classroomGroups Grupos de aulas que pueden contener más grupos
38 * @param rs resultset de la consulta a la base de datos.
39 */
40function addClassroomGroup(&$classroomGroups, $rs){
41
42        array_walk($classroomGroups, function(&$group,$key){
43                global $rs;
44                if (isset($group['id']) && $group['id'] === $rs->campos["group_group_id"]) {
45                        array_push($group["classroomGroups"],array("id" => $rs->campos["group_id"],
46                                "name" => $rs->campos["nombregrupoordenador"],
47                                "comments" => $rs->campos["comentarios"],
48                                "classroomGroups" => array()));
49                }
50                else if(count($group["classroomGroups"]) > 0){
51                        addClassroomGroup($group["classroomGroups"], $rs);
52                }
53                /**/
54        });
55}
56
57/**
58 * @fn    getStatus(ouid, labid, [clntid])
59 * @brief    Returns client execution status or status of all lab's clients.
60 * @param    int ouid    OU id.
61 * @param    int labid   Lab. id.
62 * @param    int clntid  Client id. (optional)
63 * @return   string      JSON object or array of objects including status data.
64 */
65function getStatus($ouid, $labid, $clntid=0) {
66        global $userid;
67        global $cmd;
68        global $LONCABECERA;
69        global $LONHEXPRM;
70        $app = \Slim\Slim::getInstance();
71        $response = [];
72        $id = [];
73        $stat = [];
74        $ip = "";
75        $urls = [];
76        // Status mapping.
77        $status = ['OFF'=>"off",
78                   'INI'=>"initializing",
79                   'OPG'=>"oglive",
80                   'BSY'=>"busy",
81                   'LNX'=>"linux",
82                   'OSX'=>"macos",
83                   'WIN'=>"windows",
84                   'UNK'=>"unknown"];
85        // Parameters.
86        $ouid = htmlspecialchars($ouid);
87        $labid = htmlspecialchars($labid);
88        $single = is_numeric(explode("/", $app->request->getResourceUri())[6]);
89
90        // Database query.
91        $cmd->texto = <<<EOD
92SELECT adm.idusuario, aulas.idaula, ordenadores.idordenador, ordenadores.ip
93  FROM ordenadores
94  JOIN aulas USING(idaula)
95 RIGHT JOIN administradores_centros AS adm USING(idcentro)
96 WHERE adm.idusuario = '$userid'
97   AND adm.idcentro='$ouid'
98   AND aulas.idaula='$labid'
99EOD;
100        // Request for a single client.
101        if ($single) {
102                $clntid = htmlspecialchars($clntid);
103                $cmd->texto .= <<<EOD
104   AND ordenadores.idordenador='$clntid';
105EOD;
106        }
107        $rs=new Recordset;
108        $rs->Comando=&$cmd;
109        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
110        $rs->Primero();
111        // Check if user is an UO admin and asset exists.
112        if (checkAdmin($rs->campos["idusuario"]) and (($single and checkParameter($rs->campos["idordenador"])) or (! $single and checkParameter($rs->campos["idaula"])))) {
113                while (!$rs->EOF) {
114                        $id[$rs->campos["ip"]] = $rs->campos["idordenador"];
115                        $stat[$rs->campos["ip"]] = $status['OFF'];
116                        $rs->Siguiente();
117                }
118                // Get client status.
119                $clientid = implode(",", $id);
120                $clientip = implode(";", array_keys($id));
121                $result = clients(2, $clientip);
122                // Check status type.
123                if (checkParameter($result)) {
124                        foreach (explode(";", $result) as $data) {
125                                if (!empty($data)) {
126                                        list($clip, $clst) = explode("/", $data);
127                                        if ($clst != "OFF") {
128                                                // Update current status.
129                                                $stat[$clip] = $status[$clst];
130                                        }
131                                }
132                        }
133                }
134                // Prepare request to new OGAgent for OSes.
135                foreach ($stat as $ip => $st) {
136                        if ($st == "off") {
137                                $urls[$ip] = "https://$ip:8000/opengnsys/status";
138                        }
139                }
140                // Send request to OGAgents.
141                if (isset($urls)) {
142                        $result = multiRequest($urls);
143                }
144                // Parse responses.
145                reset($urls);
146                foreach ($result as $res) {
147                        if (!empty($res['data'])) {
148                                // Get status and session data.
149                                $ip = key($urls);
150                                $data = json_decode($res['data']);
151                                if (@isset($status[$data->status])) {
152                                        $stat[$ip] = $status[$data->status];
153                                        $logged[$ip] = $data->loggedin;
154                                } else {
155                                        $stat[$ip] = $status['UNK'];
156                                }
157                        }
158                        unset($urls[$ip]);
159                }
160                // Compose JSON response.
161                if ($single) {
162                        // Single response.
163                        $response['id'] = (int)reset($id);
164                        $response['ip'] = key($id);
165                        $response['status'] = $stat[key($id)];
166                        empty($logged[$ip]) || $response['loggedin'] = $logged[$ip];
167                } else {
168                        // Multiple responses.
169                        foreach ($stat as $ip => $st) {
170                                if (isset($id[$ip])) {
171                                        $tmp = ['id' => (int)$id[$ip],
172                                                'ip' => $ip,
173                                                'status' => $stat[$ip]];
174                                        empty($logged[$ip]) || $tmp['loggedin'] = $logged[$ip];
175                                        array_push($response, $tmp);
176                                }
177                        }
178                }
179                jsonResponse(200, $response);
180        }
181        $rs->Cerrar();
182}
183
184
185// REST routes.
186
187/**
188 * @brief    user login.
189 * @note     Route: /login, Method: POST
190 * @param    string username   User name.
191 * @param    string password   User password.
192 * @return   string            JSON response with user id. and API key.
193 * @note     User's API key is stored in a new field of "usuarios" table.
194 */
195$app->post('/login',
196    function() use ($app) {
197        global $cmd;
198        global $userid;
199
200        $response = Array();
201        // Reading JSON parameters.
202        try {
203                $input = json_decode($app->request()->getBody());
204                $user = htmlspecialchars($input->username);
205                $pass = htmlspecialchars($input->password);
206        } catch (Exception $e) {
207                // Error message.
208                $response["message"] = $e->getMessage();
209                jsonResponse(400, $response);
210                $app->stop();
211        }
212
213        // Checking parameters.
214        if (! empty($user) and ! empty($pass)) {
215                // Database query.
216                $cmd->texto = "SELECT idusuario, apikey
217                                 FROM usuarios
218                                WHERE usuario='$user' AND pasguor=SHA2('$pass',224)";
219                $rs=new Recordset;
220                $rs->Comando=&$cmd;
221                if ($rs->Abrir()) {
222                        $rs->Primero();
223                        if (!$rs->EOF){
224                                // JSON response.
225                                $userid=$rs->campos["idusuario"];
226                                $apikey=$rs->campos["apikey"];
227                                $response['userid'] = $userid;
228                                $response['apikey'] = $apikey;
229                                jsonResponse(200, $response);
230                        } else {
231                                // Credentials error.
232                                $response['message'] = 'Login failed. Incorrect credentials';
233                                jsonResponse(401, $response);
234                                $app->stop();
235                        }
236                        $rs->Cerrar();
237                } else {
238                        // Access error.
239                        $response['message'] = "An error occurred. Please try again";
240                        jsonResponse(500, $response);
241                        $app->stop();
242                }
243        } else {
244                # Error: missing some input parameter.
245                $response['message'] = 'Missing username or password';
246                jsonResponse(400, $response);
247                $app->stop();
248        }
249    }
250);
251
252/**
253 * @brief    List all defined Organizational Units
254 * @note     Route: /ous, Method: GET
255 * @return   string  JSON array with id. and name for every defined OU
256 */
257$app->get('/ous(/)', function() {
258        global $cmd;
259
260        $cmd->texto = "SELECT * FROM centros";
261        $rs=new Recordset;
262        $rs->Comando=&$cmd;
263        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
264        $response = Array();
265        $rs->Primero();
266        while (!$rs->EOF) {
267                $tmp = Array();
268                $tmp['id'] = (int)$rs->campos["idcentro"];
269                $tmp['name'] = $rs->campos["nombrecentro"];
270                array_push($response, $tmp);
271                $rs->Siguiente();
272        }
273        $rs->Cerrar();
274        jsonResponse(200, $response);
275   }
276);
277
278/**
279 * @brief    Get Organizational Unit data
280 * @note     Route: /ous/:ouid, Method: GET
281 * @param    int ouid  OU id.
282 * @return   string    JSON string with OU's parameters
283 */
284$app->get('/ous/:ouid(/)', 'validateApiKey',
285    function($ouid) {
286        global $cmd;
287        global $userid;
288
289        $ouid = htmlspecialchars($ouid);
290        // Show OU information if user is OU's admin.
291        $cmd->texto = <<<EOD
292SELECT *
293  FROM centros
294 RIGHT JOIN administradores_centros USING(idcentro)
295 WHERE administradores_centros.idusuario = '$userid'
296   AND centros.idcentro = '$ouid'
297 LIMIT 1;
298EOD;
299        $rs=new Recordset;
300        $rs->Comando=&$cmd;
301        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
302        $rs->Primero();
303        if (checkAdmin($rs->campos["idusuario"]) and
304            checkParameter($rs->campos["idcentro"])) {
305                $response['id'] = (int)$ouid;
306                $response['name'] = $rs->campos["nombrecentro"];
307                $response['description'] = $rs->campos["comentarios"];
308                jsonResponse(200, $response);
309        }
310        $rs->Cerrar();
311    }
312);
313
314/**
315 * @brief    List group of labs in an Organizational Unit
316 * @note     Route: /ous/:ouid/groups, Method: GET
317 * @param    int ouid   OU id.
318 * @return   string      JSON array of OU groups
319 */
320$app->get('/ous/:ouid/groups(/)', 'validateApiKey', function($ouid) {
321        global $cmd;
322        global $userid;
323
324        $ouid = htmlspecialchars($ouid);
325        // List group of labs if user is OU's admin.
326        $cmd->texto = <<<EOD
327SELECT adm.idusuario, grupos.*
328  FROM grupos
329 RIGHT JOIN administradores_centros AS adm USING(idcentro)
330 WHERE adm.idusuario = '$userid'
331   AND idcentro='$ouid';
332EOD;
333        $rs=new Recordset;
334        $rs->Comando=&$cmd;
335        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
336        $rs->Primero();
337        // Check if user is an UO admin.
338        if (checkAdmin($rs->campos["idusuario"])) {
339                $response = Array();
340                // Read data.
341                if (! is_null($rs->campos["idcentro"])) {
342                        while (!$rs->EOF) {
343                                $tmp = Array();
344                                $tmp['id'] = (int)$rs->campos["idgrupo"];
345                                $tmp['name'] = $rs->campos["nombregrupo"];
346                                $tmp['type'] = $rs->campos["tipo"];
347                                $tmp['comments'] = $rs->campos["comentarios"];
348                                if($rs->campos["grupoid"] != 0){
349                                        $tmp['parent']['id'] = (int)$rs->campos["grupoid"];
350                                }
351                                array_push($response, $tmp);
352                                $rs->Siguiente();
353                        }
354                }
355                jsonResponse(200, $response);
356        }
357        $rs->Cerrar();
358    }
359);
360
361/**
362 * @brief    List all labs defined in an OU
363 * @note     Route: /ous/:ouid/labs, Method: GET
364 * @param    int ouid  OU id.
365 * @return   string    JSON array of all UO's labs data
366 */
367$app->get('/ous/:ouid/labs(/)', 'validateApiKey',
368    function($ouid) {
369        global $userid;
370        global $cmd;
371
372        $ouid = htmlspecialchars($ouid);
373        // Database query.
374        $cmd->texto = <<<EOD
375SELECT adm.idusuario, aulas.*, grp.idgrupo AS group_id,
376       grp.nombregrupoordenador, grp.grupoid AS group_group_id, grp.comentarios
377  FROM aulas
378 RIGHT JOIN administradores_centros AS adm USING(idcentro)
379  LEFT JOIN gruposordenadores AS grp USING(idaula)
380 WHERE adm.idusuario = '$userid'
381   AND adm.idcentro='$ouid'
382 ORDER BY aulas.idaula, grp.idgrupo
383EOD;
384        $rs=new Recordset;
385        $rs->Comando=&$cmd;
386        if (!$rs->Abrir()) return(false);       // Error opening recordset.
387        // Check if user is an UO admin.
388        $rs->Primero();
389        if (checkAdmin($rs->campos["idusuario"])) {
390                $response = Array();
391                if (! is_null($rs->campos["idcentro"])) {
392                        while (!$rs->EOF) {
393                                // En los resultados las aulas vienen repetidas tantas veces como grupos tengan, solo dejamos uno
394                                $classroomIndex = -1;
395                                $found=false;
396                                $index = 0;
397                                while(!$found && $index < count($response)){
398                                        if(isset($response[$index]["id"]) && $response[$index]["id"] == $rs->campos["idaula"]){
399                                                $classroomIndex = $index;
400                                                $found = true;
401                                        }
402                                        $index++;
403                                }
404                                if(!$found){
405                                        $tmp = Array();
406                                        $tmp['id'] = (int)$rs->campos["idaula"];
407                                        $tmp['name'] = $rs->campos["nombreaula"];
408                                        $tmp['inremotepc'] = ($rs->campos["inremotepc"] == 1);
409                                        $tmp['group']['id'] = (int)$rs->campos["grupoid"];
410                                        $tmp['ou']['id'] = (int)$ouid;
411                                        array_push($response, $tmp);
412                                }
413                                else{
414                                        // Le añadimos el grupo en cuestion siempre que no sea un subgrupo
415                                        if($rs->campos["group_group_id"] == 0){
416                                                array_push($response[$classroomIndex]['classroomGroups'],
417                                                        array("id" => (int)$rs->campos["group_id"],
418                                                        "name" => $rs->campos["nombregrupoordenador"],
419                                                        "comments" => $rs->campos["comentarios"],
420                                                        "classroomGroups" => array()));
421                                        }
422                                        else {
423                                                // Buscamos el grupo donde añadir el grupo
424                                                addClassroomGroup($response[$classroomIndex]['classroomGroups'], $rs);
425                                        }
426                                }
427                                $rs->Siguiente();
428                        }
429                }
430                jsonResponse(200, $response);
431        }
432        $rs->Cerrar();
433    }
434);
435
436/**
437 * @brief    Get lab data
438 * @note     Route: /ous/:ouid/labs/:labid, Method: GET
439 * @param    int ouid   OU id.
440 * @param    int labid  lab id.
441 * @return   string     JSON string with lab parameters
442 */
443$app->get('/ous/:ouid/labs/:labid(/)', 'validateApiKey',
444    function($ouid, $labid) {
445        global $userid;
446        global $cmd;
447
448        $ouid = htmlspecialchars($ouid);
449        $labid = htmlspecialchars($labid);
450        // Database query.
451        $cmd->texto = <<<EOD
452SELECT adm.idusuario, COUNT(idordenador) AS defclients, aulas.*
453  FROM aulas
454 RIGHT JOIN administradores_centros AS adm USING(idcentro)
455  LEFT JOIN ordenadores USING(idaula)
456 WHERE adm.idusuario = '$userid'
457   AND idcentro='$ouid'
458   AND idaula='$labid';
459EOD;
460        $rs=new Recordset;
461        $rs->Comando=&$cmd;
462        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
463        $rs->Primero();
464        // Check if user is an UO admin and lab exists.
465        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idaula"])) {
466                $response['id'] = (int)$rs->campos["idaula"];
467                $response['name'] = $rs->campos["nombreaula"];
468                $response['location'] = $rs->campos["ubicacion"];
469                $response['description'] = $rs->campos["comentarios"];
470                $response['inremotepc'] = ($rs->campos["inremotepc"] == 1);
471                $response['capacity'] = (int)$rs->campos["puestos"];
472                if ($rs->campos["idordprofesor"]) {
473                        $response['profclient']['id'] = (int)$rs->campos["idordprofesor"];
474                }
475                $response['defclients'] = (int)$rs->campos["defclients"];
476                $response['projector'] = ($rs->campos["cagnon"] == 1);
477                $response['board'] = ($rs->campos["pizarra"] == 1);
478                $response['routerip'] = $rs->campos["router"];
479                $response['netmask'] = $rs->campos["netmask"];
480                $response['ntp'] = $rs->campos["ntp"];
481                $response['dns'] = $rs->campos["dns"];
482                $response['proxyurl'] = $rs->campos["proxy"];
483                switch ($rs->campos["modomul"]) {
484                        case 1:  $response['mcastmode'] = "half-duplex"; break;
485                        case 2:  $response['mcastmode'] = "full-duplex"; break;
486                        default: $response['mcastmode'] = $rs->campos["modomul"];
487                }
488                $response['mcastip'] = $rs->campos["ipmul"];
489                $response['mcastport'] = $rs->campos["pormul"];
490                $response['mcastspeed'] = $rs->campos["velmul"];
491                $response['p2pmode'] = $rs->campos["modp2p"];
492                $response['p2ptime'] = $rs->campos["timep2p"];
493                $response['picture'] = $rs->campos["urlfoto"];
494                jsonResponse(200, $response);
495        }
496        $rs->Cerrar();
497    }
498);
499
500
501/**
502 * @brief    List all clients defined in a lab
503 * @note     Route: /ous/:ouid/labs/:labid/clients, Method: GET
504 * @param    int ouid   OU id.
505 * @param    int labid  lab id.
506 * @return   string     JSON data with lab id. and array of lab parameters
507 */
508$app->get('/ous/:ouid/labs/:labid/clients(/)', 'validateApiKey',
509    function($ouid, $labid) {
510        global $userid;
511        global $cmd;
512
513        $ouid = htmlspecialchars($ouid);
514        $labid = htmlspecialchars($labid);
515        // Database query.
516        $cmd->texto = <<<EOD
517SELECT adm.idusuario, ordenadores.*, aulas.idaula AS labid
518  FROM ordenadores
519 RIGHT JOIN aulas USING(idaula)
520 RIGHT JOIN administradores_centros AS adm USING(idcentro)
521 WHERE adm.idusuario = '$userid'
522   AND adm.idcentro='$ouid'
523   AND aulas.idaula='$labid';
524EOD;
525        $rs=new Recordset;
526        $rs->Comando=&$cmd;
527        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
528        $rs->Primero();
529        // Check if user is an UO admin and lab exists.
530        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["labid"])) {
531                $response = Array();
532                while (!$rs->EOF) {
533                        if (!is_null($rs->campos["idordenador"])) {
534                                $tmp = Array();
535                                $tmp['id'] = (int)$rs->campos["idordenador"];
536                                $tmp['name'] = $rs->campos["nombreordenador"];
537                                $tmp['ip'] = $rs->campos["ip"];
538                                $tmp['mac'] = $rs->campos["mac"];
539                                $tmp['ou']['id'] = (int)$ouid;
540                                $tmp['lab']['id'] = (int)$labid;
541                                array_push($response, $tmp);
542                        }
543                        $rs->Siguiente();
544                }
545                jsonResponse(200, $response);
546        }
547        $rs->Cerrar();
548    }
549);
550
551/**
552 * @brief    Get execution status of all clients defined in a lab
553 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/status, Method: GET
554 * @param    int ouid   OU id.
555 * @param    int labid  lab id.
556 * @return   string     JSON string with array of all client status defined in a lab
557 */
558$app->get('/ous/:ouid/labs/:labid/clients/status(/)', 'validateApiKey', 'getStatus');
559
560/**
561 * @brief    Get client data
562 * @note     Route: /ous/id1/labs/id2clients/id3, Method: GET
563 * @param    int ouid    OU id.
564 * @param    int labid   lab id.
565 * @param    int clntid  client id.
566 * @return   string      JSON string with hardware parameters
567 */
568$app->get('/ous/:ouid/labs/:labid/clients/:clntid(/)', 'validateApiKey',
569    function($ouid, $labid, $clntid) {
570        global $userid;
571        global $cmd;
572
573        $ouid = htmlspecialchars($ouid);
574        $labid = htmlspecialchars($labid);
575        $clntid = htmlspecialchars($clntid);
576        // Database query.
577        $cmd->texto = <<<EOD
578SELECT adm.idusuario, ordenadores.*,
579       IF(ordenadores.idordenador=aulas.idordprofesor, 1, 0) AS profclient
580  FROM ordenadores
581  JOIN aulas USING(idaula)
582 RIGHT JOIN administradores_centros AS adm USING(idcentro)
583 WHERE adm.idusuario = '$userid'
584   AND idcentro='$ouid'
585   AND idaula='$labid'
586   AND idordenador='$clntid';
587EOD;
588        $rs=new Recordset;
589        $rs->Comando=&$cmd;
590        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
591        $rs->Primero();
592        // Check if user is an UO admin, lab exists and client exists.
593        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idaula"]) and checkParameter($rs->campos["idordenador"])) {
594                // Read data.
595                $response['id'] = (int)$rs->campos["idordenador"];
596                $response['name'] = $rs->campos["nombreordenador"];
597                $response['serialno'] = $rs->campos["numserie"];
598                $response['netiface'] = $rs->campos["netiface"];
599                $response['netdriver'] = $rs->campos["netdriver"];
600                $response['mac'] = $rs->campos["mac"];
601                $response['ip'] = $rs->campos["ip"];
602                $response['netmask'] = $rs->campos["mascara"];
603                $response['routerip'] = $rs->campos["router"];
604                $response['repo']['id'] = (int)$rs->campos["idrepositorio"];
605                $response['profclient'] = ($rs->campos["profclient"] == 1);
606                //$response['hardprofile']['id'] = $rs->campos["idperfilhard"];
607                //$response['menu']['id'] = $rs->campos["idmenu"];
608                $response['validation'] = ($rs->campos["validacion"] == 1);
609                $response['boottype'] = $rs->campos["arranque"];
610                $response['picture'] = $rs->campos["fotoord"];
611                jsonResponse(200, $response);
612        }
613        $rs->Cerrar();
614    }
615);
616
617/**
618 * @brief    Get client's harware configuration data
619 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/hardware, Method: GET
620 * @param    int ouid    OU id.
621 * @param    int labid   lab id.
622 * @param    int clntid  client id.
623 * @return   string      JSON string with cleint parameters
624 */
625$app->get('/ous/:ouid/labs/:labid/clients/:clntid/hardware(/)', 'validateApiKey',
626    function($ouid, $labid, $clntid) {
627        global $userid;
628        global $cmd;
629
630        $ouid = htmlspecialchars($ouid);
631        $labid = htmlspecialchars($labid);
632        $clntid = htmlspecialchars($clntid);
633        // Database query.
634        $cmd->texto = <<<EOD
635SELECT adm.idusuario, ordenadores.idordenador, ordenadores.nombreordenador,
636       tipohardwares.nemonico, hardwares.descripcion
637  FROM ordenadores
638  JOIN aulas USING(idaula)
639 RIGHT JOIN administradores_centros AS adm USING(idcentro)
640  LEFT JOIN perfileshard_hardwares USING(idperfilhard)
641  LEFT JOIN hardwares ON perfileshard_hardwares.idhardware=hardwares.idhardware
642  LEFT JOIN tipohardwares ON tipohardwares.idtipohardware=hardwares.idtipohardware
643 WHERE adm.idusuario = '$userid'
644   AND adm.idcentro='$ouid'
645   AND aulas.idaula='$labid'
646   AND ordenadores.idordenador='$clntid';
647EOD;
648        $rs=new Recordset;
649        $rs->Comando=&$cmd;
650        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
651        $rs->Primero();
652        // Check if user is an UO admin and client exists.
653        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
654                // Read data.
655                $response['id'] = (int)$rs->campos["idordenador"];
656                $response['name'] = $rs->campos["nombreordenador"];
657                $response['hardware'] = Array();
658                while (!$rs->EOF) {
659                        if (!is_null($rs->campos["nemonico"])) {
660                                $tmp = Array();
661                                $tmp['type'] = $rs->campos["nemonico"];
662                                $tmp['description'] = $rs->campos["descripcion"];
663                                array_push($response['hardware'], $tmp);
664                        }
665                        $rs->Siguiente();
666                }
667                jsonResponse(200, $response);
668        }
669        $rs->Cerrar();
670    }
671);
672
673/**
674 * @brief    Get client's disk configuration data
675 * @note     Route: /ous/:ouid1/labs/:labid/clients/:clntid/diskcfg, Method: GET
676 * @param    int ouid    OU id.
677 * @param    int labid   lab id.
678 * @param    int clntid  client id.
679 * @return   string      JSON string with disk parameters
680 */
681$app->get('/ous/:ouid/labs/:labid/clients/:clntid/diskcfg(/)', 'validateApiKey',
682    function($ouid, $labid, $clntid) {
683        global $userid;
684        global $cmd;
685
686        $ouid = htmlspecialchars($ouid);
687        $labid = htmlspecialchars($labid);
688        $clntid = htmlspecialchars($clntid);
689        // Database query.
690        $cmd->texto = <<<EOD
691SELECT adm.idusuario, ordenadores.idordenador AS clientid,
692       ordenadores.nombreordenador, ordenadores_particiones.*, tipospar.tipopar,
693       sistemasficheros.nemonico, nombresos.nombreso, imagenes.nombreca,
694       (imagenes.revision - ordenadores_particiones.revision) AS difimagen
695  FROM ordenadores_particiones
696 RIGHT JOIN ordenadores USING(idordenador)
697  JOIN aulas USING(idaula)
698 RIGHT JOIN administradores_centros AS adm USING(idcentro)
699  LEFT JOIN tipospar USING(codpar)
700  LEFT JOIN sistemasficheros USING(idsistemafichero)
701  LEFT JOIN nombresos USING(idnombreso)
702  LEFT JOIN imagenes USING(idimagen)
703 WHERE adm.idusuario = '$userid'
704   AND adm.idcentro='$ouid'
705   AND aulas.idaula='$labid'
706   AND ordenadores.idordenador='$clntid'
707 ORDER BY numdisk ASC, numpar ASC;
708EOD;
709        $rs=new Recordset;
710        $rs->Comando=&$cmd;
711        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
712        $rs->Primero();
713        // Check if user is an UO admin and client exists.
714        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["clientid"])) {
715                // Read data.
716                $response['id'] = (int)$rs->campos["clientid"];
717                $response['name'] = $rs->campos["nombreordenador"];
718                $response['diskcfg'] = Array();
719                while (!$rs->EOF) {
720                        // Skip header.
721                        if ($rs->campos["numdisk"] == 0) {
722                                $rs->Siguiente();
723                                continue;
724                        }
725                        $tmp = Array();
726                        // Common data.
727                        $tmp['disk'] = (int)$rs->campos["numdisk"];
728                        $tmp['size'] = (int)$rs->campos["tamano"];
729                        if ($rs->campos["numpar"] == 0) {
730                                // Disk data.
731                                switch ($rs->campos["codpar"]) {
732                                        case 1:  $tmp['parttable'] = "MSDOS"; break;
733                                        case 2:  $tmp['parttable'] = "GPT"; break;
734                                        case 3:  $tmp['parttable'] = "LVM"; break;
735                                        case 4:  $tmp['parttable'] = "ZPOOL"; break;
736                                        default: $tmp['parttable'] = $rs->campos["codpar"];
737                                }
738                        } else {
739                                // Partition data.
740                                $tmp['partition'] = (int)$rs->campos["numpar"];
741                                $tmp['parttype'] = $rs->campos["tipopar"];
742                                $tmp['filesystem'] = $rs->campos["nemonico"];
743                                $tmp['usage'] = (int)$rs->campos["uso"];
744                                if ($rs->campos["nombreso"] != null) {
745                                        $tmp['os'] = $rs->campos["nombreso"];
746                                        if ($rs->campos["idimagen"] > 0) {
747                                                // Restored image data.
748                                                $tmp['image']['id'] = (int)$rs->campos["idimagen"];
749                                                $tmp['image']['deploydate'] = $rs->campos["fechadespliegue"];
750                                                // Check if image is updated.
751                                                $tmp['image']['updated'] = ($rs->campos["difimagen"] == 0);
752                                        }
753                                }
754                                //$tmp['cachedata'] = $rs->campos["cache"];
755                        }
756                        array_push($response['diskcfg'], $tmp);
757                        $rs->Siguiente();
758                }
759                jsonResponse(200, $response);
760        }
761        $rs->Cerrar();
762    }
763);
764
765/**
766 * @brief    Get client's execution status
767 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/status, Method: GET
768 * @param    int ouid    OU id.
769 * @param    int labid   lab id.
770 * @param    int clntid  client id.
771 * @return   string      JSON string with client status
772 */
773$app->get('/ous/:ouid/labs/:labid/clients/:clntid/status(/)', 'validateApiKey', 'getStatus');
774
775/**
776 * @brief    List all image repositories defined in an OU
777 * @note     Route: /ous/id/repos, Method: GET
778 * @param    int ouid  OU id.
779 * @return   string    JSON array of all UO's repo data
780 */
781$app->get('/ous/:ouid/repos(/)', 'validateApiKey',
782    function($ouid) {
783        global $userid;
784        global $cmd;
785
786        $ouid = htmlspecialchars($ouid);
787        // Database query.
788        $cmd->texto = <<<EOD
789SELECT adm.idusuario, adm.idcentro AS ouid, repositorios.*
790  FROM repositorios
791 RIGHT JOIN administradores_centros AS adm USING(idcentro)
792 WHERE adm.idusuario = '$userid'
793   AND adm.idcentro='$ouid';
794EOD;
795        $rs=new Recordset;
796        $rs->Comando=&$cmd;
797        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
798        $rs->Primero();
799        // Check if user is an UO admin.
800        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["ouid"])) {
801                $response = Array();
802                while (!$rs->EOF) {
803                        if (! is_null($rs->campos["idcentro"])) {
804                                $tmp = Array();
805                                $tmp['id'] = (int)$rs->campos["idrepositorio"];
806                                $tmp['name'] = $rs->campos["nombrerepositorio"];
807                                $tmp['ou']['id'] = (int)$ouid;
808                                array_push($response, $tmp);
809                        }
810                        $rs->Siguiente();
811                }
812                jsonResponse(200, $response);
813        }
814        $rs->Cerrar();
815    }
816);
817
818/**
819 * @brief    Get image repository data
820 * @note     Route: /ous/:ouid/repos/:repoid, Method: GET
821 * @param    int ouid    OU id.
822 * @param    int repoid  repository id.
823 * @return   string      JSON string with repo parameters
824 */
825$app->get('/ous/:ouid/repos/:repoid(/)', 'validateApiKey',
826    function($ouid, $repoid) {
827        global $userid;
828        global $cmd;
829
830        $ouid = htmlspecialchars($ouid);
831        $repoid = htmlspecialchars($repoid);
832        // Database query.
833        $cmd->texto = <<<EOD
834SELECT adm.idusuario, repositorios.*
835  FROM repositorios
836 RIGHT JOIN administradores_centros AS adm USING(idcentro)
837 WHERE adm.idusuario = '$userid'
838   AND adm.idcentro='$ouid'
839   AND idrepositorio='$repoid';
840EOD;
841        $rs=new Recordset;
842        $rs->Comando=&$cmd;
843        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
844        $rs->Primero();
845        // Check if user is an UO admin and repo exists.
846        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idrepositorio"])) {
847                // Read data.
848                $response['id'] = (int)$rs->campos["idrepositorio"];
849                $response['name'] = $rs->campos["nombrerepositorio"];
850                $response['description'] = $rs->campos["comentarios"];
851                $response['ip'] = $rs->campos["ip"];
852                jsonResponse(200, $response);
853        }
854        $rs->Cerrar();
855    }
856);
857
858/**
859 * @brief    List all images defined in an OU
860 * @note     Route: /ous/:ouid/images, Method: GET
861 * @param    int ouid  OU id.
862 * @return   string    JSON array of all UO's image data
863 */
864$app->get('/ous/:ouid/images(/)', 'validateApiKey',
865    function($ouid) {
866        global $userid;
867        global $cmd;
868
869        $ouid = htmlspecialchars($ouid);
870        // Database query.
871        $cmd->texto = <<<EOD
872SELECT adm.idusuario, adm.idcentro AS ouid, imagenes.*
873  FROM imagenes
874 RIGHT JOIN administradores_centros AS adm USING(idcentro)
875 WHERE adm.idusuario = '$userid'
876   AND adm.idcentro='$ouid';
877EOD;
878        $rs=new Recordset;
879        $rs->Comando=&$cmd;
880        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
881        $rs->Primero();
882        // Check if user is an UO admin.
883        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["ouid"])) {
884                $response = Array();
885                while (!$rs->EOF) {
886                        if (! is_null($rs->campos["idcentro"])) {
887                                $tmp = Array();
888                                $tmp['id'] = (int)$rs->campos["idimagen"];
889                                $tmp['name'] = $rs->campos["nombreca"];
890                                $tmp['inremotepc'] = ($rs->campos["inremotepc"] == 1);
891                                $tmp['ou']['id'] = (int)$ouid;
892                                array_push($response, $tmp);
893                        }
894                        $rs->Siguiente();
895                }
896                jsonResponse(200, $response);
897        }
898    }
899);
900
901/**
902 * @brief    Get image data
903 * @note     Route: /ous/:ouid/images/:imgid, Method: GET
904 * @param    int ouid   OU id.
905 * @param    int imgid  image id.
906 * @return   string     JSON string with image parameters
907 */
908$app->get('/ous/:ouid/images/:imgid(/)', 'validateApiKey',
909    function($ouid, $imgid) {
910        global $userid;
911        global $cmd;
912
913        $ouid = htmlspecialchars($ouid);
914        $imgid = htmlspecialchars($imgid);
915        // Database query.
916        $cmd->texto = <<<EOD
917SELECT adm.idusuario, imagenes.*, nombreso AS os
918  FROM imagenes
919 RIGHT JOIN administradores_centros AS adm USING(idcentro)
920  LEFT JOIN perfilessoft USING(idperfilsoft)
921  LEFT JOIN nombresos USING(idnombreso)
922 WHERE adm.idusuario = '$userid'
923   AND adm.idcentro='$ouid'
924   AND idimagen='$imgid';
925EOD;
926        $rs=new Recordset;
927        $rs->Comando=&$cmd;
928        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
929        $rs->Primero();
930        // Check if user is an UO admin and repo exists.
931        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idimagen"])) {
932                // Read data.
933                $response['id'] = (int)$rs->campos["idimagen"];
934                $response['name'] = $rs->campos["nombreca"];
935                $response['description'] = $rs->campos["descripcion"];
936                $response['comments'] = $rs->campos["comentarios"];
937                $response['inremotepc'] = ($rs->campos["inremotepc"] == 1);
938                $response['repo']['id'] = (int)$rs->campos["idrepositorio"];
939                switch ($rs->campos["tipo"]) {
940                        // Image type.
941                        case 1:  $response['type'] = "monolithic"; break;
942                        case 2:  $response['type'] = "base"; break;
943                        case 3:  $response['type'] = "incremental";
944                                 $response['baseimg'] = $rs->campos["imagenid"];
945                                 $response['path'] = $rs->campos["ruta"];
946                                 break;
947                        default: $response['type'] = $rs->campos["tipo"];
948                }
949                if ($rs->campos["idordenador"] != 0) {
950                        // Source client data.
951                        $response['client']['id'] = (int)$rs->campos["idordenador"];
952                        $response['client']['disk'] = (int)$rs->campos["numdisk"];
953                        $response['client']['partition'] = (int)$rs->campos["numpar"];
954                        $response['creationdate'] = $rs->campos["fechacreacion"];
955                        $response['release'] = (int)$rs->campos["revision"];
956                        $response['os'] = $rs->campos["os"];
957                }
958                jsonResponse(200, $response);
959        }
960        $rs->Cerrar();
961    }
962);
963
964// Lista de softeare instalado en una imagen.
965/**
966 * @brief    List software installed in an image
967 * @note     Route: /ous/:ouid/images/:imgid/software, Method: GET
968 * @param    int ouid   OU id.
969 * @param    int imgid  image id.
970 * @return   string     JSON array with installed software
971 */$app->get('/ous/:ouid/images/:imgid/software(/)', 'validateApiKey',
972    function($ouid, $imgid) {
973        global $userid;
974        global $cmd;
975
976        $ouid = htmlspecialchars($ouid);
977        $imgid = htmlspecialchars($imgid);
978        // Database query.
979        $cmd->texto = <<<EOD
980SELECT adm.idusuario, imagenes.idimagen, imagenes.nombreca,
981       nombresos.nombreso, softwares.descripcion
982  FROM imagenes
983 RIGHT JOIN administradores_centros AS adm USING(idcentro)
984  LEFT JOIN perfilessoft USING(idperfilsoft)
985  LEFT JOIN nombresos USING(idnombreso)
986  LEFT JOIN perfilessoft_softwares USING(idperfilsoft)
987  LEFT JOIN softwares USING(idsoftware)
988 WHERE adm.idusuario = '$userid'
989   AND adm.idcentro='$ouid'
990   AND imagenes.idimagen='$imgid'
991 ORDER BY softwares.descripcion ASC;
992EOD;
993        $rs=new Recordset;
994        $rs->Comando=&$cmd;
995        if (!$rs->Abrir()) return(false);       // Error oppening recordset.
996        $rs->Primero();
997        // Check if user is an UO admin and repo exists.
998        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idimagen"])) {
999                $response['id'] = (int)$rs->campos["idimagen"];
1000                $response['name'] = $rs->campos["nombreca"];
1001                if (is_null($rs->campos["nombreso"])) {
1002                        // Null object.
1003                        $response['software'] = Array();
1004                        jsonResponse(200, $response, JSON_FORCE_OBJECT);
1005                } else {
1006                        // Read data.
1007                        $response['software']['os'] = $rs->campos["nombreso"];
1008                        //$response['software']['type'] = ...;  // OS type
1009                        $response['software']['applications'] = Array();
1010                        while (!$rs->EOF) {
1011                                // Ignoring empty fields.
1012                                if (!is_null($rs->campos["descripcion"])) {
1013                                        array_push($response['software']['applications'], $rs->campos["descripcion"]);
1014                                }
1015                                $rs->Siguiente();
1016                        }
1017                        jsonResponse(200, $response);
1018                }
1019        }
1020        $rs->Cerrar();
1021    }
1022);
1023
Note: See TracBrowser for help on using the repository browser.