Refactoring storage access
Added checks during installation phase
This commit is contained in:
parent
535fce4f8f
commit
da437a203b
11 changed files with 75 additions and 57 deletions
|
@ -32,15 +32,6 @@ abstract class Controller
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a filesystem instance
|
||||
* @return Filesystem
|
||||
*/
|
||||
protected function getStorage(): Filesystem
|
||||
{
|
||||
return new Filesystem(new Local($this->settings['storage_dir']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return int
|
||||
|
@ -51,7 +42,7 @@ abstract class Controller
|
|||
|
||||
$totalSize = 0;
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
$filesystem = storage();
|
||||
foreach ($medias as $media) {
|
||||
try {
|
||||
$totalSize += $filesystem->getSize($media->storage_path);
|
||||
|
|
|
@ -49,7 +49,7 @@ class DashboardController extends Controller
|
|||
$pages = $this->database->query('SELECT COUNT(*) AS `count` FROM `uploads` WHERE `user_id` = ?', Session::get('user_id'))->fetch()->count / self::PER_PAGE;
|
||||
}
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
$filesystem = storage();
|
||||
|
||||
foreach ($medias as $media) {
|
||||
$extension = pathinfo($media->filename, PATHINFO_EXTENSION);
|
||||
|
@ -91,7 +91,7 @@ class DashboardController extends Controller
|
|||
|
||||
$totalSize = 0;
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
$filesystem = storage();
|
||||
foreach ($medias as $media) {
|
||||
$totalSize += $filesystem->getSize($media->storage_path);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class UploadController extends Controller
|
|||
$fileInfo = pathinfo($file->getClientFilename());
|
||||
$storagePath = "$user->user_code/$code.$fileInfo[extension]";
|
||||
|
||||
$this->getStorage()->writeStream($storagePath, $file->getStream()->detach());
|
||||
storage()->writeStream($storagePath, $file->getStream()->detach());
|
||||
|
||||
$this->database->query('INSERT INTO `uploads`(`user_id`, `code`, `filename`, `storage_path`) VALUES (?, ?, ?, ?)', [
|
||||
$user->id,
|
||||
|
@ -88,12 +88,10 @@ class UploadController extends Controller
|
|||
throw new NotFoundException($request, $response);
|
||||
}
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
|
||||
if (isBot($request->getHeaderLine('User-Agent'))) {
|
||||
return $this->streamMedia($request, $response, $filesystem, $media);
|
||||
return $this->streamMedia($request, $response, storage(), $media);
|
||||
} else {
|
||||
|
||||
$filesystem = storage();
|
||||
try {
|
||||
$media->mimetype = $filesystem->getMimetype($media->storage_path);
|
||||
$media->size = humanFileSize($filesystem->getSize($media->storage_path));
|
||||
|
@ -152,9 +150,8 @@ class UploadController extends Controller
|
|||
|
||||
if (Session::get('admin', false) || $user->id === $media->user_id) {
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
try {
|
||||
$filesystem->delete($media->storage_path);
|
||||
storage()->delete($media->storage_path);
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new NotFoundException($request, $response);
|
||||
} finally {
|
||||
|
@ -185,7 +182,7 @@ class UploadController extends Controller
|
|||
throw new NotFoundException($request, $response);
|
||||
}
|
||||
|
||||
return $this->streamMedia($request, $response, $this->getStorage(), $media);
|
||||
return $this->streamMedia($request, $response, storage(), $media);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,7 +200,7 @@ class UploadController extends Controller
|
|||
if (!$media || !$media->published && Session::get('user_id') !== $media->user_id && !Session::get('admin', false)) {
|
||||
throw new NotFoundException($request, $response);
|
||||
}
|
||||
return $this->streamMedia($request, $response, $this->getStorage(), $media);
|
||||
return $this->streamMedia($request, $response, storage(), $media);
|
||||
}
|
||||
|
||||
|
||||
|
@ -222,7 +219,7 @@ class UploadController extends Controller
|
|||
if (!$media || !$media->published && Session::get('user_id') !== $media->user_id && !Session::get('admin', false)) {
|
||||
throw new NotFoundException($request, $response);
|
||||
}
|
||||
return $this->streamMedia($request, $response, $this->getStorage(), $media, 'attachment');
|
||||
return $this->streamMedia($request, $response, storage(), $media, 'attachment');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,9 +264,8 @@ class UploadController extends Controller
|
|||
|
||||
if (Session::get('admin', false) || $media->user_id === Session::get('user_id')) {
|
||||
|
||||
$filesystem = $this->getStorage();
|
||||
try {
|
||||
$filesystem->delete($media->storage_path);
|
||||
storage()->delete($media->storage_path);
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new NotFoundException($request, $response);
|
||||
} finally {
|
||||
|
|
|
@ -90,7 +90,7 @@ class Session
|
|||
*/
|
||||
public static function alert($message, string $type = 'info'): void
|
||||
{
|
||||
$_SESSION['_flash'] = [$type => $message];
|
||||
$_SESSION['_flash'][] = [$type => $message];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
<?php
|
||||
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Filesystem;
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!function_exists('storage')) {
|
||||
/**
|
||||
* Get a filesystem instance given a path
|
||||
* @param string $root
|
||||
* @return Filesystem
|
||||
*/
|
||||
function storage($root = null): Filesystem
|
||||
{
|
||||
global $app;
|
||||
$storagePath = $app->getContainer()->get('settings')['storage_dir'];
|
||||
return new Filesystem(new Local($root !== null ? $root : $storagePath));
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('humanFileSize')) {
|
||||
/**
|
||||
* Generate a human readable file size
|
||||
|
@ -61,7 +78,7 @@ if (!function_exists('redirect')) {
|
|||
*/
|
||||
function redirect(\Slim\Http\Response $response, string $path, $args = [], $status = null)
|
||||
{
|
||||
if ($path === '/' || substr($path, 0, 1) === '/') {
|
||||
if ($path === '/' || $path === './' || substr($path, 0, 1) === '/') {
|
||||
$url = urlFor($path);
|
||||
} else {
|
||||
$url = route($path, $args);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "sergix44/xbackbone",
|
||||
"version": "2.3",
|
||||
"version": "2.3.1",
|
||||
"description": "A lightweight ShareX PHP backend",
|
||||
"type": "project",
|
||||
"require": {
|
||||
|
|
12
composer.lock
generated
12
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b7bca0067b8963611274642752122ecb",
|
||||
"content-hash": "265c1ca72d526b36b50fcec633b5807f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
|
@ -39,16 +39,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "53662d6688033a5eccde987bdd5a4a98ebe2d952"
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/53662d6688033a5eccde987bdd5a4a98ebe2d952",
|
||||
"reference": "53662d6688033a5eccde987bdd5a4a98ebe2d952",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
|
||||
"reference": "9f83dded91781a01c63574e387eaa769be769115",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -102,7 +102,7 @@
|
|||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2018-12-03T05:07:51+00:00"
|
||||
"time": "2018-12-04T20:46:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "intervention/image",
|
||||
|
|
|
@ -113,6 +113,18 @@ $app = new App($container);
|
|||
|
||||
$app->get('/', function (Request $request, Response $response) {
|
||||
|
||||
if (!is_writable(__DIR__ . '/../resources/cache')) {
|
||||
Session::alert('The cache folder is not writable (' . __DIR__ . '/../resources/cache' . ')', 'danger');
|
||||
}
|
||||
|
||||
if (!is_writable(__DIR__ . '/../resources/database')) {
|
||||
Session::alert('The database folder is not writable (' . __DIR__ . '/../resources/database' . ')', 'danger');
|
||||
}
|
||||
|
||||
if (!is_writable(__DIR__ . '/../resources/sessions')) {
|
||||
Session::alert('The sessions folder is not writable (' . __DIR__ . '/../resources/sessions' . ')', 'danger');
|
||||
}
|
||||
|
||||
$installed = file_exists(__DIR__ . '/../config.php');
|
||||
|
||||
return $this->view->render($response, 'install.twig', ['installed' => $installed]);
|
||||
|
@ -131,15 +143,22 @@ $app->post('/', function (Request $request, Response $response) use (&$config) {
|
|||
$config['db']['username'] = $request->getParam('db_user');
|
||||
$config['db']['password'] = $request->getParam('db_password');
|
||||
|
||||
if (!is_writable($config['storage_dir'])) {
|
||||
Session::alert('The storage folder is not writable (' . $config['storage_dir'] . ')', 'danger');
|
||||
return redirect($response, '.');
|
||||
try {
|
||||
storage($config['storage_dir']);
|
||||
} catch (LogicException $exception) {
|
||||
Session::alert('The storage folder is not readable (' . $config['storage_dir'] . ')', 'danger');
|
||||
return redirect($response, './');
|
||||
} finally {
|
||||
if (!is_writable($config['storage_dir'])) {
|
||||
Session::alert('The storage folder is not writable (' . $config['storage_dir'] . ')', 'danger');
|
||||
return redirect($response, './');
|
||||
}
|
||||
}
|
||||
|
||||
$ret = file_put_contents(__DIR__ . '/../config.php', '<?php' . PHP_EOL . 'return ' . var_export($config, true) . ';');
|
||||
if ($ret === false) {
|
||||
Session::alert('The config folder is not writable (' . __DIR__ . '/../config.php' . ')', 'danger');
|
||||
return redirect($response, '.');
|
||||
return redirect($response, './');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +170,7 @@ $app->post('/', function (Request $request, Response $response) use (&$config) {
|
|||
migrate($config);
|
||||
} catch (PDOException $exception) {
|
||||
Session::alert("Cannot connect to the database: {$exception->getMessage()} [{$exception->getCode()}]", 'danger');
|
||||
return redirect($response, '.');
|
||||
return redirect($response, './');
|
||||
}
|
||||
|
||||
if (!$installed) {
|
||||
|
|
|
@ -19,14 +19,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{% for type, message in alerts %}
|
||||
<div class="alert alert-{{ type }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% include 'comp/alert.twig' %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card mt-3">
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
"devDependencies": {
|
||||
"grunt": "^1.0",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-contrib-cssmin": "^2.2.1",
|
||||
"grunt-contrib-jshint": "^1.1.0",
|
||||
"grunt-contrib-uglify": "^3.3.0",
|
||||
"grunt-contrib-cssmin": "^3.0.0",
|
||||
"grunt-contrib-jshint": "^2.0.0",
|
||||
"grunt-contrib-uglify": "^4.0.0",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
"grunt-zip": "^0.17.1",
|
||||
"grunt-zip": "^0.18.1",
|
||||
"load-grunt-tasks": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{% for type, message in alerts %}
|
||||
<div class="alert alert-{{ type }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% for alert in alerts %}
|
||||
{% for type, message in alert %}
|
||||
<div class="alert alert-{{ type }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
Loading…
Reference in a new issue