9a61e8fd48
todo: GCS added GCS, no GLOBALS, two methods for saving pastes and comments use GLOBALS for verbosity again added getAllPastes() to all storage providers moved to bin, added --delete options, make use of $store->getAllPastes() added --delete-* options to help longopts without -- *sigh* fixed arguments drop singleton behaviour to allow multiple backends of the same type simultaneously remove singleton from Model, collapse loop in migrate.php comments is not indexed tests without data singleton fix exit if scandir() fails extended meta doc
305 lines
11 KiB
PHP
305 lines
11 KiB
PHP
<?php
|
|
|
|
use PrivateBin\Controller;
|
|
use PrivateBin\Data\Filesystem;
|
|
use PrivateBin\Persistence\ServerSalt;
|
|
use PrivateBin\Request;
|
|
|
|
class JsonApiTest extends PHPUnit_Framework_TestCase
|
|
{
|
|
protected $_model;
|
|
|
|
protected $_path;
|
|
|
|
public function setUp()
|
|
{
|
|
/* Setup Routine */
|
|
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
|
if (!is_dir($this->_path)) {
|
|
mkdir($this->_path);
|
|
}
|
|
$this->_model = new Filesystem(array('dir' => $this->_path));
|
|
ServerSalt::setStore($this->_model);
|
|
|
|
$_POST = array();
|
|
$_GET = array();
|
|
$_SERVER = array();
|
|
if ($this->_model->exists(Helper::getPasteId())) {
|
|
$this->_model->delete(Helper::getPasteId());
|
|
}
|
|
$options = parse_ini_file(CONF_SAMPLE, true);
|
|
$options['model_options']['dir'] = $this->_path;
|
|
Helper::confBackup();
|
|
Helper::createIniFile(CONF, $options);
|
|
}
|
|
|
|
public function tearDown()
|
|
{
|
|
/* Tear Down Routine */
|
|
unlink(CONF);
|
|
Helper::confRestore();
|
|
Helper::rmDir($this->_path);
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testCreate()
|
|
{
|
|
$options = parse_ini_file(CONF, true);
|
|
$options['traffic']['limit'] = 0;
|
|
Helper::createIniFile(CONF, $options);
|
|
$paste = Helper::getPasteJson();
|
|
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
|
file_put_contents($file, $paste);
|
|
Request::setInputStream($file);
|
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
|
$_SERVER['REMOTE_ADDR'] = '::1';
|
|
$_SERVER['REQUEST_URI'] = '/';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$response = json_decode($content, true);
|
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
|
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
|
$this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
|
|
$paste = $this->_model->read($response['id']);
|
|
$this->assertEquals(
|
|
hash_hmac('sha256', $response['id'], $paste['meta']['salt']),
|
|
$response['deletetoken'],
|
|
'outputs valid delete token'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testPut()
|
|
{
|
|
$options = parse_ini_file(CONF, true);
|
|
$options['traffic']['limit'] = 0;
|
|
Helper::createIniFile(CONF, $options);
|
|
$paste = Helper::getPasteJson();
|
|
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
|
file_put_contents($file, $paste);
|
|
Request::setInputStream($file);
|
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
|
$_GET[Helper::getPasteId()] = '';
|
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
|
$_SERVER['REQUEST_METHOD'] = 'PUT';
|
|
$_SERVER['REMOTE_ADDR'] = '::1';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
unlink($file);
|
|
$response = json_decode($content, true);
|
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
|
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputted paste ID matches input');
|
|
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
|
$this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
|
|
$paste = $this->_model->read($response['id']);
|
|
$this->assertEquals(
|
|
hash_hmac('sha256', $response['id'], $paste['meta']['salt']),
|
|
$response['deletetoken'],
|
|
'outputs valid delete token'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testDelete()
|
|
{
|
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
|
$paste = $this->_model->read(Helper::getPasteId());
|
|
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
|
file_put_contents($file, json_encode(array(
|
|
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste['meta']['salt']),
|
|
)));
|
|
Request::setInputStream($file);
|
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
|
$_GET[Helper::getPasteId()] = '';
|
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
|
$_SERVER['REQUEST_METHOD'] = 'DELETE';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
unlink($file);
|
|
$response = json_decode($content, true);
|
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
|
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testDeleteWithPost()
|
|
{
|
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
|
$paste = $this->_model->read(Helper::getPasteId());
|
|
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
|
file_put_contents($file, json_encode(array(
|
|
'pasteid' => Helper::getPasteId(),
|
|
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste['meta']['salt']),
|
|
)));
|
|
Request::setInputStream($file);
|
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$response = json_decode($content, true);
|
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
|
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testRead()
|
|
{
|
|
$paste = Helper::getPaste();
|
|
$this->_model->create(Helper::getPasteId(), $paste);
|
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
|
$_GET[Helper::getPasteId()] = '';
|
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$response = json_decode($content, true);
|
|
$this->assertEquals(0, $response['status'], 'outputs success status');
|
|
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputs data correctly');
|
|
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
|
$this->assertEquals($paste['ct'], $response['ct'], 'outputs data correctly');
|
|
$this->assertEquals($paste['meta']['created'], $response['meta']['created'], 'outputs postdate correctly');
|
|
$this->assertEquals(0, $response['comment_count'], 'outputs comment_count correctly');
|
|
$this->assertEquals(0, $response['comment_offset'], 'outputs comment_offset correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testJsonLdPaste()
|
|
{
|
|
$_GET['jsonld'] = 'paste';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertEquals(str_replace(
|
|
'?jsonld=',
|
|
'/?jsonld=',
|
|
file_get_contents(PUBLIC_PATH . '/js/paste.jsonld')
|
|
), $content, 'outputs data correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testJsonLdComment()
|
|
{
|
|
$_GET['jsonld'] = 'comment';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertEquals(str_replace(
|
|
'?jsonld=',
|
|
'/?jsonld=',
|
|
file_get_contents(PUBLIC_PATH . '/js/comment.jsonld')
|
|
), $content, 'outputs data correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testJsonLdPasteMeta()
|
|
{
|
|
$_GET['jsonld'] = 'pastemeta';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertEquals(str_replace(
|
|
'?jsonld=',
|
|
'/?jsonld=',
|
|
file_get_contents(PUBLIC_PATH . '/js/pastemeta.jsonld')
|
|
), $content, 'outputs data correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testJsonLdCommentMeta()
|
|
{
|
|
$_GET['jsonld'] = 'commentmeta';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertEquals(str_replace(
|
|
'?jsonld=',
|
|
'/?jsonld=',
|
|
file_get_contents(PUBLIC_PATH . '/js/commentmeta.jsonld')
|
|
), $content, 'outputs data correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testJsonLdInvalid()
|
|
{
|
|
$_GET['jsonld'] = CONF;
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertEquals('{}', $content, 'does not output nasty data');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testShortenViaYourls()
|
|
{
|
|
$mock_yourls_service = $this->_path . DIRECTORY_SEPARATOR . 'yourls.json';
|
|
$options = parse_ini_file(CONF, true);
|
|
$options['main']['basepath'] = 'https://example.com/path';
|
|
$options['main']['urlshortener'] = 'https://example.com/path/shortenviayourls?link=';
|
|
$options['yourls']['apiurl'] = $mock_yourls_service;
|
|
Helper::createIniFile(CONF, $options);
|
|
|
|
// the real service answer is more complex, but we only look for the shorturl & statusCode
|
|
file_put_contents($mock_yourls_service, '{"shorturl":"https:\/\/example.com\/1","statusCode":200}');
|
|
|
|
$_SERVER['REQUEST_URI'] = '/path/shortenviayourls?link=https%3A%2F%2Fexample.com%2Fpath%2F%3Ffoo%23bar';
|
|
$_GET['link'] = 'https://example.com/path/?foo#bar';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertContains('id="pasteurl" href="https://example.com/1"', $content, 'outputs shortened URL correctly');
|
|
}
|
|
|
|
/**
|
|
* @runInSeparateProcess
|
|
*/
|
|
public function testShortenViaYourlsFailure()
|
|
{
|
|
$_SERVER['REQUEST_URI'] = '/path/shortenviayourls?link=https%3A%2F%2Fexample.com%2Fpath%2F%3Ffoo%23bar';
|
|
$_GET['link'] = 'https://example.com/path/?foo#bar';
|
|
ob_start();
|
|
new Controller;
|
|
$content = ob_get_contents();
|
|
ob_end_clean();
|
|
$this->assertContains('Error calling YOURLS.', $content, 'outputs error correctly');
|
|
}
|
|
}
|