Merge branch 'master' into php8
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Google\Cloud\Core\Exception\BadRequestException;
|
||||
use Google\Cloud\Core\Exception\NotFoundException;
|
||||
use Google\Cloud\Storage\Bucket;
|
||||
use Google\Cloud\Storage\Connection\ConnectionInterface;
|
||||
use Google\Cloud\Storage\StorageClient;
|
||||
use Google\Cloud\Storage\StorageObject;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
@@ -21,6 +27,586 @@ if (!defined('CONF_SAMPLE')) {
|
||||
require PATH . 'vendor/autoload.php';
|
||||
Helper::updateSubresourceIntegrity();
|
||||
|
||||
/**
|
||||
* Class StorageClientStub provides a limited stub for performing the unit test
|
||||
*/
|
||||
class StorageClientStub extends StorageClient
|
||||
{
|
||||
private $_config = null;
|
||||
private $_connection = null;
|
||||
private $_buckets = array();
|
||||
|
||||
public function __construct(array $config = array())
|
||||
{
|
||||
$this->_config = $config;
|
||||
$this->_connection = new ConnectionInterfaceStub();
|
||||
}
|
||||
|
||||
public function bucket($name, $userProject = false)
|
||||
{
|
||||
if (!key_exists($name, $this->_buckets)) {
|
||||
$b = new BucketStub($this->_connection, $name, array(), $this);
|
||||
$this->_buckets[$name] = $b;
|
||||
}
|
||||
return $this->_buckets[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Google\Cloud\Core\Exception\NotFoundException
|
||||
*/
|
||||
public function deleteBucket($name)
|
||||
{
|
||||
if (key_exists($name, $this->_buckets)) {
|
||||
unset($this->_buckets[$name]);
|
||||
} else {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
public function buckets(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function registerStreamWrapper($protocol = null)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function unregisterStreamWrapper($protocol = null)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function signedUrlUploader($uri, $data, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function timestamp(\DateTimeInterface $timestamp, $nanoSeconds = null)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getServiceAccount(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function hmacKeys(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function hmacKey($accessId, $projectId = null, array $metadata = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function createHmacKey($serviceAccountEmail, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function createBucket($name, array $options = array())
|
||||
{
|
||||
if (key_exists($name, $this->_buckets)) {
|
||||
throw new BadRequestException('already exists');
|
||||
}
|
||||
$b = new BucketStub($this->_connection, $name, array(), $this);
|
||||
$this->_buckets[$name] = $b;
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class BucketStub stubs a GCS bucket.
|
||||
*/
|
||||
class BucketStub extends Bucket
|
||||
{
|
||||
public $_objects;
|
||||
private $_name;
|
||||
private $_info;
|
||||
private $_connection;
|
||||
private $_client;
|
||||
|
||||
public function __construct(ConnectionInterface $connection, $name, array $info = array(), $client = null)
|
||||
{
|
||||
$this->_name = $name;
|
||||
$this->_info = $info;
|
||||
$this->_connection = $connection;
|
||||
$this->_objects = array();
|
||||
$this->_client = $client;
|
||||
}
|
||||
|
||||
public function acl()
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function defaultAcl()
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function exists()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function upload($data, array $options = array())
|
||||
{
|
||||
if (!is_string($data) || !key_exists('name', $options)) {
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
$name = $options['name'];
|
||||
$generation = '1';
|
||||
$o = new StorageObjectStub($this->_connection, $name, $this, $generation, $options);
|
||||
$this->_objects[$options['name']] = $o;
|
||||
$o->setData($data);
|
||||
}
|
||||
|
||||
public function uploadAsync($data, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getResumableUploader($data, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getStreamableUploader($data, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function object($name, array $options = array())
|
||||
{
|
||||
if (key_exists($name, $this->_objects)) {
|
||||
return $this->_objects[$name];
|
||||
} else {
|
||||
return new StorageObjectStub($this->_connection, $name, $this, null, $options);
|
||||
}
|
||||
}
|
||||
|
||||
public function objects(array $options = array())
|
||||
{
|
||||
$prefix = key_exists('prefix', $options) ? $options['prefix'] : '';
|
||||
|
||||
return new CallbackFilterIterator(
|
||||
new ArrayIterator($this->_objects),
|
||||
function ($current, $key, $iterator) use ($prefix) {
|
||||
return substr($key, 0, strlen($prefix)) == $prefix;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function createNotification($topic, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function notification($id)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function notifications(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function delete(array $options = array())
|
||||
{
|
||||
$this->_client->deleteBucket($this->_name);
|
||||
}
|
||||
|
||||
public function update(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function compose(array $sourceObjects, $name, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function info(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function reload(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function name()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
public static function lifecycle(array $lifecycle = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function currentLifecycle(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function isWritable($file = null)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function iam()
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function lockRetentionPolicy(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function signedUrl($expires, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function generateSignedPostPolicyV4($objectName, $expires, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class StorageObjectStub stubs a GCS storage object.
|
||||
*/
|
||||
class StorageObjectStub extends StorageObject
|
||||
{
|
||||
private $_name;
|
||||
private $_data;
|
||||
private $_info;
|
||||
private $_bucket;
|
||||
private $_generation;
|
||||
private $_exists = false;
|
||||
private $_connection;
|
||||
|
||||
public function __construct(ConnectionInterface $connection, $name, $bucket, $generation = null, array $info = array(), $encryptionKey = null, $encryptionKeySHA256 = null)
|
||||
{
|
||||
$this->_name = $name;
|
||||
$this->_bucket = $bucket;
|
||||
$this->_generation = $generation;
|
||||
$this->_info = $info;
|
||||
$this->_connection = $connection;
|
||||
$timeCreated = new Datetime();
|
||||
$this->_info['metadata']['timeCreated'] = $timeCreated->format('Y-m-d\TH:i:s.u\Z');
|
||||
}
|
||||
|
||||
public function acl()
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function exists(array $options = array())
|
||||
{
|
||||
return key_exists($this->_name, $this->_bucket->_objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function delete(array $options = array())
|
||||
{
|
||||
if (key_exists($this->_name, $this->_bucket->_objects)) {
|
||||
unset($this->_bucket->_objects[$this->_name]);
|
||||
} else {
|
||||
throw new NotFoundException('key ' . $this->_name . ' not found.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function update(array $metadata, array $options = array())
|
||||
{
|
||||
if (!$this->_exists) {
|
||||
throw new NotFoundException('key ' . $this->_name . ' not found.');
|
||||
}
|
||||
$this->_info = $metadata;
|
||||
}
|
||||
|
||||
public function copy($destination, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function rewrite($destination, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function rename($name, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function downloadAsString(array $options = array())
|
||||
{
|
||||
if (!$this->_exists) {
|
||||
throw new NotFoundException('key ' . $this->_name . ' not found.');
|
||||
}
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
public function downloadToFile($path, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function downloadAsStream(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function downloadAsStreamAsync(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function signedUrl($expires, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function signedUploadUrl($expires, array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function beginSignedUploadSession(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function info(array $options = array())
|
||||
{
|
||||
return key_exists('metadata',$this->_info) ? $this->_info['metadata'] : array();
|
||||
}
|
||||
|
||||
public function reload(array $options = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function name()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
public function identity()
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function gcsUri()
|
||||
{
|
||||
return sprintf(
|
||||
'gs://%s/%s',
|
||||
$this->_bucket->name(),
|
||||
$this->_name
|
||||
);
|
||||
}
|
||||
|
||||
public function setData($data)
|
||||
{
|
||||
$this->_data = $data;
|
||||
$this->_exists = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class ConnectionInterfaceStub required for the stubs.
|
||||
*/
|
||||
class ConnectionInterfaceStub implements ConnectionInterface
|
||||
{
|
||||
public function deleteAcl(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getAcl(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function listAcl(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function insertAcl(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function patchAcl(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function deleteBucket(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getBucket(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function listBuckets(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function insertBucket(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getBucketIamPolicy(array $args)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function setBucketIamPolicy(array $args)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function testBucketIamPermissions(array $args)
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function patchBucket(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function deleteObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function copyObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function rewriteObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function composeObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function listObjects(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function patchObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function downloadObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function insertObject(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getNotification(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function deleteNotification(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function insertNotification(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function listNotifications(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getServiceAccount(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function lockRetentionPolicy(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function createHmacKey(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function deleteHmacKey(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function getHmacKey(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function updateHmacKey(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
|
||||
public function listHmacKeys(array $args = array())
|
||||
{
|
||||
throw new BadMethodCallException('not supported by this stub');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Helper provides unit tests pastes and comments of various formats
|
||||
*/
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
@@ -155,7 +741,11 @@ class Helper
|
||||
public static function getPastePost($version = 2, array $meta = array())
|
||||
{
|
||||
$example = self::getPaste($version, $meta);
|
||||
$example['meta'] = array('expire' => $example['meta']['expire']);
|
||||
if ($version == 2) {
|
||||
$example['meta'] = array('expire' => $example['meta']['expire']);
|
||||
} else {
|
||||
unset($example['meta']['postdate']);
|
||||
}
|
||||
return $example;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ class ConfigurationTest extends TestCase
|
||||
$this->_minimalConfig = '[main]' . PHP_EOL . '[model]' . PHP_EOL . '[model_options]';
|
||||
$this->_options = Configuration::getDefaults();
|
||||
$this->_options['model_options']['dir'] = PATH . $this->_options['model_options']['dir'];
|
||||
$this->_options['traffic']['dir'] = PATH . $this->_options['traffic']['dir'];
|
||||
$this->_options['purge']['dir'] = PATH . $this->_options['purge']['dir'];
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_cfg';
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
@@ -142,44 +140,6 @@ class ConfigurationTest extends TestCase
|
||||
$this->assertEquals('Database', $conf->getKey('class', 'model'), 'old db class gets renamed');
|
||||
}
|
||||
|
||||
public function testHandleConfigFileRename()
|
||||
{
|
||||
$options = $this->_options;
|
||||
Helper::createIniFile(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample', $options);
|
||||
|
||||
$options['main']['opendiscussion'] = true;
|
||||
$options['main']['fileupload'] = true;
|
||||
$options['main']['template'] = 'darkstrap';
|
||||
Helper::createIniFile(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', $options);
|
||||
|
||||
$conf = new Configuration;
|
||||
$this->assertFileExists(CONF, 'old configuration file gets converted');
|
||||
$this->assertFileDoesNotExist(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', 'old configuration file gets removed');
|
||||
$this->assertFileDoesNotExist(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample', 'old configuration sample file gets removed');
|
||||
$this->assertTrue(
|
||||
$conf->getKey('opendiscussion') &&
|
||||
$conf->getKey('fileupload') &&
|
||||
$conf->getKey('template') === 'darkstrap',
|
||||
'configuration values get converted'
|
||||
);
|
||||
}
|
||||
|
||||
public function testRenameIniSample()
|
||||
{
|
||||
$iniSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample';
|
||||
|
||||
Helper::createIniFile(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', $this->_options);
|
||||
if (is_file(CONF)) {
|
||||
unlink(CONF);
|
||||
}
|
||||
rename(CONF_SAMPLE, $iniSample);
|
||||
new Configuration;
|
||||
$this->assertFileDoesNotExist($iniSample, 'old sample file gets removed');
|
||||
$this->assertFileExists(CONF_SAMPLE, 'new sample file gets created');
|
||||
$this->assertFileExists(CONF, 'old configuration file gets converted');
|
||||
$this->assertFileDoesNotExist(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', 'old configuration file gets removed');
|
||||
}
|
||||
|
||||
public function testConfigPath()
|
||||
{
|
||||
// setup
|
||||
@@ -199,29 +159,4 @@ class ConfigurationTest extends TestCase
|
||||
}
|
||||
putenv('CONFIG_PATH');
|
||||
}
|
||||
|
||||
public function testConfigPathIni()
|
||||
{
|
||||
// setup
|
||||
$configFile = $this->_path . DIRECTORY_SEPARATOR . 'conf.ini';
|
||||
$configMigrated = $this->_path . DIRECTORY_SEPARATOR . 'conf.php';
|
||||
$options = $this->_options;
|
||||
$options['main']['name'] = 'OtherBin';
|
||||
Helper::createIniFile($configFile, $options);
|
||||
$this->assertFileDoesNotExist(CONF, 'configuration in the default location is non existing');
|
||||
|
||||
// test
|
||||
putenv('CONFIG_PATH=' . $this->_path);
|
||||
$conf = new Configuration;
|
||||
$this->assertEquals('OtherBin', $conf->getKey('name'), 'changing config path is supported for ini files as well');
|
||||
$this->assertFileExists($configMigrated, 'old configuration file gets converted');
|
||||
$this->assertFileDoesNotExist($configFile, 'old configuration file gets removed');
|
||||
$this->assertFileDoesNotExist(CONF, 'configuration is not created in the default location');
|
||||
|
||||
// cleanup environment
|
||||
if (is_file($configFile)) {
|
||||
unlink($configFile);
|
||||
}
|
||||
putenv('CONFIG_PATH');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,8 +429,6 @@ class ConfigurationCombinationsTest extends TestCase
|
||||
Helper::confBackup();
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
ServerSalt::setPath($this->_path);
|
||||
TrafficLimiter::setPath($this->_path);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
@@ -450,8 +448,6 @@ class ConfigurationCombinationsTest extends TestCase
|
||||
if ($this->_model->exists(Helper::getPasteId()))
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$configuration['model_options']['dir'] = $this->_path;
|
||||
$configuration['traffic']['dir'] = $this->_path;
|
||||
$configuration['purge']['dir'] = $this->_path;
|
||||
Helper::createIniFile(CONF, $configuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ class ControllerTest extends TestCase
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_data = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
ServerSalt::setStore($this->_data);
|
||||
TrafficLimiter::setStore($this->_data);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
@@ -38,11 +40,8 @@ class ControllerTest extends TestCase
|
||||
$this->_data->delete(Helper::getPasteId());
|
||||
}
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['dir'] = $this->_path;
|
||||
$options['traffic']['dir'] = $this->_path;
|
||||
$options['model_options']['dir'] = $this->_path;
|
||||
Helper::createIniFile(CONF, $options);
|
||||
ServerSalt::setPath($this->_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +49,8 @@ class ControllerTest extends TestCase
|
||||
*/
|
||||
public function testView()
|
||||
{
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_GET[Helper::getPasteId()] = '';
|
||||
ob_start();
|
||||
new Controller;
|
||||
$content = ob_get_contents();
|
||||
@@ -129,27 +130,9 @@ class ControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 2
|
||||
*/
|
||||
public function testHtaccess()
|
||||
{
|
||||
$htaccess = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||
@unlink($htaccess);
|
||||
|
||||
$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';
|
||||
ob_start();
|
||||
new Controller;
|
||||
ob_end_clean();
|
||||
|
||||
$this->assertFileExists($htaccess, 'htaccess recreated');
|
||||
}
|
||||
|
||||
public function testConf()
|
||||
{
|
||||
file_put_contents(CONF, '');
|
||||
@@ -492,6 +475,29 @@ class ControllerTest extends TestCase
|
||||
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste exists after posting data');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testCreateInvalidFormat()
|
||||
{
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['traffic']['limit'] = 0;
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
||||
file_put_contents($file, Helper::getPasteJson(1));
|
||||
Request::setInputStream($file);
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new Controller;
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(1, $response['status'], 'outputs error status');
|
||||
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste exists after posting data');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
@@ -540,7 +546,7 @@ class ControllerTest extends TestCase
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(1, $response['status'], 'outputs error status');
|
||||
$this->assertFalse($this->_data->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'paste exists after posting data');
|
||||
$this->assertFalse($this->_data->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment exists after posting data');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
use PrivateBin\Data\Database;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
|
||||
require_once 'ControllerTest.php';
|
||||
|
||||
@@ -24,6 +26,8 @@ class ControllerWithDbTest extends ControllerTest
|
||||
}
|
||||
$this->_options['dsn'] = 'sqlite:' . $this->_path . DIRECTORY_SEPARATOR . 'tst.sq3';
|
||||
$this->_data = Database::getInstance($this->_options);
|
||||
ServerSalt::setStore($this->_data);
|
||||
TrafficLimiter::setStore($this->_data);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
|
||||
59
tst/ControllerWithGcsTest.php
Normal file
59
tst/ControllerWithGcsTest.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
use Google\Auth\HttpHandler\HttpHandlerFactory;
|
||||
use GuzzleHttp\Client;
|
||||
use PrivateBin\Data\GoogleCloudStorage;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
|
||||
require_once 'ControllerTest.php';
|
||||
|
||||
class ControllerWithGcsTest extends ControllerTest
|
||||
{
|
||||
private static $_client;
|
||||
private static $_bucket;
|
||||
private $_options = array();
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
$httpClient = new Client(array('debug'=>false));
|
||||
$handler = HttpHandlerFactory::build($httpClient);
|
||||
|
||||
$name = 'pb-';
|
||||
$alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
||||
for ($i = 0; $i < 29; ++$i) {
|
||||
$name .= $alphabet[rand(0, strlen($alphabet) - 1)];
|
||||
}
|
||||
self::$_client = new StorageClientStub(array());
|
||||
self::$_bucket = self::$_client->createBucket($name);
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
$this->_options = array(
|
||||
'bucket' => self::$_bucket->name(),
|
||||
'prefix' => 'pastes',
|
||||
);
|
||||
$this->_data = GoogleCloudStorage::getInstance($this->_options);
|
||||
ServerSalt::setStore($this->_data);
|
||||
TrafficLimiter::setStore($this->_data);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
// but then inject a db config
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['model'] = array(
|
||||
'class' => 'GoogleCloudStorage',
|
||||
);
|
||||
$options['model_options'] = $this->_options;
|
||||
Helper::createIniFile(CONF, $options);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PrivateBin\Controller;
|
||||
use PrivateBin\Data\Database;
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
|
||||
class DatabaseTest extends TestCase
|
||||
{
|
||||
@@ -32,6 +34,19 @@ class DatabaseTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testSaltMigration()
|
||||
{
|
||||
ServerSalt::setStore(Filesystem::getInstance(array('dir' => 'data')));
|
||||
$salt = ServerSalt::get();
|
||||
$file = 'data' . DIRECTORY_SEPARATOR . 'salt.php';
|
||||
$this->assertFileExists($file, 'ServerSalt got initialized and stored on disk');
|
||||
$this->assertNotEquals($salt, '');
|
||||
ServerSalt::setStore($this->_model);
|
||||
ServerSalt::get();
|
||||
$this->assertFileNotExists($file, 'legacy ServerSalt got removed');
|
||||
$this->assertEquals($salt, ServerSalt::get(), 'ServerSalt got preserved & migrated');
|
||||
}
|
||||
|
||||
public function testDatabaseBasedDataStoreWorks()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
@@ -266,6 +281,48 @@ class DatabaseTest extends TestCase
|
||||
Helper::rmDir($this->_path);
|
||||
}
|
||||
|
||||
public function testCorruptMeta()
|
||||
{
|
||||
mkdir($this->_path);
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'meta-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$this->_options['dsn'] = 'sqlite:' . $path;
|
||||
$this->_options['tbl'] = 'baz_';
|
||||
$model = Database::getInstance($this->_options);
|
||||
$paste = Helper::getPaste(1, array('expire_date' => 1344803344));
|
||||
unset($paste['meta']['formatter'], $paste['meta']['opendiscussion'], $paste['meta']['salt']);
|
||||
$model->delete(Helper::getPasteId());
|
||||
|
||||
$db = new PDO(
|
||||
$this->_options['dsn'],
|
||||
$this->_options['usr'],
|
||||
$this->_options['pwd'],
|
||||
$this->_options['opt']
|
||||
);
|
||||
$statement = $db->prepare('INSERT INTO baz_paste VALUES(?,?,?,?,?,?,?,?,?)');
|
||||
$statement->execute(
|
||||
array(
|
||||
Helper::getPasteId(),
|
||||
$paste['data'],
|
||||
$paste['meta']['postdate'],
|
||||
$paste['meta']['expire_date'],
|
||||
0,
|
||||
0,
|
||||
'{',
|
||||
null,
|
||||
null,
|
||||
)
|
||||
);
|
||||
$statement->closeCursor();
|
||||
|
||||
$this->assertTrue($model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
$this->assertEquals($paste, $model->read(Helper::getPasteId()));
|
||||
|
||||
Helper::rmDir($this->_path);
|
||||
}
|
||||
|
||||
public function testTableUpgrade()
|
||||
{
|
||||
mkdir($this->_path);
|
||||
|
||||
@@ -118,6 +118,7 @@ class FilesystemTest extends TestCase
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertFalse($this->_model->create(Helper::getPasteId(), $paste), 'unable to store broken paste');
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does still not exist');
|
||||
$this->assertFalse($this->_model->setValue('foo', 'non existing namespace'), 'rejects setting value in non existing namespace');
|
||||
}
|
||||
|
||||
public function testCommentErrorDetection()
|
||||
|
||||
182
tst/Data/GoogleCloudStorageTest.php
Normal file
182
tst/Data/GoogleCloudStorageTest.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
use Google\Auth\HttpHandler\HttpHandlerFactory;
|
||||
use GuzzleHttp\Client;
|
||||
use PrivateBin\Data\GoogleCloudStorage;
|
||||
|
||||
class GoogleCloudStorageTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
private static $_client;
|
||||
private static $_bucket;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
$httpClient = new Client(array('debug'=>false));
|
||||
$handler = HttpHandlerFactory::build($httpClient);
|
||||
|
||||
$name = 'pb-';
|
||||
$alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
||||
for ($i = 0; $i < 29; ++$i) {
|
||||
$name .= $alphabet[rand(0, strlen($alphabet) - 1)];
|
||||
}
|
||||
self::$_client = new StorageClientStub(array());
|
||||
self::$_bucket = self::$_client->createBucket($name);
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
ini_set('error_log', stream_get_meta_data(tmpfile())['uri']);
|
||||
$this->_model = GoogleCloudStorage::getInstance(array(
|
||||
'bucket' => self::$_bucket->name(),
|
||||
'prefix' => 'pastes',
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
foreach (self::$_bucket->objects() as $object) {
|
||||
$object->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
self::$_bucket->delete();
|
||||
}
|
||||
|
||||
public function testFileBasedDataStoreWorks()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
|
||||
// storing pastes
|
||||
$paste = Helper::getPaste(2, array('expire_date' => 1344803344));
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertTrue($this->_model->create(Helper::getPasteId(), $paste), 'store new paste');
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
$this->assertFalse($this->_model->create(Helper::getPasteId(), $paste), 'unable to store the same paste twice');
|
||||
$this->assertEquals($paste, $this->_model->read(Helper::getPasteId()));
|
||||
|
||||
// storing comments
|
||||
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does not yet exist');
|
||||
$this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()), 'store comment');
|
||||
$this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment exists after storing it');
|
||||
$this->assertFalse($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()), 'unable to store the same comment twice');
|
||||
$comment = Helper::getComment();
|
||||
$comment['id'] = Helper::getCommentId();
|
||||
$comment['parentid'] = Helper::getPasteId();
|
||||
$this->assertEquals(
|
||||
array($comment['meta']['created'] => $comment),
|
||||
$this->_model->readComments(Helper::getPasteId())
|
||||
);
|
||||
|
||||
// deleting pastes
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
||||
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment was deleted with paste');
|
||||
$this->assertFalse($this->_model->read(Helper::getPasteId()), 'paste can no longer be found');
|
||||
}
|
||||
|
||||
/**
|
||||
* pastes a-g are expired and should get deleted, x never expires and y-z expire in an hour
|
||||
*/
|
||||
public function testPurge()
|
||||
{
|
||||
$expired = Helper::getPaste(2, array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(2, array('expire_date' => time() + 3600));
|
||||
$keys = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'x', 'y', 'z');
|
||||
$ids = array();
|
||||
foreach ($keys as $key) {
|
||||
$ids[$key] = hash('fnv164', $key);
|
||||
$this->assertFalse($this->_model->exists($ids[$key]), "paste $key does not yet exist");
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $paste), "store $key paste");
|
||||
} elseif ($key === 'x') {
|
||||
$this->assertTrue($this->_model->create($ids[$key], Helper::getPaste()), "store $key paste");
|
||||
} else {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $expired), "store $key paste");
|
||||
}
|
||||
$this->assertTrue($this->_model->exists($ids[$key]), "paste $key exists after storing it");
|
||||
}
|
||||
$this->_model->purge(10);
|
||||
foreach ($ids as $key => $id) {
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
$this->assertTrue($this->_model->exists($id), "paste $key exists after purge");
|
||||
$this->_model->delete($id);
|
||||
} else {
|
||||
$this->assertFalse($this->_model->exists($id), "paste $key was purged");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testErrorDetection()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$paste = Helper::getPaste(2, array('expire' => "Invalid UTF-8 sequence: \xB1\x31"));
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertFalse($this->_model->create(Helper::getPasteId(), $paste), 'unable to store broken paste');
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does still not exist');
|
||||
}
|
||||
|
||||
public function testCommentErrorDetection()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$comment = Helper::getComment(1, array('nickname' => "Invalid UTF-8 sequence: \xB1\x31"));
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertTrue($this->_model->create(Helper::getPasteId(), Helper::getPaste()), 'store new paste');
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does not yet exist');
|
||||
$this->assertFalse($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), $comment), 'unable to store broken comment');
|
||||
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does still not exist');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testKeyValueStore()
|
||||
{
|
||||
$salt = bin2hex(random_bytes(256));
|
||||
$this->_model->setValue($salt, 'salt', '');
|
||||
$storedSalt = $this->_model->getValue('salt', '');
|
||||
$this->assertEquals($salt, $storedSalt);
|
||||
$this->_model->purgeValues('salt', time() + 60);
|
||||
$this->assertEquals('', $this->_model->getValue('salt', 'master'));
|
||||
|
||||
$client = hash_hmac('sha512', '127.0.0.1', $salt);
|
||||
$expire = time();
|
||||
$this->_model->setValue(strval($expire), 'traffic_limiter', $client);
|
||||
$storedExpired = $this->_model->getValue('traffic_limiter', $client);
|
||||
$this->assertEquals(strval($expire), $storedExpired);
|
||||
|
||||
$this->_model->purgeValues('traffic_limiter', time() - 60);
|
||||
$this->assertEquals($storedExpired, $this->_model->getValue('traffic_limiter', $client));
|
||||
$this->_model->purgeValues('traffic_limiter', time() + 60);
|
||||
$this->assertEquals('', $this->_model->getValue('traffic_limiter', $client));
|
||||
|
||||
$purgeAt = $expire + (15 * 60);
|
||||
$this->_model->setValue(strval($purgeAt), 'purge_limiter', '');
|
||||
$storedPurgedAt = $this->_model->getValue('purge_limiter', '');
|
||||
$this->assertEquals(strval($purgeAt), $storedPurgedAt);
|
||||
$this->_model->purgeValues('purge_limiter', $purgeAt + 60);
|
||||
$this->assertEquals('', $this->_model->getValue('purge_limiter', ''));
|
||||
$this->assertEquals('', $this->_model->getValue('purge_limiter', 'at'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testKeyValuePurgeTrafficLimiter()
|
||||
{
|
||||
$salt = bin2hex(random_bytes(256));
|
||||
$client = hash_hmac('sha512', '127.0.0.1', $salt);
|
||||
$expire = time();
|
||||
$this->_model->setValue(strval($expire), 'traffic_limiter', $client);
|
||||
$storedExpired = $this->_model->getValue('traffic_limiter', $client);
|
||||
$this->assertEquals(strval($expire), $storedExpired);
|
||||
|
||||
$this->_model->purgeValues('traffic_limiter', time() - 60);
|
||||
$this->assertEquals($storedExpired, $this->_model->getValue('traffic_limiter', $client));
|
||||
|
||||
$this->_model->purgeValues('traffic_limiter', time() + 60);
|
||||
$this->assertEquals('', $this->_model->getValue('traffic_limiter', $client));
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ class JsonApiTest extends TestCase
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
ServerSalt::setPath($this->_path);
|
||||
ServerSalt::setStore($this->_model);
|
||||
|
||||
$_POST = array();
|
||||
$_GET = array();
|
||||
@@ -26,8 +26,6 @@ class JsonApiTest extends TestCase
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
}
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['dir'] = $this->_path;
|
||||
$options['traffic']['dir'] = $this->_path;
|
||||
$options['model_options']['dir'] = $this->_path;
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
|
||||
@@ -26,7 +26,6 @@ class ModelTest extends TestCase
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
ServerSalt::setPath($this->_path);
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['limit'] = 0;
|
||||
$options['model'] = array(
|
||||
@@ -40,6 +39,7 @@ class ModelTest extends TestCase
|
||||
);
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
ServerSalt::setStore(Database::getInstance($options['model_options']));
|
||||
$this->_conf = new Configuration;
|
||||
$this->_model = new Model($this->_conf);
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
@@ -103,6 +103,58 @@ class ModelTest extends TestCase
|
||||
$this->assertEquals(array(), $paste->getComments(), 'comment was deleted with paste');
|
||||
}
|
||||
|
||||
public function testPasteV1()
|
||||
{
|
||||
$pasteData = Helper::getPaste(1);
|
||||
unset($pasteData['meta']['formatter']);
|
||||
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'v1-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['limit'] = 0;
|
||||
$options['model'] = array(
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
'dsn' => 'sqlite:' . $path,
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
$model->getPaste('0000000000000000')->exists(); // triggers database table creation
|
||||
$model->getPaste(Helper::getPasteId())->delete(); // deletes the cache
|
||||
|
||||
$db = new PDO(
|
||||
$options['model_options']['dsn'],
|
||||
$options['model_options']['usr'],
|
||||
$options['model_options']['pwd'],
|
||||
$options['model_options']['opt']
|
||||
);
|
||||
$statement = $db->prepare('INSERT INTO paste VALUES(?,?,?,?,?,?,?,?,?)');
|
||||
$statement->execute(
|
||||
array(
|
||||
Helper::getPasteId(),
|
||||
$pasteData['data'],
|
||||
$pasteData['meta']['postdate'],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
json_encode($pasteData['meta']),
|
||||
null,
|
||||
null,
|
||||
)
|
||||
);
|
||||
$statement->closeCursor();
|
||||
|
||||
$paste = $model->getPaste(Helper::getPasteId());
|
||||
$this->assertNotEmpty($paste->getDeleteToken(), 'excercise the condition to load the data from storage');
|
||||
$this->assertEquals('plaintext', $paste->get()['meta']['formatter'], 'paste got created with default formatter');
|
||||
}
|
||||
|
||||
public function testCommentDefaults()
|
||||
{
|
||||
$comment = new Comment(
|
||||
@@ -132,6 +184,101 @@ class ModelTest extends TestCase
|
||||
$paste->store();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 76
|
||||
*/
|
||||
public function testStoreFail()
|
||||
{
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'model-store-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['limit'] = 0;
|
||||
$options['model'] = array(
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
'dsn' => 'sqlite:' . $path,
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
|
||||
$pasteData = Helper::getPastePost();
|
||||
$model->getPaste(Helper::getPasteId())->delete();
|
||||
$model->getPaste(Helper::getPasteId())->exists();
|
||||
|
||||
$db = new PDO(
|
||||
$options['model_options']['dsn'],
|
||||
$options['model_options']['usr'],
|
||||
$options['model_options']['pwd'],
|
||||
$options['model_options']['opt']
|
||||
);
|
||||
$statement = $db->prepare('DROP TABLE paste');
|
||||
$statement->execute();
|
||||
$statement->closeCursor();
|
||||
|
||||
$paste = $model->getPaste();
|
||||
$paste->setData($pasteData);
|
||||
$paste->store();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 70
|
||||
*/
|
||||
public function testCommentStoreFail()
|
||||
{
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'model-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||
$options['purge']['limit'] = 0;
|
||||
$options['model'] = array(
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
'dsn' => 'sqlite:' . $path,
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
|
||||
$pasteData = Helper::getPastePost();
|
||||
$commentData = Helper::getCommentPost();
|
||||
$model->getPaste(Helper::getPasteId())->delete();
|
||||
|
||||
$paste = $model->getPaste();
|
||||
$paste->setData($pasteData);
|
||||
$paste->store();
|
||||
$paste->exists();
|
||||
|
||||
$db = new PDO(
|
||||
$options['model_options']['dsn'],
|
||||
$options['model_options']['usr'],
|
||||
$options['model_options']['pwd'],
|
||||
$options['model_options']['opt']
|
||||
);
|
||||
$statement = $db->prepare('DROP TABLE comment');
|
||||
$statement->execute();
|
||||
$statement->closeCursor();
|
||||
|
||||
$comment = $paste->getComment(Helper::getPasteId());
|
||||
$comment->setData($commentData);
|
||||
$comment->store();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 69
|
||||
*/
|
||||
public function testCommentDuplicate()
|
||||
{
|
||||
$pasteData = Helper::getPastePost();
|
||||
@@ -190,6 +337,22 @@ class ModelTest extends TestCase
|
||||
$paste->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 75
|
||||
*/
|
||||
public function testInvalidPasteFormat()
|
||||
{
|
||||
$pasteData = Helper::getPastePost();
|
||||
$pasteData['adata'][1] = 'format does not exist';
|
||||
$paste = $this->_model->getPaste();
|
||||
$paste->setData($pasteData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionCode 60
|
||||
*/
|
||||
public function testInvalidPasteId()
|
||||
{
|
||||
$this->expectException(Exception::class);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\PurgeLimiter;
|
||||
|
||||
class PurgeLimiterTest extends TestCase
|
||||
@@ -14,7 +15,9 @@ class PurgeLimiterTest extends TestCase
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
PurgeLimiter::setPath($this->_path);
|
||||
PurgeLimiter::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_path))
|
||||
);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
|
||||
class ServerSaltTest extends TestCase
|
||||
@@ -20,7 +21,9 @@ class ServerSaltTest extends TestCase
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
ServerSalt::setPath($this->_path);
|
||||
ServerSalt::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_path))
|
||||
);
|
||||
|
||||
$this->_otherPath = $this->_path . DIRECTORY_SEPARATOR . 'foo';
|
||||
|
||||
@@ -41,13 +44,19 @@ class ServerSaltTest extends TestCase
|
||||
public function testGeneration()
|
||||
{
|
||||
// generating new salt
|
||||
ServerSalt::setPath($this->_path);
|
||||
ServerSalt::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_path))
|
||||
);
|
||||
$salt = ServerSalt::get();
|
||||
|
||||
// try setting a different path and resetting it
|
||||
ServerSalt::setPath($this->_otherPath);
|
||||
ServerSalt::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_otherPath))
|
||||
);
|
||||
$this->assertNotEquals($salt, ServerSalt::get());
|
||||
ServerSalt::setPath($this->_path);
|
||||
ServerSalt::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_path))
|
||||
);
|
||||
$this->assertEquals($salt, ServerSalt::get());
|
||||
}
|
||||
|
||||
@@ -55,10 +64,11 @@ class ServerSaltTest extends TestCase
|
||||
{
|
||||
// try setting an invalid path
|
||||
chmod($this->_invalidPath, 0000);
|
||||
ServerSalt::setPath($this->_invalidPath);
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(11);
|
||||
ServerSalt::get();
|
||||
$store = Filesystem::getInstance(array('dir' => $this->_invalidPath));
|
||||
ServerSalt::setStore($store);
|
||||
$salt = ServerSalt::get();
|
||||
ServerSalt::setStore($store);
|
||||
$this->assertNotEquals($salt, ServerSalt::get());
|
||||
}
|
||||
|
||||
public function testFileRead()
|
||||
@@ -67,10 +77,11 @@ class ServerSaltTest extends TestCase
|
||||
chmod($this->_invalidPath, 0700);
|
||||
file_put_contents($this->_invalidFile, '');
|
||||
chmod($this->_invalidFile, 0000);
|
||||
ServerSalt::setPath($this->_invalidPath);
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(20);
|
||||
ServerSalt::get();
|
||||
$store = Filesystem::getInstance(array('dir' => $this->_invalidPath));
|
||||
ServerSalt::setStore($store);
|
||||
$salt = ServerSalt::get();
|
||||
ServerSalt::setStore($store);
|
||||
$this->assertNotEquals($salt, ServerSalt::get());
|
||||
}
|
||||
|
||||
public function testFileWrite()
|
||||
@@ -83,19 +94,24 @@ class ServerSaltTest extends TestCase
|
||||
}
|
||||
file_put_contents($this->_invalidPath . DIRECTORY_SEPARATOR . '.htaccess', '');
|
||||
chmod($this->_invalidPath, 0500);
|
||||
ServerSalt::setPath($this->_invalidPath);
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(13);
|
||||
ServerSalt::get();
|
||||
$store = Filesystem::getInstance(array('dir' => $this->_invalidPath));
|
||||
ServerSalt::setStore($store);
|
||||
$salt = ServerSalt::get();
|
||||
ServerSalt::setStore($store);
|
||||
$this->assertNotEquals($salt, ServerSalt::get());
|
||||
}
|
||||
|
||||
public function testPermissionShenanigans()
|
||||
{
|
||||
// try creating an invalid path
|
||||
chmod($this->_invalidPath, 0000);
|
||||
ServerSalt::setPath($this->_invalidPath . DIRECTORY_SEPARATOR . 'baz');
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(10);
|
||||
ServerSalt::get();
|
||||
ServerSalt::setStore(
|
||||
Filesystem::getInstance(array('dir' => $this->_invalidPath . DIRECTORY_SEPARATOR . 'baz'))
|
||||
);
|
||||
$store = Filesystem::getInstance(array('dir' => $this->_invalidPath));
|
||||
ServerSalt::setStore($store);
|
||||
$salt = ServerSalt::get();
|
||||
ServerSalt::setStore($store);
|
||||
$this->assertNotEquals($salt, ServerSalt::get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
|
||||
class TrafficLimiterTest extends TestCase
|
||||
@@ -11,7 +13,9 @@ class TrafficLimiterTest extends TestCase
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'trafficlimit';
|
||||
TrafficLimiter::setPath($this->_path);
|
||||
$store = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
ServerSalt::setStore($store);
|
||||
TrafficLimiter::setStore($store);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
@@ -20,11 +24,17 @@ class TrafficLimiterTest extends TestCase
|
||||
Helper::rmDir($this->_path . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public function testHtaccess()
|
||||
{
|
||||
$htaccess = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||
@unlink($htaccess);
|
||||
$_SERVER['REMOTE_ADDR'] = 'foobar';
|
||||
TrafficLimiter::canPass();
|
||||
$this->assertFileExists($htaccess, 'htaccess recreated');
|
||||
}
|
||||
|
||||
public function testTrafficGetsLimited()
|
||||
{
|
||||
$this->assertEquals($this->_path, TrafficLimiter::getPath());
|
||||
$file = 'baz';
|
||||
$this->assertEquals($this->_path . DIRECTORY_SEPARATOR . $file, TrafficLimiter::getPath($file));
|
||||
TrafficLimiter::setLimit(4);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
|
||||
@@ -36,5 +46,20 @@ class TrafficLimiterTest extends TestCase
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass');
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$this->assertFalse(TrafficLimiter::canPass(), 'fifth request is to fast, may not pass');
|
||||
|
||||
// exempted IPs configuration
|
||||
TrafficLimiter::setExemptedIp('1.2.3.4,10.10.10.0/24,2001:1620:2057::/48');
|
||||
$this->assertFalse(TrafficLimiter::canPass(), 'still too fast and not exempted');
|
||||
$_SERVER['REMOTE_ADDR'] = '10.10.10.10';
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in exempted range');
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv4 in exempted range');
|
||||
$_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in exempted range');
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv6 in exempted range');
|
||||
TrafficLimiter::setExemptedIp('127.*,foobar');
|
||||
$this->assertFalse(TrafficLimiter::canPass(), 'request is to fast, invalid range');
|
||||
$_SERVER['REMOTE_ADDR'] = 'foobar';
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but non-IP address matches exempted range');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ class ViewTest extends TestCase
|
||||
$page->assign('PASSWORD', true);
|
||||
$page->assign('FILEUPLOAD', false);
|
||||
$page->assign('ZEROBINCOMPATIBILITY', false);
|
||||
$page->assign('INFO', 'example');
|
||||
$page->assign('NOTICE', 'example');
|
||||
$page->assign('LANGUAGESELECTION', '');
|
||||
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Vizhash16x16;
|
||||
|
||||
@@ -18,7 +19,7 @@ class Vizhash16x16Test extends TestCase
|
||||
mkdir($this->_path);
|
||||
}
|
||||
$this->_file = $this->_path . DIRECTORY_SEPARATOR . 'vizhash.png';
|
||||
ServerSalt::setPath($this->_path);
|
||||
ServerSalt::setStore(Filesystem::getInstance(array('dir' => $this->_path)));
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
|
||||
Reference in New Issue
Block a user