rest.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. // Copyright (C) 2010-2013 Combodo SARL
  3. //
  4. // This file is part of iTop.
  5. //
  6. // iTop is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // iTop is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with iTop. If not, see <http://www.gnu.org/licenses/>
  18. /**
  19. * Entry point for all the REST services
  20. *
  21. * --------------------------------------------------
  22. * Create an object
  23. * --------------------------------------------------
  24. * POST itop/webservices/rest.php
  25. * {
  26. * operation: 'object_create',
  27. * comment: 'Synchronization from blah...',
  28. * class: 'UserRequest',
  29. * results: 'id, friendlyname',
  30. * fields:
  31. * {
  32. * org_id: 'SELECT Organization WHERE name = "Demo"',
  33. * caller_id:
  34. * {
  35. * name: 'monet',
  36. * first_name: 'claude',
  37. * }
  38. * title: 'Houston, got a problem!',
  39. * description: 'The fridge is empty'
  40. * contacts_list:
  41. * [
  42. * {
  43. * role: 'pizza delivery',
  44. * contact_id:
  45. * {
  46. * finalclass: 'Person',
  47. * name: 'monet',
  48. * first_name: 'claude'
  49. * }
  50. * }
  51. * ]
  52. * }
  53. * }
  54. *
  55. *
  56. * @copyright Copyright (C) 2010-2013 Combodo SARL
  57. * @license http://opensource.org/licenses/AGPL-3.0
  58. */
  59. if (!defined('__DIR__')) define('__DIR__', dirname(__FILE__));
  60. require_once(__DIR__.'/../approot.inc.php');
  61. require_once(APPROOT.'/application/application.inc.php');
  62. require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
  63. require_once(APPROOT.'/application/startup.inc.php');
  64. require_once(APPROOT.'core/restservices.class.inc.php');
  65. /**
  66. * Result structure that is specific to the hardcoded verb 'list_operations'
  67. */
  68. class RestResultListOperations extends RestResult
  69. {
  70. public $version;
  71. public $operations;
  72. public function AddOperation($sVerb, $sDescription, $sServiceProviderClass)
  73. {
  74. $this->operations[] = array(
  75. 'verb' => $sVerb,
  76. 'description' => $sDescription,
  77. 'extension' => $sServiceProviderClass
  78. );
  79. }
  80. }
  81. ////////////////////////////////////////////////////////////////////////////////
  82. //
  83. // Main
  84. //
  85. $oP = new ajax_page('rest');
  86. try
  87. {
  88. utils::UseParamFile();
  89. $sAuthUser = utils::ReadPostedParam('auth_user', null, 'raw_data');
  90. $sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
  91. if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))
  92. {
  93. UserRights::Login($sAuthUser); // Login & set the user's language
  94. }
  95. else
  96. {
  97. throw new Exception("Invalid login '$sAuthUser'", RestResult::UNAUTHORIZED);
  98. }
  99. $sVersion = utils::ReadParam('version', null, false, 'raw_data');
  100. if ($sVersion == null)
  101. {
  102. throw new Exception("Missing parameter 'version' (e.g. '1.0')", RestResult::MISSING_VERSION);
  103. }
  104. $sJsonString = utils::ReadPostedParam('json_data', null, 'raw_data');
  105. if ($sJsonString == null)
  106. {
  107. throw new Exception("Missing parameter 'json_data", RestResult::MISSING_JSON);
  108. }
  109. $aJsonData = json_decode($sJsonString);
  110. if ($aJsonData == null)
  111. {
  112. throw new Exception("Parameter json_data is not a valid JSON structure", RestResult::INVALID_JSON);
  113. }
  114. $aProviders = array();
  115. foreach(get_declared_classes() as $sPHPClass)
  116. {
  117. $oRefClass = new ReflectionClass($sPHPClass);
  118. if ($oRefClass->implementsInterface('iRestServiceProvider'))
  119. {
  120. $aProviders[] = new $sPHPClass;
  121. }
  122. }
  123. $aOpToRestService = array(); // verb => $oRestServiceProvider
  124. foreach ($aProviders as $oRestSP)
  125. {
  126. $aOperations = $oRestSP->ListOperations($sVersion);
  127. foreach ($aOperations as $aOpData)
  128. {
  129. $aOpToRestService[$aOpData['verb']] = array
  130. (
  131. 'service_provider' => $oRestSP,
  132. 'description' => $aOpData['description'],
  133. );
  134. }
  135. }
  136. if (count($aOpToRestService) == 0)
  137. {
  138. throw new Exception("There is no service available for version '$sVersion'", RestResult::UNSUPPORTED_VERSION);
  139. }
  140. $sOperation = RestUtils::GetMandatoryParam($aJsonData, 'operation');
  141. if ($sOperation == 'list_operations')
  142. {
  143. $oResult = new RestResultListOperations();
  144. $oResult->message = "Operations: ".count($aOpToRestService);
  145. $oResult->version = $sVersion;
  146. foreach ($aOpToRestService as $sVerb => $aOpData)
  147. {
  148. $oResult->AddOperation($sVerb, $aOpData['description'], get_class($aOpData['service_provider']));
  149. }
  150. }
  151. else
  152. {
  153. if (!array_key_exists($sOperation, $aOpToRestService))
  154. {
  155. throw new Exception("Unknown verb '$sVersion'", RestResult::UNKNOWN_OPERATION);
  156. }
  157. $oRS = $aOpToRestService[$sOperation]['service_provider'];
  158. $oResult = $oRS->ExecOperation($sVersion, $sOperation, $aJsonData);
  159. }
  160. }
  161. catch(Exception $e)
  162. {
  163. $oResult = new RestResult();
  164. if ($e->GetCode() == 0)
  165. {
  166. $oResult->code = RestResult::INTERNAL_ERROR;
  167. }
  168. else
  169. {
  170. $oResult->code = $e->GetCode();
  171. }
  172. $oResult->message = "Error: ".$e->GetMessage();
  173. }
  174. // Output the results
  175. //
  176. $oP->add_header('Access-Control-Allow-Origin: *');
  177. $sCallback = utils::ReadParam('callback', null);
  178. if ($sCallback == null)
  179. {
  180. $oP->SetContentType('application/json');
  181. $oP->add(json_encode($oResult));
  182. }
  183. else
  184. {
  185. $oP->SetContentType('application/javascript');
  186. $oP->add($sCallback.'('.json_encode($oResult).')');
  187. }
  188. $oP->Output();
  189. ?>