JsonApiTest.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. use PHPUnit\Framework\TestCase;
  3. use PrivateBin\Controller;
  4. use PrivateBin\Data\Filesystem;
  5. use PrivateBin\Persistence\ServerSalt;
  6. use PrivateBin\Request;
  7. class JsonApiTest extends TestCase
  8. {
  9. protected $_model;
  10. protected $_path;
  11. public function setUp(): void
  12. {
  13. /* Setup Routine */
  14. $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
  15. $this->_model = Filesystem::getInstance(array('dir' => $this->_path));
  16. ServerSalt::setStore($this->_model);
  17. $_POST = array();
  18. $_GET = array();
  19. $_SERVER = array();
  20. if ($this->_model->exists(Helper::getPasteId())) {
  21. $this->_model->delete(Helper::getPasteId());
  22. }
  23. $options = parse_ini_file(CONF_SAMPLE, true);
  24. $options['model_options']['dir'] = $this->_path;
  25. Helper::confBackup();
  26. Helper::createIniFile(CONF, $options);
  27. }
  28. public function tearDown(): void
  29. {
  30. /* Tear Down Routine */
  31. unlink(CONF);
  32. Helper::confRestore();
  33. Helper::rmDir($this->_path);
  34. }
  35. /**
  36. * @runInSeparateProcess
  37. */
  38. public function testCreate()
  39. {
  40. $options = parse_ini_file(CONF, true);
  41. $options['traffic']['limit'] = 0;
  42. Helper::createIniFile(CONF, $options);
  43. $paste = Helper::getPasteJson();
  44. $file = tempnam(sys_get_temp_dir(), 'FOO');
  45. file_put_contents($file, $paste);
  46. Request::setInputStream($file);
  47. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  48. $_SERVER['REQUEST_METHOD'] = 'POST';
  49. $_SERVER['REMOTE_ADDR'] = '::1';
  50. $_SERVER['REQUEST_URI'] = '/';
  51. ob_start();
  52. new Controller;
  53. $content = ob_get_contents();
  54. ob_end_clean();
  55. $response = json_decode($content, true);
  56. $this->assertEquals(0, $response['status'], 'outputs status');
  57. $this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
  58. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  59. $paste = $this->_model->read($response['id']);
  60. $this->assertEquals(
  61. hash_hmac('sha256', $response['id'], $paste['meta']['salt']),
  62. $response['deletetoken'],
  63. 'outputs valid delete token'
  64. );
  65. }
  66. /**
  67. * @runInSeparateProcess
  68. */
  69. public function testPut()
  70. {
  71. $options = parse_ini_file(CONF, true);
  72. $options['traffic']['limit'] = 0;
  73. Helper::createIniFile(CONF, $options);
  74. $paste = Helper::getPasteJson();
  75. $file = tempnam(sys_get_temp_dir(), 'FOO');
  76. file_put_contents($file, $paste);
  77. Request::setInputStream($file);
  78. $_SERVER['QUERY_STRING'] = Helper::getPasteId();
  79. $_GET[Helper::getPasteId()] = '';
  80. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  81. $_SERVER['REQUEST_METHOD'] = 'PUT';
  82. $_SERVER['REMOTE_ADDR'] = '::1';
  83. ob_start();
  84. new Controller;
  85. $content = ob_get_contents();
  86. ob_end_clean();
  87. unlink($file);
  88. $response = json_decode($content, true);
  89. $this->assertEquals(0, $response['status'], 'outputs status');
  90. $this->assertEquals(Helper::getPasteId(), $response['id'], 'outputted paste ID matches input');
  91. $this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
  92. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  93. $paste = $this->_model->read($response['id']);
  94. $this->assertEquals(
  95. hash_hmac('sha256', $response['id'], $paste['meta']['salt']),
  96. $response['deletetoken'],
  97. 'outputs valid delete token'
  98. );
  99. }
  100. /**
  101. * @runInSeparateProcess
  102. */
  103. public function testDelete()
  104. {
  105. $this->_model->create(Helper::getPasteId(), Helper::getPaste());
  106. $this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
  107. $paste = $this->_model->read(Helper::getPasteId());
  108. $file = tempnam(sys_get_temp_dir(), 'FOO');
  109. file_put_contents($file, json_encode(array(
  110. 'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste['meta']['salt']),
  111. )));
  112. Request::setInputStream($file);
  113. $_SERVER['QUERY_STRING'] = Helper::getPasteId();
  114. $_GET[Helper::getPasteId()] = '';
  115. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  116. $_SERVER['REQUEST_METHOD'] = 'DELETE';
  117. ob_start();
  118. new Controller;
  119. $content = ob_get_contents();
  120. ob_end_clean();
  121. unlink($file);
  122. $response = json_decode($content, true);
  123. $this->assertEquals(0, $response['status'], 'outputs status');
  124. $this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
  125. }
  126. /**
  127. * @runInSeparateProcess
  128. */
  129. public function testDeleteWithPost()
  130. {
  131. $this->_model->create(Helper::getPasteId(), Helper::getPaste());
  132. $this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
  133. $paste = $this->_model->read(Helper::getPasteId());
  134. $file = tempnam(sys_get_temp_dir(), 'FOO');
  135. file_put_contents($file, json_encode(array(
  136. 'pasteid' => Helper::getPasteId(),
  137. 'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste['meta']['salt']),
  138. )));
  139. Request::setInputStream($file);
  140. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  141. $_SERVER['REQUEST_METHOD'] = 'POST';
  142. ob_start();
  143. new Controller;
  144. $content = ob_get_contents();
  145. ob_end_clean();
  146. $response = json_decode($content, true);
  147. $this->assertEquals(0, $response['status'], 'outputs status');
  148. $this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
  149. }
  150. /**
  151. * @runInSeparateProcess
  152. */
  153. public function testRead()
  154. {
  155. $paste = Helper::getPaste();
  156. $this->_model->create(Helper::getPasteId(), $paste);
  157. $_SERVER['QUERY_STRING'] = Helper::getPasteId();
  158. $_GET[Helper::getPasteId()] = '';
  159. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  160. ob_start();
  161. new Controller;
  162. $content = ob_get_contents();
  163. ob_end_clean();
  164. $response = json_decode($content, true);
  165. $this->assertEquals(0, $response['status'], 'outputs success status');
  166. $this->assertEquals(Helper::getPasteId(), $response['id'], 'outputs data correctly');
  167. $this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
  168. $this->assertEquals($paste['ct'], $response['ct'], 'outputs data correctly');
  169. $this->assertEquals($paste['meta']['created'], $response['meta']['created'], 'outputs postdate correctly');
  170. $this->assertEquals(0, $response['comment_count'], 'outputs comment_count correctly');
  171. $this->assertEquals(0, $response['comment_offset'], 'outputs comment_offset correctly');
  172. }
  173. /**
  174. * @runInSeparateProcess
  175. */
  176. public function testJsonLdPaste()
  177. {
  178. $paste = Helper::getPaste();
  179. $this->_model->create(Helper::getPasteId(), $paste);
  180. $_GET['jsonld'] = 'paste';
  181. ob_start();
  182. new Controller;
  183. $content = ob_get_contents();
  184. ob_end_clean();
  185. $this->assertEquals(str_replace(
  186. '?jsonld=',
  187. '/?jsonld=',
  188. file_get_contents(PUBLIC_PATH . '/js/paste.jsonld')
  189. ), $content, 'outputs data correctly');
  190. }
  191. /**
  192. * @runInSeparateProcess
  193. */
  194. public function testJsonLdComment()
  195. {
  196. $paste = Helper::getPaste();
  197. $this->_model->create(Helper::getPasteId(), $paste);
  198. $_GET['jsonld'] = 'comment';
  199. ob_start();
  200. new Controller;
  201. $content = ob_get_contents();
  202. ob_end_clean();
  203. $this->assertEquals(str_replace(
  204. '?jsonld=',
  205. '/?jsonld=',
  206. file_get_contents(PUBLIC_PATH . '/js/comment.jsonld')
  207. ), $content, 'outputs data correctly');
  208. }
  209. /**
  210. * @runInSeparateProcess
  211. */
  212. public function testJsonLdPasteMeta()
  213. {
  214. $paste = Helper::getPaste();
  215. $this->_model->create(Helper::getPasteId(), $paste);
  216. $_GET['jsonld'] = 'pastemeta';
  217. ob_start();
  218. new Controller;
  219. $content = ob_get_contents();
  220. ob_end_clean();
  221. $this->assertEquals(str_replace(
  222. '?jsonld=',
  223. '/?jsonld=',
  224. file_get_contents(PUBLIC_PATH . '/js/pastemeta.jsonld')
  225. ), $content, 'outputs data correctly');
  226. }
  227. /**
  228. * @runInSeparateProcess
  229. */
  230. public function testJsonLdCommentMeta()
  231. {
  232. $paste = Helper::getPaste();
  233. $this->_model->create(Helper::getPasteId(), $paste);
  234. $_GET['jsonld'] = 'commentmeta';
  235. ob_start();
  236. new Controller;
  237. $content = ob_get_contents();
  238. ob_end_clean();
  239. $this->assertEquals(str_replace(
  240. '?jsonld=',
  241. '/?jsonld=',
  242. file_get_contents(PUBLIC_PATH . '/js/commentmeta.jsonld')
  243. ), $content, 'outputs data correctly');
  244. }
  245. /**
  246. * @runInSeparateProcess
  247. */
  248. public function testJsonLdInvalid()
  249. {
  250. $paste = Helper::getPaste();
  251. $this->_model->create(Helper::getPasteId(), $paste);
  252. $_GET['jsonld'] = CONF;
  253. ob_start();
  254. new Controller;
  255. $content = ob_get_contents();
  256. ob_end_clean();
  257. $this->assertEquals('{}', $content, 'does not output nasty data');
  258. }
  259. }