source: admin/WebConsole/rest/common.php @ be87371

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since be87371 was 4705afe, checked in by ramon <ramongomez@…>, 7 years ago

#708: Tiempo de sesión ilimitado si parámetro deadLine es 0 en ruta REST ous/:ouid/labs/:labid/clients/:clntid/session.

git-svn-id: https://opengnsys.es/svn/branches/version1.1@5496 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 8.8 KB
RevLine 
[3551804]1<?php
2/**
3 * @file    index.php
[1ab1b31d]4 * @brief   OpenGnsys REST API: common functions and routes
[3551804]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-11-17
11 */
12
13
[13dc959]14// Common constants.
15define('REST_LOGFILE', '/opt/opengnsys/log/rest.log');
16
17
[1ab1b31d]18// Common functions.
19
[3551804]20/**
[13dc959]21 * @brief   Function to write a line into log file.
22 * @param   string message  Message to log.
23 * warning  Line format: "Date: ClientIP: UserId: Status: Method Route: Message"
24 */
25function writeRestLog($message = "") {
26        global $userid;
27        if (is_writable(REST_LOGFILE)) {
28                $app = \Slim\Slim::getInstance();
29                file_put_contents(REST_LOGFILE, date(DATE_ISO8601) .": " .
30                                                $_SERVER['REMOTE_ADDR'] . ": " .
31                                                (isset($userid) ? $userid : "-") . ": " .
32                                                $app->response->getStatus() . ": " .
33                                                $app->request->getMethod() . " " .
34                                                $app->request->getPathInfo() . ": $message\n",
35                                FILE_APPEND);
36        }
37}
38
39/**
[3551804]40 * @brief   Compose JSON response.
41 * @param   int status      Status code for HTTP response.
42 * @param   array response  Response data.
[5ff84a5]43 * @param   int opts        Options to encode JSON data.
[3551804]44 * @return  string          JSON response.
[1ab1b31d]45 */
[5ff84a5]46function jsonResponse($status, $response, $opts=0) {
[d8b6c70]47        $app = \Slim\Slim::getInstance();
48        // HTTP status code.
49        $app->status($status);
50        // Content-type HTTP header.
51        $app->contentType('application/json; charset=utf-8');
52        // JSON response.
53        echo json_encode($response, $opts);
[3551804]54}
55
[1ab1b31d]56/**
[8ba8712]57 * @brief   Print immediately JSON response to continue processing.
58 * @param   int status      Status code for HTTP response.
59 * @param   array response  Response data.
60 * @param   int opts        Options to encode JSON data.
61 * @return  string          JSON response.
62 */
63function jsonResponseNow($status, $response, $opts=0) {
64        // Flush buffer.
65        ob_end_clean();
66        ob_end_flush();
67        header("Connection: close");
68        // Compose headers and content.
69        http_response_code((int)$status);
70        header('Content-type: application/json; charset=utf-8');
71        ignore_user_abort();
72        ob_start();
73        echo json_encode($response, $opts);
74        $size = ob_get_length();
75        header("Content-Length: $size");
76        // Print content.
77        ob_end_flush();
78        flush();
79        session_write_close();
80}
81
82/**
[1ab1b31d]83 * @brief    Validate API key included in "Authorization" HTTP header.
84 * @return   JSON response on error.
85 */
86function validateApiKey() {
87        global $cmd;
88        global $userid;
89        $response = array();
90        $app = \Slim\Slim::getInstance();
91        // Read Authorization HTTP header.
[2f11053]92        if (! empty($_SERVER['HTTP_AUTHORIZATION'])) {
[1ab1b31d]93                // Assign user id. that match this key to global variable.
[2f11053]94                $apikey = htmlspecialchars($_SERVER['HTTP_AUTHORIZATION']);
[1ab1b31d]95                $cmd->texto = "SELECT idusuario
96                                 FROM usuarios
97                                WHERE apikey='$apikey' LIMIT 1";
98                $rs=new Recordset;
99                $rs->Comando=&$cmd;
100                if ($rs->Abrir()) {
101                        $rs->Primero();
102                        if (!$rs->EOF){
103                                // Fetch user id.
104                                $userid = $rs->campos["idusuario"];
105                        } else {
106                                // Credentials error.
107                                $response['message'] = 'Login failed. Incorrect credentials';
108                                jsonResponse(401, $response);
109                                $app->stop();
110                        }
111                        $rs->Cerrar();
112                } else {
[a38cb26]113                        // Database error.
[1ab1b31d]114                        $response['message'] = "An error occurred, please try again";
115                        jsonResponse(500, $response);
116                }
117        } else {
118                // Error: missing API key.
119                $response['message'] = 'Missing API key';
120                jsonResponse(400, $response);
121                $app->stop();
122        }
123}
124
125/**
126 * @brief    Check if parameter is set and print error messages if empty.
127 * @param    string param    Parameter to check.
128 * @return   boolean         "false" if parameter is null, otherwise "true".
129 */
130function checkParameter($param) {
131        if (isset($param)) {
132                return true;
133        } else {
134                // Print error message.
135                $response['message'] = 'Parameter not found';
136                jsonResponse(400, $response);
137                return false;
138        }
139}
140
141/**
[d8b6c70]142 * @brief    Check if all parameters are positive integer numbers.
143 * @param    int id ...      Identificators to check (variable number of parameters).
144 * @return   boolean         "true" if all ids are int>0, otherwise "false".
145 */
146function checkIds() {
147        $opts = Array('options' => Array('min_range' => 1));    // Check for int>0
148        foreach (func_get_args() as $id) {
[4705afe]149                if (filter_var($id, FILTER_VALIDATE_INT, $opts) === false) {
[d8b6c70]150                        return false;
151                }
152        }
153        return true;
154}
155
156/**
[1ab1b31d]157 * @fn       sendCommand($serverip, $serverport, $reqframe, &$values)
158 * @brief    Send a command to an OpenGnsys ogAdmServer and get request.
159 * @param    string serverip    Server IP address.
160 * @param    string serverport  Server port.
161 * @param    string reqframe    Request frame (field's separator is "\r").
162 * @param    array values       Response values (out parameter).
163 * @return   boolean            "true" if success, otherwise "false".
164 */
165function sendCommand($serverip, $serverport, $reqframe, &$values) {
166        global $LONCABECERA;
167        global $LONHEXPRM;
168
169        // Connect to server.
170        $respvalues = "";
171        $connect = new SockHidra($serverip, $serverport);
172        if ($connect->conectar()) {
173                // Send request frame to server.
174                $result = $connect->envia_peticion($reqframe);
175                if ($result) {
176                        // Parse request frame.
177                        $respframe = $connect->recibe_respuesta();
178                        $connect->desconectar();
179                        $paramlen = hexdec(substr($respframe, $LONCABECERA, $LONHEXPRM));
180                        $params = substr($respframe, $LONCABECERA+$LONHEXPRM, $paramlen);
181                        // Fetch values and return result.
182                        $values = extrae_parametros($params, "\r", '=');
183                        return ($values);
184                } else {
185                        // Return with error.
186                        return (false);
187                }
188        } else {
189                // Return with error.
190                return (false);
191        }
192}
193
194/**
[357352b]195 * @brief   Show custom message for "not found" error (404).
196 */
197$app->notFound(function() {
[e7d47882]198        echo "REST route not found.";
[357352b]199   }
200);
201
202/**
[13dc959]203 * @brief   Hook to write a REST init log message, if debug is enabled.
204 * @warning Message will be written in REST log file.
205 */
206$app->hook('slim.before', function() use ($app) {
207        if ($app->settings['debug'])
208                writeRestLog("Init.");
209    }
210);
211
212/**
213 * @brief   Hook to write an error log message and a REST exit log message if debug is enabled.
214 * @warning Error message will be written in web server's error file.
215 * @warning REST message will be written in REST log file.
[1ab1b31d]216 */
217$app->hook('slim.after', function() use ($app) {
218        if ($app->response->getStatus() != 200 ) {
[357352b]219                // Compose error message (truncating long lines).
220                $app->log->error(date(DATE_ISO8601) . ': ' .
[13dc959]221                                 $app->getName() . ': ' .
222                                 $_SERVER['REMOTE_ADDR'] . ": " .
223                                 (isset($userid) ? $userid : "-") . ": " .
[1ab1b31d]224                                 $app->response->getStatus() . ': ' .
[f784f18]225                                 $app->request->getMethod() . ' ' .
[1ab1b31d]226                                 $app->request->getPathInfo() . ': ' .
[357352b]227                                 substr($app->response->getBody(), 0, 100));
[1ab1b31d]228        }
[13dc959]229        if ($app->settings['debug'])
230                writeRestLog("Exit.");
[1ab1b31d]231   }
232);
233
234
[3551804]235// Common routes.
236
237/**
238 * @brief    Get general server information
239 * @note     Route: /info, Method: GET
240 * @param    no
241 * @return   JSON object with basic server information (version, services, etc.)
242 */
243$app->get('/info', function() {
[606a0c7]244      // Reading version file.
[3551804]245      @list($project, $version, $release) = explode(' ', file_get_contents('/opt/opengnsys/doc/VERSION.txt'));
[606a0c7]246      $response['project'] = trim($project);
247      $response['version'] = trim($version);
248      $response['release'] = trim($release);
[3551804]249      // Getting actived services.
250      @$services = parse_ini_file('/etc/default/opengnsys');
[606a0c7]251      $response['services'] = Array();
252      if (@$services["RUN_OGADMSERVER"] === "yes") {
253          array_push($response['services'], "server");
254          $hasOglive = true;
255      }
256      if (@$services["RUN_OGADMREPO"] === "yes")  array_push($response['services'], "repository");
257      if (@$services["RUN_BTTRACKER"] === "yes")  array_push($response['services'], "tracker");
258      // Reading installed ogLive information file.
259      if ($hasOglive === true) {
[90e3284]260          $data = json_decode(@file_get_contents('/opt/opengnsys/etc/ogliveinfo.json'));
261          if (isset($data->oglive)) {
262              $response['oglive'] = $data->oglive;
[606a0c7]263          }
264      }
[3551804]265      jsonResponse(200, $response);
266   }
267);
268
269/**
270 * @brief    Get the server status
271 * @note     Route: /status, Method: GET
272 * @param    no
273 * @return   JSON object with all data collected from server status (RAM, %CPU, etc.).
274 */
275$app->get('/status', function() {
276      // Getting memory and CPU information.
277      exec("awk '$1~/Mem/ {print $2}' /proc/meminfo",$memInfo);
278      $memInfo = array("total" => $memInfo[0], "used" => $memInfo[1]);
279      $cpuInfo = exec("awk '$1==\"cpu\" {printf \"%.2f\",($2+$4)*100/($2+$4+$5)}' /proc/stat");
280      $cpuModel = exec("awk -F: '$1~/model name/ {print $2}' /proc/cpuinfo");
281      $response["memInfo"] = $memInfo;
282      $response["cpu"] = array("model" => trim($cpuModel), "usage" => $cpuInfo);
283      jsonResponse(200, $response);
284   }
285);
[357352b]286?>
Note: See TracBrowser for help on using the repository browser.