source: admin/WebConsole/rest/common.php @ 72d19da

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-instalacion
Last change on this file since 72d19da was b6ec162, checked in by Ramón M. Gómez <ramongomez@…>, 6 years ago

#834: Remove all redundant PHP closing tags.

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