index.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. # ***** BEGIN LICENSE BLOCK *****
  3. # Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4. #
  5. # The contents of this file are subject to the Mozilla Public License Version
  6. # 1.1 (the "License"); you may not use this file except in compliance with
  7. # the License. You may obtain a copy of the License at
  8. # http://www.mozilla.org/MPL/
  9. #
  10. # Software distributed under the License is distributed on an "AS IS" basis,
  11. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. # for the specific language governing rights and limitations under the
  13. # License.
  14. #
  15. # The Original Code is Weave Minimal Server
  16. #
  17. # The Initial Developer of the Original Code is
  18. # Mozilla Labs.
  19. # Portions created by the Initial Developer are Copyright (C) 2008
  20. # the Initial Developer. All Rights Reserved.
  21. #
  22. # Contributor(s):
  23. # Toby Elliott (telliott@mozilla.com)
  24. # Luca Tettamanti
  25. # Christian Wittmer <chris@computersalat.de>
  26. #
  27. # Alternatively, the contents of this file may be used under the terms of
  28. # either the GNU General Public License Version 2 or later (the "GPL"), or
  29. # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30. # in which case the provisions of the GPL or the LGPL are applicable instead
  31. # of those above. If you wish to allow use of your version of this file only
  32. # under the terms of either the GPL or the LGPL, and not to allow others to
  33. # use your version of this file under the terms of the MPL, indicate your
  34. # decision by deleting the provisions above and replace them with the notice
  35. # and other provisions required by the GPL or the LGPL. If you do not delete
  36. # the provisions above, a recipient may use your version of this file under
  37. # the terms of any one of the MPL, the GPL or the LGPL.
  38. #
  39. # ***** END LICENSE BLOCK *****
  40. if ( ! file_exists("settings.php") && file_exists("setup.php") ) {
  41. require_once "setup.php";
  42. exit;
  43. } else if ( ! file_exists("settings.php") ) {
  44. echo "<hr><h2>Maybe the setup is not completed, missing settings.php</h2><hr>";
  45. exit;
  46. } else if ( file_exists("setup.php") ) {
  47. echo "<hr><h2>Maybe the setup is not completed, else please delete setup.php</h2><hr>";
  48. exit;
  49. }
  50. require_once 'weave_storage.php';
  51. require_once 'weave_basic_object.php';
  52. require_once 'weave_utils.php';
  53. require_once 'weave_hash.php';
  54. require_once "WBOJsonOutput.php";
  55. //header("Content-type: application/json");
  56. $server_time = round(microtime(1), 2);
  57. header("X-Weave-Timestamp: " . $server_time);
  58. # Basic path extraction and validation. No point in going on if these are missing
  59. $path = '/';
  60. if (!empty($_SERVER['PATH_INFO']))
  61. $path = $_SERVER['PATH_INFO'];
  62. else if (!empty($_SERVER['ORIG_PATH_INFO']))
  63. $path = $_SERVER['ORIG_PATH_INFO'];
  64. else if (!empty($_SERVER["REQUEST_URI"]))
  65. {
  66. log_error("experimental path");
  67. # this is kind of an experimental try, i needed it so i build it,
  68. # but that doesent mean that it does work... well it works for me
  69. # and it shouldnt break anything...
  70. $path = $_SERVER["REQUEST_URI"];
  71. $lastfolder = substr(FSYNCMS_ROOT,strrpos(FSYNCMS_ROOT, "/",-2));
  72. $path = substr($path, (strpos($path,$lastfolder) + strlen($lastfolder)-1)); #chop the lead slash
  73. if(strpos($path,'?') != false)
  74. $path = substr($path, 0, strpos($path,'?')); //remove php arguments
  75. log_error("path_exp:".$path);
  76. }
  77. else
  78. report_problem("No path found", 404);
  79. $path = substr($path, 1); #chop the lead slash
  80. log_error("start request_____" . $path);
  81. // ensure that we got a valid request
  82. if ( !$path )
  83. report_problem("Invalid request!", 400);
  84. // split path into parts and make sure that all values are properly initialized
  85. list($version, $username, $function, $collection, $id) = array_pad(explode('/', $path.'///'), 5, '');
  86. if($version == 'user' || $version == 'misc')
  87. {
  88. //asking for userApi -> user.php
  89. $include = true;
  90. require 'user.php';
  91. exit(); // should not get here, but how knows
  92. }
  93. header("Content-type: application/json");
  94. if ($version != '1.0' && $version != '1.1')
  95. report_problem('Function not found', 404);
  96. if ($function != "info" && $function != "storage")
  97. report_problem(WEAVE_ERROR_FUNCTION_NOT_SUPPORTED, 400);
  98. if (!validate_username($username))
  99. report_problem(WEAVE_ERROR_INVALID_USERNAME, 400);
  100. #only a delete has meaning without a collection
  101. if ($collection)
  102. {
  103. if (!validate_collection($collection))
  104. report_problem(WEAVE_ERROR_INVALID_COLLECTION, 400);
  105. }
  106. else if ($_SERVER['REQUEST_METHOD'] != 'DELETE')
  107. report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
  108. #quick check to make sure that any non-storage function calls are just using GET
  109. if ($function != 'storage' && $_SERVER['REQUEST_METHOD'] != 'GET')
  110. report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
  111. #user passes preliminaries, connections made, onto actually getting the data
  112. try
  113. {
  114. $db = new WeaveStorage($username);
  115. #Auth the user
  116. verify_user($username, $db);
  117. #user passes preliminaries, connections made, onto actually getting the data
  118. if ($_SERVER['REQUEST_METHOD'] == 'GET')
  119. {
  120. if ($function == 'info')
  121. {
  122. switch ($collection)
  123. {
  124. case 'quota':
  125. exit(json_encode(array($db->get_storage_total())));
  126. case 'collections':
  127. exit(json_encode($db->get_collection_list_with_timestamps()));
  128. case 'collection_counts':
  129. exit(json_encode($db->get_collection_list_with_counts()));
  130. case 'collection_usage':
  131. $results = $db->get_collection_storage_totals();
  132. foreach (array_keys($results) as $collection)
  133. {
  134. $results[$collection] = ceil($results[$collection] / 1024); #converting to k from bytes
  135. }
  136. exit(json_encode($results));
  137. default:
  138. report_problem(WEAVE_ERROR_INVALID_PROTOCOL, 400);
  139. }
  140. }
  141. elseif ($function == 'storage')
  142. {
  143. log_error("function storage");
  144. if ($id) #retrieve a single record
  145. {
  146. $wbo = $db->retrieve_objects($collection, $id, 1); #get the full contents of one record
  147. if (count($wbo) > 0)
  148. {
  149. $item = array_shift($wbo);
  150. echo $item->json();
  151. }
  152. else
  153. report_problem("record not found", 404);
  154. }
  155. else #retrieve a batch of records. Sadly, due to potential record sizes, have the storage object stream the output...
  156. {
  157. log_error("retrieve a batch");
  158. $full = array_key_exists('full', $_GET) && $_GET['full'];
  159. $outputter = new WBOJsonOutput($full);
  160. $params = validate_search_params();
  161. $ids = $db->retrieve_objects($collection, null, $full, $outputter,
  162. $params['parentid'], $params['predecessorid'],
  163. $params['newer'], $params['older'],
  164. $params['sort'],
  165. $params['limit'], $params['offset'],
  166. $params['ids'],
  167. $params['index_above'], $params['index_below'], $params['depth']
  168. );
  169. }
  170. }
  171. }
  172. else if ($_SERVER['REQUEST_METHOD'] == 'PUT') #add a single record to the server
  173. {
  174. $wbo = new wbo();
  175. $json = get_json();
  176. if (!$wbo->extract_json($json))
  177. report_problem(WEAVE_ERROR_JSON_PARSE, 400);
  178. check_quota($db);
  179. check_timestamp($collection, $db);
  180. #use the url if the json object doesn't have an id
  181. if (!$wbo->id() && $id) { $wbo->id($id); }
  182. $wbo->collection($collection);
  183. $wbo->modified($server_time); #current microtime
  184. if ($wbo->validate())
  185. {
  186. #if there's no payload (as opposed to blank), then update the metadata
  187. if ($wbo->payload_exists())
  188. $db->store_object($wbo);
  189. else
  190. $db->update_object($wbo);
  191. }
  192. else
  193. {
  194. report_problem(WEAVE_ERROR_INVALID_WBO, 400);
  195. }
  196. echo json_encode($server_time);
  197. }
  198. else if ($_SERVER['REQUEST_METHOD'] == 'POST')
  199. {
  200. $json = get_json();
  201. check_quota($db);
  202. check_timestamp($collection, $db);
  203. $success_ids = array();
  204. $failed_ids = array();
  205. $db->begin_transaction();
  206. foreach ($json as $wbo_data)
  207. {
  208. $wbo = new wbo();
  209. if (!$wbo->extract_json($wbo_data))
  210. {
  211. $failed_ids[$wbo->id()] = $wbo->get_error();
  212. continue;
  213. }
  214. $wbo->collection($collection);
  215. $wbo->modified($server_time);
  216. if ($wbo->validate())
  217. {
  218. #if there's no payload (as opposed to blank), then update the metadata
  219. if ($wbo->payload_exists())
  220. {
  221. $db->store_object($wbo);
  222. }
  223. else
  224. {
  225. $db->update_object($wbo);
  226. }
  227. $success_ids[] = $wbo->id();
  228. }
  229. else
  230. {
  231. $failed_ids[$wbo->id()] = $wbo->get_error();
  232. }
  233. }
  234. $db->commit_transaction();
  235. echo json_encode(array('success' => $success_ids, 'failed' => $failed_ids));
  236. }
  237. else if ($_SERVER['REQUEST_METHOD'] == 'DELETE')
  238. {
  239. check_timestamp($collection, $db);
  240. if ($id)
  241. {
  242. $db->delete_object($collection, $id);
  243. $db->clear_quota_usage($username);
  244. }
  245. else if ($collection)
  246. {
  247. $params = validate_search_params();
  248. $db->delete_objects($collection, null,
  249. $params['parentid'], $params['predecessorid'],
  250. $params['newer'], $params['older'],
  251. $params['sort'],
  252. $params['limit'], $params['offset'],
  253. $params['ids'],
  254. $params['index_above'], $params['index_below']
  255. );
  256. $db->clear_quota_usage($username);
  257. }
  258. else if($function == 'storage') // ich vermute mal storage reinigen
  259. {
  260. if (!array_key_exists('HTTP_X_CONFIRM_DELETE', $_SERVER))
  261. report_problem(WEAVE_ERROR_NO_OVERWRITE, 412);
  262. $db->delete_storage($username);
  263. $db->clear_quota_usage($username);
  264. }
  265. else
  266. {
  267. if (!array_key_exists('HTTP_X_CONFIRM_DELETE', $_SERVER))
  268. report_problem(WEAVE_ERROR_NO_OVERWRITE, 412);
  269. log_error("delete "."Server ".print_r( $_SERVER, true));
  270. $db->delete_user($username);
  271. }
  272. echo json_encode($server_time);
  273. }
  274. else
  275. {
  276. #bad protocol. There are protocols left? HEAD, I guess.
  277. report_problem(1, 400);
  278. }
  279. }
  280. catch(Exception $e)
  281. {
  282. report_problem($e->getMessage(), $e->getCode());
  283. }
  284. #The datasets we might be dealing with here are too large for sticking it all into an array, so
  285. #we need to define a direct-output method for the storage class to use. If we start producing multiples
  286. #(unlikely), we can put them in their own class.
  287. #include_once "WBOJsonOutput.php";
  288. ?>