source: admin/WebConsole/rest/common.php @ 3bbaf79

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 3bbaf79 was 7e7c0cd, checked in by ramon <ramongomez@…>, 7 years ago

#708: Compatibilidad con funciones horarias de PHP 5.6+.

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

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