Skip to content

Commit 7e15124

Browse files
authored
Merge pull request #13 from olssonm/dev
Dev
2 parents e3b615c + fbfbed9 commit 7e15124

File tree

10 files changed

+180
-24
lines changed

10 files changed

+180
-24
lines changed

.travis.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@ matrix:
1414
- php: 7.1
1515
env:
1616
- ILLUMINATE_VERSION=5.8.*
17-
- php: 7.2
17+
- php: 7.2.24
1818
env:
1919
- ILLUMINATE_VERSION=5.8.*
20-
- php: 7.2
20+
- php: 7.2.24
21+
env:
22+
- ILLUMINATE_VERSION=6.0.*
23+
- php: 7.2.24
24+
env:
25+
- ILLUMINATE_VERSION=^6.0
26+
- php: 7.3
2127
env:
2228
- ILLUMINATE_VERSION=^6.0

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Backup Shield simply listens for when the .zip-file generated by Laravel-backup
2121
composer require olssonm/laravel-backup-shield
2222
```
2323

24-
Requires `PHP: "^7.1"` and `laravel/framework: "^5.8"`. **Compatible with Laravel 6**
24+
Requires `PHP: "^7.1"` and `laravel/framework: "^5.8"`. Compatible with Laravel 6.
2525

2626
Please note that `spatie/laravel-backup: "^6"` and `laravel/framework: "^6.0"` requires PHP 7.2.
2727

@@ -49,7 +49,7 @@ Set to `NULL` if you want to keep your backup without a password.
4949

5050
Set your type of encryption. Available options are:
5151

52-
`\Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT` (PKWARE/ZipCrypto)
52+
`\Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT` (PHP < 7.2: PKWARE/ZipCrypto, PHP >= 7.2: AES 128)
5353
`\Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_128` (AES 128)
5454
`\Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_192` (AES 192)
5555
`\Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_256` (AES 256)
@@ -60,6 +60,12 @@ Using the `ENCRYPTION_DEFAULT` (PKWARE/ZipCrypto) crypto gives you the best port
6060

6161
Also to note is that when zipping very large files ZipCrypto might be very inefficient as the entire data-set will have to be loaded into memory to perform the encryption, if the zipped file's content is bigger than your available RAM you *will* run out of memory.
6262

63+
#### Differences when using PHP < 7.2 and PHP >= 7.2
64+
65+
Since PHP 7.2 (coupled with zip-extension >= 1.14.0) PHP can natively password-protect .zip-files via the ZipArchive-methods. If these conditions are met, ZipArchive is used. Else, the package will automatically use the [nelexa/zip](https://github.com/Ne-Lexa/php-zip)-package.
66+
67+
The former might be less memory-intensive.
68+
6369
## Testing
6470

6571
``` bash

phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
convertNoticesToExceptions="true"
88
convertWarningsToExceptions="true"
99
processIsolation="false"
10-
stopOnFailure="false"
10+
stopOnFailure="true"
1111
>
1212
<testsuites>
1313
<testsuite name="Package Test Suite">

src/BackupShieldServiceProvider.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
namespace Olssonm\BackupShield;
44

55
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
6+
use Olssonm\BackupShield\Factories\Password;
7+
use Olssonm\BackupShield\Encryption;
68

9+
/**
10+
* Laravel service provider for the Backup Shield-package
11+
*/
712
class BackupShieldServiceProvider extends ServiceProvider
813
{
914
/**
@@ -38,7 +43,7 @@ public function __construct($app) {
3843
*
3944
* @return void
4045
*/
41-
public function boot()
46+
public function boot() : void
4247
{
4348
// Publishing of configuration
4449
$this->publishes([
@@ -50,11 +55,15 @@ public function boot()
5055

5156
/**
5257
* Register any package services.
53-
*
58+
*
5459
* @return void
5560
*/
56-
public function register()
61+
public function register() : void
5762
{
63+
$this->app->singleton('Olssonm\BackupShield\Encryption', function ($app) {
64+
return new \Olssonm\BackupShield\Encryption;
65+
});
66+
5867
$this->mergeConfigFrom(
5968
$this->config, 'backup-shield'
6069
);

src/Encryption.php

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,78 @@
44

55
use PhpZip\ZipFile;
66

7+
use \ZipArchive;
8+
79
class Encryption
810
{
9-
const ENCRYPTION_DEFAULT = ZipFile::ENCRYPTION_METHOD_TRADITIONAL;
10-
const ENCRYPTION_WINZIP_AES_128 = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128;
11-
const ENCRYPTION_WINZIP_AES_192 = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192;
12-
const ENCRYPTION_WINZIP_AES_256 = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
11+
/**
12+
* Default encryption contants
13+
*
14+
* @var string
15+
*/
16+
const ENCRYPTION_DEFAULT = 'default';
17+
18+
/**
19+
* AES-128 encryption contants
20+
*
21+
* @var string
22+
*/
23+
const ENCRYPTION_WINZIP_AES_128 = 'aes_128';
24+
25+
/**
26+
* AES-192 encryption contants
27+
*
28+
* @var string
29+
*/
30+
const ENCRYPTION_WINZIP_AES_192 = 'aes_192';
31+
32+
/**
33+
* AES-256 encryption contants
34+
*
35+
* @var string
36+
*/
37+
const ENCRYPTION_WINZIP_AES_256 = 'aes_256';
38+
39+
/**
40+
* ZipArchive encryption constants; stores as simple string for PHP < 7.2
41+
* backwards compatability
42+
*
43+
* @var array
44+
*/
45+
private $zipArchiveOptions = [
46+
self::ENCRYPTION_DEFAULT => '257',
47+
self::ENCRYPTION_WINZIP_AES_128 => '257',
48+
self::ENCRYPTION_WINZIP_AES_192 => '258',
49+
self::ENCRYPTION_WINZIP_AES_256 => '259',
50+
];
51+
52+
/**
53+
* ZipFile encryption constants
54+
*
55+
* @var array
56+
*/
57+
private $zipFileOptions = [
58+
self::ENCRYPTION_DEFAULT => ZipFile::ENCRYPTION_METHOD_TRADITIONAL,
59+
self::ENCRYPTION_WINZIP_AES_128 => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128,
60+
self::ENCRYPTION_WINZIP_AES_192 => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192,
61+
self::ENCRYPTION_WINZIP_AES_256 => ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256,
62+
];
63+
64+
/**
65+
* Retrive appropriate encryption constant
66+
*
67+
* @param string $type
68+
* @param string $engine
69+
* @return mixed
70+
*/
71+
public function getEncryptionConstant($type, $engine)
72+
{
73+
if ($engine == 'ZipArchive' && isset($this->zipArchiveOptions[$type])) {
74+
return $this->zipArchiveOptions[$type];
75+
} elseif ($engine == 'ZipFile' && isset($this->zipFileOptions[$type])) {
76+
return $this->zipFileOptions[$type];
77+
} else {
78+
throw new \Exception("Encryption key not set or invalid value", 1);
79+
}
80+
}
1381
}

src/Factories/Password.php

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,100 @@
22

33
namespace Olssonm\BackupShield\Factories;
44

5+
use Illuminate\Support\Collection;
6+
7+
use Olssonm\BackupShield\Encryption;
58
use PhpZip\ZipFile;
9+
use \ZipArchive;
610

711
class Password
812
{
913
/**
10-
* Path to .zip-fil
14+
* Path to .zip-file
15+
*
1116
* @var string
1217
*/
1318
public $path;
1419

20+
/**
21+
* The chosen password
22+
*
23+
* @var string
24+
*/
25+
protected $password;
26+
1527
/**
1628
* Read the .zip, apply password and encryption, then rewrite the file
1729
* @param string $path the path to the .zip-file
1830
*/
19-
function __construct(string $path)
31+
function __construct(Encryption $encryption, string $path)
32+
{
33+
$this->password = config('backup-shield.password');
34+
35+
if (!$this->password) {
36+
return $this->path = $path;
37+
}
38+
39+
// If ZipArchive is enabled
40+
if (class_exists('ZipArchive') && in_array('setEncryptionIndex', get_class_methods('ZipArchive'))) {
41+
consoleOutput()->info('Applying password and encryption to zip using ZipArchive...');
42+
$this->makeZipArchive($encryption, $path);
43+
}
44+
45+
// Fall back on PHP-driven ZipFile
46+
else {
47+
consoleOutput()->info('Applying password and encryption to zip using ZipFile...');
48+
$this->makeZipFile($encryption, $path);
49+
}
50+
51+
consoleOutput()->info('Successfully applied password and encryption to zip.');
52+
}
53+
54+
/**
55+
* Use native PHP ZipArchive
56+
*
57+
* @param Encryption $encryption
58+
* @return void
59+
*/
60+
protected function makeZipArchive(Encryption $encryption, string $path) : void
2061
{
21-
consoleOutput()->info('Applying password and encryption to zip...');
62+
$encryptionConstant = $encryption->getEncryptionConstant(
63+
config('backup-shield.encryption'),
64+
'ZipArchive'
65+
);
66+
67+
$zipArchive = new ZipArchive;
68+
69+
$zipArchive->open($path, ZipArchive::OVERWRITE);
70+
$zipArchive->addFile($path, 'backup.zip');
71+
$zipArchive->setPassword($this->password);
72+
Collection::times($zipArchive->numFiles, function ($i) use ($zipArchive, $encryptionConstant) {
73+
$zipArchive->setEncryptionIndex($i - 1, $encryptionConstant);
74+
});
75+
$zipArchive->close();
76+
77+
$this->path = $path;
78+
}
79+
80+
/**
81+
* Use PhpZip\ZipFile-package to create the zip
82+
*
83+
* @param Encryption $encryption
84+
* @return void
85+
*/
86+
protected function makeZipFile(Encryption $encryption, string $path) : void
87+
{
88+
$encryptionConstant = $encryption->getEncryptionConstant(
89+
config('backup-shield.encryption'),
90+
'ZipFile'
91+
);
2292

23-
// Create a new zip, add the zip from spatie/backup, encrypt and resave/overwrite
2493
$zipFile = new ZipFile();
2594
$zipFile->addFile($path, 'backup.zip', ZipFile::METHOD_DEFLATED);
26-
$zipFile->setPassword(config('backup-shield.password'), config('backup-shield.encryption'));
95+
$zipFile->setPassword($this->password, $encryptionConstant);
2796
$zipFile->saveAsFile($path);
2897
$zipFile->close();
2998

30-
consoleOutput()->info('Successfully applied password and encryption to zip.');
31-
3299
$this->path = $path;
33100
}
34101
}

src/Listeners/PasswordProtectZip.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public function __construct()
2424
* @param \Spatie\Backup\Events\BackupZipWasCreated $event
2525
* @return string
2626
*/
27-
public function handle(BackupZipWasCreated $event)
27+
public function handle(BackupZipWasCreated $event) : string
2828
{
29-
return (new Password($event->pathToZip))->path;
29+
return (new Password(new \Olssonm\BackupShield\Encryption, $event->pathToZip))->path;
3030
}
3131
}

src/config/backup-shield.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
'encryption' => \Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT
66

77
// Available encryption methods:
8-
// \Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT (PKWARE/ZipCrypto)
8+
// \Olssonm\BackupShield\Encryption::ENCRYPTION_DEFAULT (PHP < 7.2: PKWARE/ZipCrypto, PHP >= 7.2 AES 128)
99
// \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_128 (AES 128)
1010
// \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_192 (AES 192)
1111
// \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_256 (AES 256)

tests/BackupShieldTests.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function test_listener_return_data()
6060
copy($path, $pathTest);
6161

6262
// Manually set config
63-
config()->set('backup-shield.password', 'Z|n1eMyw3[9&%u=ga$h&');
63+
config()->set('backup-shield.password', 'M79Y6aKARXa9yLrcZd3srz');
6464
config()->set('backup-shield.encryption', \Olssonm\BackupShield\Encryption::ENCRYPTION_WINZIP_AES_256);
6565

6666
$data = event(new BackupZipWasCreated($pathTest));
@@ -79,7 +79,7 @@ public function test_encryption_protection()
7979

8080
$this->assertEquals(true, $zipInfo['backup.zip']->isEncrypted());
8181
$this->assertEquals('backup.zip', $zipInfo['backup.zip']->getName());
82-
$this->assertEquals(config('backup-shield.encryption'), $zipInfo['backup.zip']->getEncryptionMethod());
82+
$this->assertEquals(0, $zipInfo['backup.zip']->getEncryptionMethod());
8383
}
8484

8585
/** Teardown */

tests/resources/test.zip

520 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)