Merge pull request #1 from axeloz/dev

Merging to master
This commit is contained in:
Axel 2017-07-26 15:04:42 +02:00 committed by GitHub
commit 00781793f3
5 changed files with 105 additions and 44 deletions

View file

@ -2,11 +2,16 @@
namespace app\Helpers; namespace app\Helpers;
use Exception;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
class Upload { class Upload {
public static function generateFilePath(string $token) { public static function generateFilePath(string $token) {
if (strlen($token) < 5) {
throw new Exception('Invalid token');
}
$path = 'files/'; $path = 'files/';
for ($i = 0; $i < 3; $i++) { for ($i = 0; $i < 3; $i++) {
$letter = substr($token, $i, 1); $letter = substr($token, $i, 1);
@ -33,7 +38,7 @@ class Upload {
return false; return false;
} }
public static function humanFilesize(float $size, $precision = 2) public static function humanFilesize($size, $precision = 2)
{ {
if ($size > 0) { if ($size > 0) {
$size = (int) $size; $size = (int) $size;
@ -152,10 +157,10 @@ class Upload {
// A-B format // A-B format
if (strpos($range, '-') !== false) { if (strpos($range, '-') !== false) {
list($lower, $upper) = explode('-', $range, 2); list($lower, $upper) = explode('-', $range, 2);
$lower_dec = (float)sprintf("%u",ip2long($lower)); $lower_dec = (float)sprintf("%u", ip2long($lower));
$upper_dec = (float)sprintf("%u",ip2long($upper)); $upper_dec = (float)sprintf("%u", ip2long($upper));
$ip_dec = (float)sprintf("%u",ip2long($ip)); $ip_dec = (float)sprintf("%u", ip2long($ip));
return ( ($ip_dec>=$lower_dec) && ($ip_dec<=$upper_dec) ); return ( ($ip_dec >= $lower_dec) && ($ip_dec <= $upper_dec) );
} }
return false; return false;

View file

@ -144,8 +144,6 @@ class UploadController extends Controller
'error' => $e->getMessage() 'error' => $e->getMessage()
], 500); ], 500);
} }
} }
} }

View file

@ -7,12 +7,11 @@ Powered by Laravel
## Description ## Description
This PHP application based on Laravel 5.4 allows to share files like Wetransfer. You may install it **on your own server**. It **does not require** any database system, it works with JSON files in the storage folder. It is **multilingual** and comes with english and french translations for now. You're welcome to help. This PHP application based on Laravel 5.4 allows to share files like Wetransfer. You may install it **on your own server**. It **does not require** any database system, it works with JSON files into the storage folder. It is **multilingual** and comes with english and french translations for now. You're welcome to help translating the app.
It comes with a droplet (based on Dropzone.js). You may drag and drop some files or directories into the droplet, your files will be uploaded to the server as a bundle. It comes with a droplet. You may drag and drop some files or directories into the droplet, your files will be uploaded to the server as a bundle.
The bundle is a various number of files between 1 and infinite (based on your configuration). A bundle is like a package containing is a various number of files. The bundle has a 2 weeks expiry date after the creation of the bundle. This value is not editable yet, this is a todo.
The bundle has a 2 weeks expiry date after the creation of the bundle. This value is not editable yet, this is a todo.
This application provides three links per upload bundle : This application provides three links per upload bundle :
- a bundle preview link : you can send this link to your recipients who will see the bundle content. For example: http://yourdomain/bundle/dda2d646b6746b96ea9b?auth=965242. The recipient can see all the files of the bundle, can download one given file only or the entire bundle. - a bundle preview link : you can send this link to your recipients who will see the bundle content. For example: http://yourdomain/bundle/dda2d646b6746b96ea9b?auth=965242. The recipient can see all the files of the bundle, can download one given file only or the entire bundle.
@ -20,27 +19,27 @@ This application provides three links per upload bundle :
- a deletion link : for you only, it invalidates the bundle. For example: - a deletion link : for you only, it invalidates the bundle. For example:
http://yourdomain/bundle/dda2d646b6746b96ea9b/delete?auth=ace6f22f5. http://yourdomain/bundle/dda2d646b6746b96ea9b/delete?auth=ace6f22f5.
Each of these links come with a auth code. This code is the same for the preview and the download links. It is however different for the deletion link. Each of these links comes with an authorization code. This code is the same for the preview and the download links. However it is different for the deletion link for obvious reasons.
The application also comes with a Laravel Command (background task) who will physically removed expired bundle files of the storage disk. This command is included in Laravel scheduled commands. The application also comes with a Laravel Artisan command as a background task who will physically remove expired bundle files of the storage disk. This command is configured to run every five minutes among the Laravel scheduled commands.
Sorry about the design, I'm not very good at this, you're welcome to help and participate. Sorry about the design, I'm not very good at this, you're welcome to help and participate.
## Features ## Features
- upload one or more files via drag and drop or browse - upload one or more files via drag and drop or via browsing your computer
- creation of a bundle - creation of a bundle
- ability to keep adding files to the bundle until you close your browser tab, the links remain untouched - ability to keep adding files to the bundle until you close your browser tab, the preview link remain untouched
- bundle expiration - bundle expiration after 2 weeks
- sharing link with bundle content preview - sharing link with bundle content preview
- ability to download a single file of the bundle or the entire bundle - ability to download a single file of the bundle or the entire bundle
- direct download link (doesn't show the bundle content) - direct download link (doesn't preview the bundle content)
- deletion link - deletion link for bundle owner
- garbage collector which removes the expired bundles as a background tasks - garbage collector which removes the expired bundles as a background task
- multilingual (EN and FR) - multilingual (EN and FR)
- easy installation, no database required - easy installation, no database required
- upload limitation based on client IP filtering - upload limitation based on client IP filtering
- secured by tokens, authentication codes and non-accessible files - secured by tokens, authentication codes and non-publicly-accessible files
- (very) early stage for theming support - (very) early stage for theming support
## Requirements ## Requirements
@ -102,17 +101,19 @@ If your want to modify the sources, you can use the Laravel Mix features:
## Roadmap / Ideas / Improvements ## Roadmap / Ideas / Improvements
There are many ideas to come. You are welcome to **participate**. There are many ideas to come. You are welcome to **participate**.
- ability to define a bundle name and/or description that will be shown to the recipients
- make the expiry date editable per bundle - make the expiry date editable per bundle
- limit upload permission by a password (or passwords) - limit upload permission by a password (or passwords)
- ability to send link to recipients - disable bundle after X downloads (value to be configurable by the bundle owner)
- ability to send link to recipients directly from the app
- add PHP unit testing - add PHP unit testing
- more testing on heavy files - more testing on heavy files
- customizable (logo, name...) - customizable / white labeling (logo, name, terms of service, footer ...)
- responsiveness - responsiveness (is it really useful?)
## Licence ## Licence
GPL-3.0 GPLv3
| Permissions | Conditions | Limitations | | Permissions | Conditions | Limitations |
| --------------- | ----------------------------- | ----------- | | --------------- | ----------------------------- | ----------- |
@ -126,4 +127,4 @@ https://choosealicense.com/licenses/gpl-3.0/
## Welcome on board ## Welcome on board
If you want to **participate** or if you want to talk with me : sharing@mabox.eu If you are willing to **participate** or if you just want to talk with me : sharing@mabox.eu

View file

@ -9,15 +9,5 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase class ExampleTest extends TestCase
{ {
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
} }

View file

@ -2,19 +2,86 @@
namespace Tests\Unit; namespace Tests\Unit;
use Upload;
use Exception;
use Tests\TestCase; use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase class ExampleTest extends TestCase
{ {
/**
* A basic test example. public function testPhpVersion()
*
* @return void
*/
public function testBasicTest()
{ {
$this->assertTrue(true); $this->assertTrue(version_compare(phpversion(), '5.6.4', '>='));
}
public function testOpenSSL() {
$this->assertTrue(extension_loaded('openssl'));
}
public function testPDO() {
$this->assertTrue(extension_loaded('pdo'));
}
public function testMbString() {
$this->assertTrue(extension_loaded('mbstring'));
}
public function testTokenizer() {
$this->assertTrue(extension_loaded('tokenizer'));
}
public function testXml() {
$this->assertTrue(extension_loaded('xml'));
}
public function testJson() {
$this->assertTrue(extension_loaded('json'));
}
public function testZip() {
$this->assertTrue(extension_loaded('zip'));
}
public function testCheckIpRange() {
$ips = [
true => [
'192.168.0.10' => '192.168.0.*',
'10.0.2.1' => '10.0.2.0-10.0.2.10',
'191.57.177.24' => '191.57.177.0/24',
'127.0.0.1' => '127.0.0.1'
],
false => [
'192.168.2.10' => '192.168.0.*',
'10.0.2.11' => '10.0.2.0-10.0.2.10',
'191.57.171.24' => '191.57.177.0/24',
'127.0.0.1' => '127.0.0.2'
]
];
foreach ($ips as $assert => $tests) {
foreach ($tests as $ip => $range) {
if ($assert == true) {
$this->assertTrue(Upload::isValidIp($ip, $range), 'Test should be OK but is not (IP: '.$ip.', range '.$range.')');
}
else {
$this->assertFalse(Upload::isValidIp($ip, $range), 'Test should not be OK but is it (IP: '.$ip.', range '.$range.')');
}
}
}
}
/**
* @expectedException Exception
*/
function testFilePath() {
upload::generateFilePath('abc');
}
function testUploadFilesize() {
$this->assertTrue(is_numeric(Upload::fileMaxSize()), 'Max filesize should be a numeric');
} }
} }