Current File : /home/escuelai/public_html/it/src/Api/APIXmlrpc.php |
<?php
/**
* ---------------------------------------------------------------------
*
* GLPI - Gestionnaire Libre de Parc Informatique
*
* http://glpi-project.org
*
* @copyright 2015-2022 Teclib' and contributors.
* @copyright 2003-2014 by the INDEPNET Development Team.
* @licence https://www.gnu.org/licenses/gpl-3.0.html
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
*/
namespace Glpi\Api;
use Toolbox;
class APIXmlrpc extends API
{
public static $content_type = "application/xml";
public static function getTypeName($nb = 0)
{
return __('XMLRPC API');
}
/**
* Upload and validate files from request and append to $this->parameters['input']
*
* @return void
*/
public function manageUploadedFiles()
{
}
/**
* parse POST var to retrieve
* - Resource
* - Identifier
* - and parameters
*
* And send to method corresponding identified resource
*
* Then send response to client.
*
* @since 9.1
*
* @return void xmlrpc response
*/
public function call()
{
Toolbox::logInfo('Deprecated: Usage of XML-RPC has been deprecated. Please use REST API.');
$resource = $this->parseIncomingParams();
// retrieve session (if exist)
$this->retrieveSession();
$this->initApi();
$code = 200;
// Do not unlock the php session for ressources that may handle it
if (in_array($resource, $this->getRessourcesWithSessionWrite())) {
$this->session_write = true;
}
// Check API session unless blacklisted (init session, ...)
if (!in_array($resource, $this->getRessourcesAllowedWithoutSession())) {
$this->initEndpoint(true, $resource);
}
if ($resource === "initSession") {
$this->returnResponse($this->initSession($this->parameters));
} elseif ($resource === "killSession") { // logout from glpi
$this->returnResponse($this->killSession());
} elseif ($resource === "changeActiveEntities") { // change active entities
$this->returnResponse($this->changeActiveEntities($this->parameters));
} elseif ($resource === "getMyEntities") { // get all entities of logged user
$this->returnResponse($this->getMyEntities($this->parameters));
} elseif ($resource === "getActiveEntities") { // get curent active entity
$this->returnResponse($this->getActiveEntities($this->parameters));
} elseif ($resource === "changeActiveProfile") { // change active profile
$this->returnResponse($this->changeActiveProfile($this->parameters));
} elseif ($resource === "getMyProfiles") { // get all profiles of current logged user
$this->returnResponse($this->getMyProfiles($this->parameters));
} elseif ($resource === "getActiveProfile") { // get current active profile
$this->returnResponse($this->getActiveProfile($this->parameters));
} elseif ($resource === "getFullSession") { // get complete php session
$this->returnResponse($this->getFullSession($this->parameters));
} elseif ($resource === "getGlpiConfig") { // get complete php var $CFG_GLPI
$this->returnResponse($this->getGlpiConfig($this->parameters));
} elseif ($resource === "getMultipleItems") { // get multiple items (with various itemtype)
$this->returnResponse($this->getMultipleItems($this->parameters));
} elseif ($resource === "listSearchOptions") { // list searchOptions of an itemtype
$this->returnResponse($this->listSearchOptions(
$this->parameters['itemtype'],
$this->parameters
));
} elseif ($resource === "search") { // Search on itemtype
$this->checkSessionToken();
// search
$response = $this->searchItems($this->parameters['itemtype'], $this->parameters);
// add pagination headers
$additionalheaders = [];
$additionalheaders["Accept-Range"] = $this->parameters['itemtype'] . " "
. Toolbox::get_max_input_vars();
if ($response['totalcount'] > 0) {
$additionalheaders["Content-Range"] = $response['content-range'];
}
// different http return codes for complete or partial response
if ($response['count'] < $response['totalcount']) {
$code = 206; // partial content
}
$this->returnResponse($response, $code, $additionalheaders);
} elseif ($resource === "lostPassword") {
$this->returnResponse($this->lostPassword($this->parameters));
} elseif (
in_array(
$resource,
["getItem", "getItems", "createItems", "updateItems", "deleteItems"]
)
) {
// commonDBTM manipulation
// check itemtype parameter
if (!isset($this->parameters['itemtype'])) {
$this->returnError(__("missing itemtype"), 400, "ITEMTYPE_RESOURCE_MISSING");
}
if (
!class_exists($this->parameters['itemtype'])
|| !is_subclass_of($this->parameters['itemtype'], 'CommonDBTM')
) {
$this->returnError(
__("itemtype not found or not an instance of CommonDBTM"),
400,
"ERROR_ITEMTYPE_NOT_FOUND_NOR_COMMONDBTM"
);
} elseif ($resource === "getItem") { // get an CommonDBTM item
// check id parameter
if (!isset($this->parameters['id'])) {
$this->returnError(__("missing id"), 400, "ID_RESOURCE_MISSING");
}
$response = $this->getItem($this->parameters['itemtype'], $this->parameters['id'], $this->parameters);
$additionalheaders = [];
if (isset($response['date_mod'])) {
$datemod = strtotime($response['date_mod']);
$additionalheaders['Last-Modified'] = gmdate("D, d M Y H:i:s", $datemod) . " GMT";
}
$this->returnResponse($response, 200, $additionalheaders);
} elseif ($resource === "getItems") { // get a collection of a CommonDBTM item
// return collection of items
$totalcount = 0;
$response = $this->getItems($this->parameters['itemtype'], $this->parameters, $totalcount);
//add pagination headers
$range = [0, $_SESSION['glpilist_limit']];
if (isset($this->parameters['range'])) {
$range = explode("-", $this->parameters['range']);
}
// fix end range
if ($range[1] > $totalcount - 1) {
$range[1] = $totalcount - 1;
}
// trigger partial content return code
if ($range[1] - $range[0] + 1 < $totalcount) {
$code = 206; // partial content
}
$additionalheaders = [];
$additionalheaders["Accept-Range"] = $this->parameters['itemtype'] . " " .
Toolbox::get_max_input_vars();
if ($totalcount > 0) {
$additionalheaders["Content-Range"] = implode('-', $range) . "/" . $totalcount;
}
$this->returnResponse($response, $code, $additionalheaders);
} elseif ($resource === "createItems") { // create one or many CommonDBTM items
$response = $this->createItems($this->parameters['itemtype'], $this->parameters);
$additionalheaders = [];
if (isset($response['id'])) {
// add a location targetting created element
$additionalheaders['location'] = self::$api_url . "/" . $this->parameters['itemtype'] . "/" . $response['id'];
} else {
// add a link header targetting created elements
$additionalheaders['link'] = "";
foreach ($response as $created_item) {
if ($created_item['id']) {
$additionalheaders['link'] .= self::$api_url . "/" . $this->parameters['itemtype'] .
"/" . $created_item['id'] . ",";
}
}
// remove last comma
$additionalheaders['link'] = trim($additionalheaders['link'], ",");
}
$this->returnResponse($response, 201);
} elseif ($resource === "updateItems") { // update one or many CommonDBTM items
$this->returnResponse($this->updateItems(
$this->parameters['itemtype'],
$this->parameters
));
} elseif ($resource === "deleteItems") { // delete one or many CommonDBTM items
if (isset($this->parameters['id'])) {
// override input
$this->parameters['input'] = new \stdClass();
$this->parameters['input']->id = $this->parameters['id'];
}
$this->returnResponse(
$this->deleteItems(
$this->parameters['itemtype'],
$this->parameters
),
$code
);
}
}
$this->messageLostError();
}
/**
* Construct this->parameters from POST data
*
* @since 9.1
*
* @return string
*/
public function parseIncomingParams()
{
$parameters = [];
$resource = "";
$parameters = xmlrpc_decode_request(
trim($this->getHttpBody()),
$resource,
'UTF-8'
);
$this->parameters = (isset($parameters[0]) && is_array($parameters[0])
? $parameters[0]
: []);
// transform input from array to object
if (
isset($this->parameters['input'])
&& is_array($this->parameters['input'])
) {
$first_field = array_values($this->parameters['input'])[0];
if (is_array($first_field)) {
foreach ($this->parameters['input'] as &$input) {
$input = json_decode(json_encode($input), false);
}
} else {
$this->parameters['input'] = json_decode(
json_encode($this->parameters['input']),
false
);
}
}
// check boolean parameters
foreach ($this->parameters as &$parameter) {
if ($parameter === "true") {
$parameter = true;
}
if ($parameter === "false") {
$parameter = false;
}
}
return $resource;
}
protected function returnResponse($response, $httpcode = 200, $additionalheaders = [])
{
if (empty($httpcode)) {
$httpcode = 200;
}
foreach ($additionalheaders as $key => $value) {
header("$key: $value");
}
http_response_code($httpcode);
$this->header($this->debug);
$response = $this->escapekeys($response);
$out = xmlrpc_encode_request(null, $response, ['encoding' => 'UTF-8',
'escaping' => 'markup'
]);
echo $out;
exit;
}
/**
* Add a space before all numeric keys to prevent their deletion by xmlrpc_encode_request function
* see https://bugs.php.net/bug.php?id=21949
*
* @since 9.1
*
* @param array $response the response array to escape
*
* @return array the escaped response.
*/
protected function escapekeys($response = [])
{
if (is_array($response)) {
$escaped_response = [];
foreach ($response as $key => $value) {
if (is_integer($key)) {
$key = " " . $key;
}
if (is_array($value)) {
$value = $this->escapekeys($value);
}
$escaped_response[$key] = $value;
}
return $escaped_response;
}
return $response;
}
}