From 712f995cd517e4bada2554b4a2e29125bef8b13e Mon Sep 17 00:00:00 2001 From: Oliver Matla Date: Fri, 15 Mar 2024 16:49:28 +0100 Subject: [PATCH 1/3] require pint --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index e548712..4a59e4a 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "laravel/sanctum": "^4.0" }, "require-dev": { + "laravel/pint": "^1.14", "laravel/sail": "^1.26", "orchestra/testbench": "^9.0", "phpunit/phpunit": "^10.5" From ce5ce7b86de91e4d1cd7d363f5dc941da39694ad Mon Sep 17 00:00:00 2001 From: Oliver Matla Date: Fri, 15 Mar 2024 16:49:41 +0100 Subject: [PATCH 2/3] apply code style --- config/protector.php | 2 +- src/Classes/AbstractMySqlSchemaStateProxy.php | 6 +- src/Classes/MySqlSchemaStateProxy.php | 16 +-- src/Commands/CreateKeys.php | 1 - src/Commands/CreateToken.php | 4 +- src/Commands/ExportDump.php | 3 - src/Commands/ImportDump.php | 41 +++---- .../EmptyBaseDirectoryException.php | 4 +- ...FailedCreatingDestinationPathException.php | 3 - .../FailedDumpGenerationException.php | 2 - .../FailedMysqlCommandException.php | 4 +- .../FailedRemoteDatabaseFetchingException.php | 3 - src/Exceptions/FileNotFoundException.php | 4 +- .../InvalidConfigurationException.php | 2 - src/Exceptions/InvalidConnectionException.php | 2 - .../InvalidEnvironmentException.php | 2 - src/Exceptions/ShellAccessDeniedException.php | 4 +- .../UnsupportedDatabaseException.php | 2 - src/Protector.php | 109 +++++++++--------- src/ProtectorFacade.php | 2 - src/ProtectorServiceProvider.php | 8 +- src/Traits/HasConfiguration.php | 4 +- tests/TestCase.php | 8 +- tests/feature/ExportDumpTest.php | 16 +-- tests/feature/ImportDumpCommandTest.php | 11 +- tests/feature/ImportDumpTest.php | 58 +++++----- tests/feature/RemoteDumpTest.php | 6 +- 27 files changed, 144 insertions(+), 183 deletions(-) diff --git a/config/protector.php b/config/protector.php index d171f83..fbb6abd 100644 --- a/config/protector.php +++ b/config/protector.php @@ -115,5 +115,5 @@ | The default is 120 seconds. | */ - 'httpTimeout' => env('PROTECTOR_HTTP_TIMEOUT', 120) + 'httpTimeout' => env('PROTECTOR_HTTP_TIMEOUT', 120), ]; diff --git a/src/Classes/AbstractMySqlSchemaStateProxy.php b/src/Classes/AbstractMySqlSchemaStateProxy.php index 14a93c1..10d1d0a 100644 --- a/src/Classes/AbstractMySqlSchemaStateProxy.php +++ b/src/Classes/AbstractMySqlSchemaStateProxy.php @@ -3,10 +3,8 @@ namespace Cybex\Protector\Classes; use Cybex\Protector\Protector; -use Exception; use Illuminate\Database\Connection; use Illuminate\Database\Schema\MySqlSchemaState; -use Illuminate\Database\Schema\SchemaState; use Symfony\Component\Process\Process; /** @@ -19,7 +17,7 @@ public function __construct(protected MySqlSchemaState $schemaState, protected P } /** - * @inheritDoc + * {@inheritDoc} */ public function dump(Connection $connection, $path) { @@ -27,7 +25,7 @@ public function dump(Connection $connection, $path) } /** - * @inheritDoc + * {@inheritDoc} */ public function load($path) { diff --git a/src/Classes/MySqlSchemaStateProxy.php b/src/Classes/MySqlSchemaStateProxy.php index 8573106..a03e67a 100644 --- a/src/Classes/MySqlSchemaStateProxy.php +++ b/src/Classes/MySqlSchemaStateProxy.php @@ -12,7 +12,7 @@ class MySqlSchemaStateProxy extends AbstractMySqlSchemaStateProxy { /** - * @inheritDoc + * {@inheritDoc} */ public function dump(Connection $connection, $path) { @@ -23,7 +23,7 @@ public function dump(Connection $connection, $path) $this->schemaState->output, array_merge( $this->baseVariables($this->schemaState->connection->getConfig()), - ['LARAVEL_LOAD_PATH' => $path,] + ['LARAVEL_LOAD_PATH' => $path] ) ); @@ -33,7 +33,7 @@ public function dump(Connection $connection, $path) } /** - * @inheritDoc + * {@inheritDoc} */ public function load($path) { @@ -48,11 +48,11 @@ protected function getCommandString(): string $command = 'mysqldump '.$this->schemaState->connectionString().' '; $conditionalParameters = [ - '--set-gtid-purged=OFF' => !$this->schemaState->connection->isMaria(), - '--no-create-db' => !$this->protector->shouldCreateDb(), - '--skip-comments' => !$this->protector->shouldDumpComments(), - '--skip-set-charset' => !$this->protector->shouldDumpCharsets(), - '--no-data' => !$this->protector->shouldDumpData(), + '--set-gtid-purged=OFF' => ! $this->schemaState->connection->isMaria(), + '--no-create-db' => ! $this->protector->shouldCreateDb(), + '--skip-comments' => ! $this->protector->shouldDumpComments(), + '--skip-set-charset' => ! $this->protector->shouldDumpCharsets(), + '--no-data' => ! $this->protector->shouldDumpData(), ]; $parameters = [ diff --git a/src/Commands/CreateKeys.php b/src/Commands/CreateKeys.php index 9afb56e..3f69adf 100644 --- a/src/Commands/CreateKeys.php +++ b/src/Commands/CreateKeys.php @@ -6,7 +6,6 @@ /** * Class CreateKeys - * @package Cybex\Protector\Commands; */ class CreateKeys extends Command { diff --git a/src/Commands/CreateToken.php b/src/Commands/CreateToken.php index 60c9b93..6047c2a 100644 --- a/src/Commands/CreateToken.php +++ b/src/Commands/CreateToken.php @@ -6,7 +6,6 @@ /** * Class CreateToken - * @package Cybex\Protector\Commands; */ class CreateToken extends Command { @@ -38,10 +37,11 @@ public function handle() $user->tokens()->whereAbilities('["protector:import"]')->delete(); $userInformation = sprintf('%s: %s (%s)', $user->id, $user->name, $user->email); - if (!$user->protector_public_key && !$publicKey) { + if (! $user->protector_public_key && ! $publicKey) { $this->error( 'The user doesn\'t have a protector public key and none was specified. Please provide a public key for the user.' ); + return null; } diff --git a/src/Commands/ExportDump.php b/src/Commands/ExportDump.php index ba4c382..0c77183 100644 --- a/src/Commands/ExportDump.php +++ b/src/Commands/ExportDump.php @@ -8,7 +8,6 @@ /** * Class ExportDump - * @package Cybex\Protector\Commands; */ class ExportDump extends Command { @@ -33,8 +32,6 @@ class ExportDump extends Command /** * Execute the console command. - * - * @return int */ public function handle(): int { diff --git a/src/Commands/ImportDump.php b/src/Commands/ImportDump.php index b77589b..bef8bd6 100644 --- a/src/Commands/ImportDump.php +++ b/src/Commands/ImportDump.php @@ -16,8 +16,6 @@ /** * Class ImportDump - * - * @package Cybex\Protector\Commands */ class ImportDump extends Command { @@ -46,13 +44,14 @@ class ImportDump extends Command protected $description = 'Imports a local or remote database dump.'; protected const DOWNLOAD_REMOTE_DUMP = 'Download remote dump'; + protected const IMPORT_EXISTING_LOCAL_DUMP = 'Import existing local dump'; + protected ?Protector $protector = null; /** * Execute the console command. * - * @return int * @throws InvalidEnvironmentException */ public function handle(): int @@ -68,13 +67,13 @@ public function handle(): int $optionLatest = $this->option('latest'); $optionConnection = $this->option('connection'); - if (App::environment('production') && !$this->option('allow-production')) { + if (App::environment('production') && ! $this->option('allow-production')) { throw new InvalidEnvironmentException( 'Import is not allowed on production systems! Use --allow-production' ); } - if ($optionForce && !($optionRemote || $optionFile || $optionDump || $optionLatest)) { + if ($optionForce && ! ($optionRemote || $optionFile || $optionDump || $optionLatest)) { $this->error('Nothing to import.'); return self::FAILURE; @@ -83,7 +82,7 @@ public function handle(): int $this->protector->withConnectionName($optionConnection); $shouldImportLocalDump = $optionFile || $optionDump || $optionLatest; - $shouldDownloadDump = $optionRemote || (!$shouldImportLocalDump && $this->userWantsRemoteDump()); + $shouldDownloadDump = $optionRemote || (! $shouldImportLocalDump && $this->userWantsRemoteDump()); if ($shouldDownloadDump) { $importFilePath = $this->getRemoteDump(); @@ -99,7 +98,7 @@ public function handle(): int } if (empty($localFilePath)) { - if (!$importFilePath) { + if (! $importFilePath) { $this->error('Found no file to import.'); return self::FAILURE; @@ -110,7 +109,7 @@ public function handle(): int $this->importDump($localFilePath, $optionForce); - if (!$optionFile) { + if (! $optionFile) { unlink($localFilePath); } @@ -119,8 +118,6 @@ public function handle(): int /** * Reads the remote dump file and deletes all old dumps if the flush option is set. - * - * @return string|null */ protected function getRemoteDump(): ?string { @@ -203,7 +200,7 @@ public function getMetaDataForFiles(array $directoryFiles): Collection foreach ($directoryFiles as $directoryFile) { $metaData = $this->protector->getDumpMetaData($directoryFile); - if ($this->option('ignore-connection-filter') || (!is_array($metaData) || empty($metaData))) { + if ($this->option('ignore-connection-filter') || (! is_array($metaData) || empty($metaData))) { $matchingFiles->push([ 'path' => $directoryFile, 'file' => basename($directoryFile), @@ -220,9 +217,9 @@ public function getMetaDataForFiles(array $directoryFiles): Collection } if (($metaData['meta']['connection'] ?? false) && Arr::exists( - config('database.connections'), - $metaData['meta']['connection'] - )) { + config('database.connections'), + $metaData['meta']['connection'] + )) { $fileInformation = [ 'path' => $directoryFile, 'file' => basename($directoryFile), @@ -269,11 +266,11 @@ public function getMetaDataForFiles(array $directoryFiles): Collection protected function importDump(string $importFilePath, ?bool $optionForce): void { if ($optionForce || $this->confirm( - sprintf( - 'Are you sure that you want to import the dump into the database: %s?', - $this->protector->getDatabaseName() - ) - )) { + sprintf( + 'Are you sure that you want to import the dump into the database: %s?', + $this->protector->getDatabaseName() + ) + )) { try { $this->protector->importDump($importFilePath, Arr::except($this->options(), ['migrate'])); @@ -309,11 +306,11 @@ public function getConnectionFiles(?string $connectionName = null): Collection $filesByConnection = $sortedFiles->groupBy('connection'); - if ($connectionName && !$filesByConnection->has($connectionName)) { + if ($connectionName && ! $filesByConnection->has($connectionName)) { throw new InvalidConnectionException(); } - if (!$connectionName) { + if (! $connectionName) { $connectionName = $this->chooseConnectionName($filesByConnection->keys()); } @@ -322,8 +319,6 @@ public function getConnectionFiles(?string $connectionName = null): Collection /** * Asks if an existing dump or a remote dump should be imported. - * - * @return bool */ protected function userWantsRemoteDump(): bool { diff --git a/src/Exceptions/EmptyBaseDirectoryException.php b/src/Exceptions/EmptyBaseDirectoryException.php index 791635d..30ad936 100644 --- a/src/Exceptions/EmptyBaseDirectoryException.php +++ b/src/Exceptions/EmptyBaseDirectoryException.php @@ -9,12 +9,10 @@ * Class FailedShellCommandException * * Thrown if a shell command couldn't be executed properly. - * - * @package Cybex\Protector\Exceptions */ class EmptyBaseDirectoryException extends Exception { - public function __construct($message = '', $code = 0, Throwable $previous = null) + public function __construct($message = '', $code = 0, ?Throwable $previous = null) { parent::__construct($message ?: 'There are no dumps in the dump folder', $code, $previous); } diff --git a/src/Exceptions/FailedCreatingDestinationPathException.php b/src/Exceptions/FailedCreatingDestinationPathException.php index fc832dd..0627a0d 100644 --- a/src/Exceptions/FailedCreatingDestinationPathException.php +++ b/src/Exceptions/FailedCreatingDestinationPathException.php @@ -8,10 +8,7 @@ * Class FailedCreatingDestinationPathException * * Thrown if the destination path could not be created. - * - * @package Cybex\Protector\Exceptions */ class FailedCreatingDestinationPathException extends Exception { - } diff --git a/src/Exceptions/FailedDumpGenerationException.php b/src/Exceptions/FailedDumpGenerationException.php index 8726fdd..ab51678 100644 --- a/src/Exceptions/FailedDumpGenerationException.php +++ b/src/Exceptions/FailedDumpGenerationException.php @@ -8,8 +8,6 @@ * Class FailedDumpGenerationException * * Thrown if the generation of the MySQL dump has failed. - * - * @package Cybex\Protector\Exceptions */ class FailedDumpGenerationException extends Exception { diff --git a/src/Exceptions/FailedMysqlCommandException.php b/src/Exceptions/FailedMysqlCommandException.php index 1d018ef..6c91e12 100644 --- a/src/Exceptions/FailedMysqlCommandException.php +++ b/src/Exceptions/FailedMysqlCommandException.php @@ -9,12 +9,10 @@ * Class FailedShellCommandException * * Thrown if a shell command couldn't be executed properly. - * - * @package Cybex\Protector\Exceptions */ class FailedMysqlCommandException extends Exception { - public function __construct($message = '', $code = 0, Throwable $previous = null) + public function __construct($message = '', $code = 0, ?Throwable $previous = null) { parent::__construct($message ?: 'Shell call to mysql client failed.', $code, $previous); } diff --git a/src/Exceptions/FailedRemoteDatabaseFetchingException.php b/src/Exceptions/FailedRemoteDatabaseFetchingException.php index 406d11b..2f850ba 100644 --- a/src/Exceptions/FailedRemoteDatabaseFetchingException.php +++ b/src/Exceptions/FailedRemoteDatabaseFetchingException.php @@ -8,10 +8,7 @@ * Class FailedRemoteDatabaseFetchingException * * Thrown if the remote database could not be fetched successfully. - * - * @package Cybex\Protector\Exceptions */ class FailedRemoteDatabaseFetchingException extends Exception { - } diff --git a/src/Exceptions/FileNotFoundException.php b/src/Exceptions/FileNotFoundException.php index fcc4c65..b6cdd09 100644 --- a/src/Exceptions/FileNotFoundException.php +++ b/src/Exceptions/FileNotFoundException.php @@ -9,12 +9,10 @@ * Class FileNotFoundException * * Thrown if a file could not be found. - * - * @package Cybex\Protector\Exceptions */ class FileNotFoundException extends Exception { - public function __construct($path, $code = 0, Throwable $previous = null) + public function __construct($path, $code = 0, ?Throwable $previous = null) { parent::__construct(sprintf('The file "%s" was not found.', $path), $code, $previous); } diff --git a/src/Exceptions/InvalidConfigurationException.php b/src/Exceptions/InvalidConfigurationException.php index a730a0f..96e23db 100644 --- a/src/Exceptions/InvalidConfigurationException.php +++ b/src/Exceptions/InvalidConfigurationException.php @@ -8,8 +8,6 @@ * Class InvalidEnvironmentException * * Thrown if the configuration is invalid or missing. - * - * @package Cybex\Protector\Exceptions */ class InvalidConfigurationException extends Exception { diff --git a/src/Exceptions/InvalidConnectionException.php b/src/Exceptions/InvalidConnectionException.php index 466ccd2..38e90c9 100644 --- a/src/Exceptions/InvalidConnectionException.php +++ b/src/Exceptions/InvalidConnectionException.php @@ -8,8 +8,6 @@ * Class InvalidConnectionException * * Thrown if the connection is not configured properly. - * - * @package Cybex\Protector\Exceptions */ class InvalidConnectionException extends Exception { diff --git a/src/Exceptions/InvalidEnvironmentException.php b/src/Exceptions/InvalidEnvironmentException.php index d2fab73..c3e9446 100644 --- a/src/Exceptions/InvalidEnvironmentException.php +++ b/src/Exceptions/InvalidEnvironmentException.php @@ -8,8 +8,6 @@ * Class InvalidEnvironmentException * * Thrown if the environment is set to Production and Production environment was not allowed explicitly. - * - * @package Cybex\Protector\Exceptions */ class InvalidEnvironmentException extends Exception { diff --git a/src/Exceptions/ShellAccessDeniedException.php b/src/Exceptions/ShellAccessDeniedException.php index ac3bac4..f11c0e5 100644 --- a/src/Exceptions/ShellAccessDeniedException.php +++ b/src/Exceptions/ShellAccessDeniedException.php @@ -9,12 +9,10 @@ * Class ShellAccessDeniedException * * Thrown when the shell access is denied. - * - * @package Cybex\Protector\Exceptions */ class ShellAccessDeniedException extends Exception { - public function __construct($message = '', $code = 0, Throwable $previous = null) + public function __construct($message = '', $code = 0, ?Throwable $previous = null) { parent::__construct( $message ?: 'Shell commands are disabled on your server, exec() must be enabled.', diff --git a/src/Exceptions/UnsupportedDatabaseException.php b/src/Exceptions/UnsupportedDatabaseException.php index 4d00875..6a3b005 100644 --- a/src/Exceptions/UnsupportedDatabaseException.php +++ b/src/Exceptions/UnsupportedDatabaseException.php @@ -8,8 +8,6 @@ * Class UnsupportedDatabaseException * * Thrown if Protector is run in an unsupported database environment. - * - * @package Cybex\Protector\Exceptions */ class UnsupportedDatabaseException extends Exception { diff --git a/src/Protector.php b/src/Protector.php index d4549fe..6275491 100644 --- a/src/Protector.php +++ b/src/Protector.php @@ -38,7 +38,6 @@ use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; -use Throwable; class Protector { @@ -46,17 +45,15 @@ class Protector /** * Cache for the runtime-metadata for a new dump. - * - * @var array */ protected array $metaDataCache = []; - public function __construct(string $connectionName = null) + public function __construct(?string $connectionName = null) { $this->withConnectionName($connectionName) - ->withDefaultMaxPacketLength() - ->withoutCreateDb() - ->withoutTablespaces(); + ->withDefaultMaxPacketLength() + ->withoutCreateDb() + ->withoutTablespaces(); } /** @@ -73,15 +70,15 @@ public function importDump(string $sourceFilePath, array $options = []): void $this->guardExecEnabled(); // Production environment is not allowed unless set in options. - if (App::environment('production') && !Arr::get($options, 'allow-production')) { + if (App::environment('production') && ! Arr::get($options, 'allow-production')) { throw new InvalidEnvironmentException('Production environment is not allowed and option was not set.'); } - if (!$this->connectionConfig) { + if (! $this->connectionConfig) { throw new InvalidConnectionException('Connection is not configured properly'); } - if (!file_exists($sourceFilePath)) { + if (! file_exists($sourceFilePath)) { throw new FileNotFoundException($sourceFilePath); } @@ -148,7 +145,7 @@ public function createDestinationFilePath(string $fileName, ?string $subFolder = */ public function createDump(array $options = []): string { - if (!$this->connectionConfig) { + if (! $this->connectionConfig) { throw new InvalidConnectionException('Connection is not configured properly.'); } @@ -186,7 +183,7 @@ public function getDumpMetaData(string $dumpFile): bool|array $decodedData = json_decode($matches['data'], true); // We store json-encoded arrays, if we do not get an array back, that means something went wrong. - if (!is_array($decodedData)) { + if (! is_array($decodedData)) { return false; } @@ -219,13 +216,13 @@ public function getRemoteDump(): string { $disk = $this->getDisk(); - if ($this->shouldEncrypt() && !$this->getPrivateKey()) { + if ($this->shouldEncrypt() && ! $this->getPrivateKey()) { throw new InvalidConfigurationException( 'For using Laravel Sanctum a crypto keypair is required. There was none found in your .env file.' ); } - if (!$serverUrl = $this->getServerUrl()) { + if (! $serverUrl = $this->getServerUrl()) { throw new InvalidConfigurationException('Server url is not set or invalid.'); } @@ -234,8 +231,8 @@ public function getRemoteDump(): string $request = $this->getConfiguredHttpRequest(); if ($isTelescopeRecording = class_exists( - \Laravel\Telescope\Telescope::class - ) && \Laravel\Telescope\Telescope::isRecording()) { + \Laravel\Telescope\Telescope::class + ) && \Laravel\Telescope\Telescope::isRecording()) { \Laravel\Telescope\Telescope::stopRecording(); } @@ -251,7 +248,7 @@ public function getRemoteDump(): string } } - if (!$response->ok()) { + if (! $response->ok()) { $httpCode = $response->status(); throw match ($httpCode) { @@ -263,7 +260,7 @@ public function getRemoteDump(): string } $destinationFilePath = $this->getDumpDestinationFilePath($response->header('Content-Disposition')); - $stream = $response->toPsrResponse()->getBody(); + $stream = $response->toPsrResponse()->getBody(); $this->writeDumpFile( $stream, @@ -326,14 +323,14 @@ protected function generateDump(array $options = []): ?string } /** @var Connection $connection */ - $connection = DB::connection($this->connectionName); - $schemaState = $connection->getSchemaState(); + $connection = DB::connection($this->connectionName); + $schemaState = $connection->getSchemaState(); $schemaStateProxy = $this->getProxyForSchemaState($schemaState); - $tempFile = tempnam('', 'protector'); + $tempFile = tempnam('', 'protector'); $schemaStateProxy->dump($connection, $tempFile); - if (!filesize($tempFile)) { + if (! filesize($tempFile)) { unlink($tempFile); $tempFile = null; @@ -389,7 +386,7 @@ public function createFilename(): string */ public function getMetaData(bool $refresh = false): array { - if (!$refresh && $this->metaDataCache) { + if (! $refresh && $this->metaDataCache) { return $this->metaDataCache; } @@ -399,19 +396,19 @@ public function getMetaData(bool $refresh = false): array $this->guardExecEnabled(); $gitInformation = [ - 'gitRevision' => $this->getGitRevision(), - 'gitBranch' => $this->getGitBranch(), + 'gitRevision' => $this->getGitRevision(), + 'gitBranch' => $this->getGitBranch(), 'gitRevisionDate' => $this->getGitHeadDate(), ]; } return $this->metaDataCache = [ - 'database' => $this->connectionConfig['database'], - 'connection' => $this->connectionName, - 'gitRevision' => $gitInformation['gitRevision'] ?? null, - 'gitBranch' => $gitInformation['gitBranch'] ?? null, + 'database' => $this->connectionConfig['database'], + 'connection' => $this->connectionName, + 'gitRevision' => $gitInformation['gitRevision'] ?? null, + 'gitBranch' => $gitInformation['gitBranch'] ?? null, 'gitRevisionDate' => $gitInformation['gitRevisionDate'] ?? null, - 'dumpedAtDate' => now(), + 'dumpedAtDate' => now(), ]; } @@ -425,7 +422,7 @@ protected function tail(string $file, int $lines, int $buffer = 1024): array // Open file-handle. $fileHandle = $this->getDisk()->readStream($file); - if (!is_resource($fileHandle)) { + if (! is_resource($fileHandle)) { throw new FileNotFoundException($file); } @@ -433,7 +430,7 @@ protected function tail(string $file, int $lines, int $buffer = 1024): array fseek($fileHandle, 0, SEEK_END); $linesToRead = $lines; - $contents = ''; + $contents = ''; // Only read file as long as file-pointer is not at start of the file and there are still lines to read open. while (ftell($fileHandle) && $linesToRead >= 0) { @@ -489,16 +486,16 @@ public function prepareFileDownloadResponse(Request $request): Response|Streamed */ public function generateFileDownloadResponse( Request $request, - string $connectionName = null + ?string $connectionName = null ): Response|StreamedResponse { $shouldEncrypt = $this->shouldEncrypt(); // Only proceed when either Laravel Sanctum is turned off or the user's token is valid. - if (!$shouldEncrypt || $request->user()?->tokenCan('protector:import')) { + if (! $shouldEncrypt || $request->user()?->tokenCan('protector:import')) { if ($this->withConnectionName($connectionName)) { try { $serverFilePath = $this->createDump(); - $publicKey = $this->getPublicKey($request); + $publicKey = $this->getPublicKey($request); } catch (InvalidConnectionException|FailedDumpGenerationException|InvalidConfigurationException $exception) { return response($exception->getMessage(), 500, ['message' => $exception->getMessage()]); } @@ -506,10 +503,10 @@ public function generateFileDownloadResponse( $chunkSize = $this->getConfigValueForKey('chunkSize'); return response()->streamDownload( - function () use ($publicKey, $request, $serverFilePath, $chunkSize, $shouldEncrypt) { + function () use ($publicKey, $serverFilePath, $chunkSize, $shouldEncrypt) { $inputHandle = fopen($serverFilePath, 'rb'); - while (!feof($inputHandle)) { + while (! feof($inputHandle)) { $chunk = fread($inputHandle, $chunkSize); // Encrypt the data when Laravel Sanctum is active. @@ -525,14 +522,14 @@ function () use ($publicKey, $request, $serverFilePath, $chunkSize, $shouldEncry }, $this->createFilename(), [ - 'Content-Type' => 'text/plain', - 'Pragma' => 'no-cache', - 'Expires' => gmdate(DATE_RFC7231, time() - 3600), + 'Content-Type' => 'text/plain', + 'Pragma' => 'no-cache', + 'Expires' => gmdate(DATE_RFC7231, time() - 3600), // Encryption adds some overhead to the chunk, which has to be considered when decrypting it. - 'Chunk-Size' => $shouldEncrypt ? $chunkSize + $this->determineEncryptionOverhead( - $chunkSize, - $publicKey - ) : $chunkSize, + 'Chunk-Size' => $shouldEncrypt ? $chunkSize + $this->determineEncryptionOverhead( + $chunkSize, + $publicKey + ) : $chunkSize, 'Sanctum-Enabled' => $shouldEncrypt, ] ); @@ -588,7 +585,7 @@ protected function getConfiguredHttpRequest(): PendingRequest } elseif ($htaccessLogin) { // Add basic authentication to request. $credentials = explode(':', $htaccessLogin); - $request = Http::withBasicAuth($credentials[0], $credentials[1]); + $request = Http::withBasicAuth($credentials[0], $credentials[1]); } else { // Protector cannot be used without any authentication. throw new InvalidConfigurationException( @@ -606,9 +603,9 @@ protected function getConfiguredHttpRequest(): PendingRequest */ public function getLatestDumpName(): string { - $disk = $this->getDisk(); + $disk = $this->getDisk(); $baseDirectory = $this->getConfigValueForKey('baseDirectory'); - $files = $disk->files($baseDirectory); + $files = $disk->files($baseDirectory); if (empty($files)) { throw new FileNotFoundException($disk->path($baseDirectory)); @@ -630,7 +627,7 @@ public function decryptString(string $encryptedString): string if ($decryptedString === false) { throw new InvalidConfigurationException( - "There was an error decrypting the provided string. This might be due to mismatching crypto keys." + 'There was an error decrypting the provided string. This might be due to mismatching crypto keys.' ); } @@ -667,15 +664,15 @@ public function createTempFilePath(string $diskFilePath): string throw new Exception('Could not create a temporary file for dump.'); } - $handle = fopen($tempFilePath, 'w'); + $handle = fopen($tempFilePath, 'w'); if ($handle === false) { throw new Exception('Could not open temporary file for writing.'); } - $stream = $this->getDisk()->readStream($diskFilePath); + $stream = $this->getDisk()->readStream($diskFilePath); - if (!is_resource($stream)) { + if (! is_resource($stream)) { fclose($handle); throw new FileNotFoundException($diskFilePath); @@ -714,7 +711,7 @@ protected function shouldEncrypt(): bool */ public function guardExecEnabled(): void { - if (!function_exists('exec')) { + if (! function_exists('exec')) { throw new ShellAccessDeniedException(); } } @@ -752,7 +749,7 @@ protected function writeDumpFile( $outputHandle = fopen($this->getDisk()->path($destinationFilePath), 'wb'); // Stop when EOF is reached or an empty chunk was read. - while (!feof($resource) && $chunk = stream_get_contents($resource, $chunkSize)) { + while (! feof($resource) && $chunk = stream_get_contents($resource, $chunkSize)) { if ($sanctumEnabled) { $chunk = $this->decryptString($chunk); } @@ -765,7 +762,7 @@ protected function writeDumpFile( protected function determineEncryptionOverhead(int $chunkSize, string $publicKey): int { - $chunk = str_repeat('0', $chunkSize); + $chunk = str_repeat('0', $chunkSize); $encryptedChunk = sodium_crypto_box_seal($chunk, $publicKey); return strlen($encryptedChunk) - $chunkSize; @@ -778,8 +775,8 @@ protected function getProxyForSchemaState($schemaState): SchemaState { return match (get_class($schemaState)) { MySqlSchemaState::class => app(MySqlSchemaStateProxy::class, [$schemaState, $this]), -// PostgresSchemaState::class => app('PostgresSchemaStateProxy', [$schemaState, $this]), -// SqliteSchemaState::class => app('SqliteSchemaStateProxy', [$schemaState, $this]), + // PostgresSchemaState::class => app('PostgresSchemaStateProxy', [$schemaState, $this]), + // SqliteSchemaState::class => app('SqliteSchemaStateProxy', [$schemaState, $this]), default => throw new UnsupportedDatabaseException('Unsupported database schema state: '.class_basename($schemaState)), }; } diff --git a/src/ProtectorFacade.php b/src/ProtectorFacade.php index 1e6ee71..9df8104 100644 --- a/src/ProtectorFacade.php +++ b/src/ProtectorFacade.php @@ -11,8 +11,6 @@ class ProtectorFacade extends Facade { /** * Get the registered name of the component. - * - * @return string */ protected static function getFacadeAccessor(): string { diff --git a/src/ProtectorServiceProvider.php b/src/ProtectorServiceProvider.php index cfa6896..497edf7 100644 --- a/src/ProtectorServiceProvider.php +++ b/src/ProtectorServiceProvider.php @@ -14,8 +14,6 @@ class ProtectorServiceProvider extends ServiceProvider { /** * Bootstrap the application services. - * - * @return void */ public function boot(): void { @@ -29,7 +27,7 @@ public function boot(): void // Publish package config to app config space. $this->publishes([ - __DIR__ . '/../config/protector.php' => config_path('protector.php'), + __DIR__.'/../config/protector.php' => config_path('protector.php'), ], 'protector.config'); $this->publishMigrations(); @@ -37,13 +35,11 @@ public function boot(): void /** * Register the application services. - * - * @return void */ public function register(): void { // Automatically apply the package configuration. - $this->mergeConfigFrom(__DIR__ . '/../config/protector.php', 'protector'); + $this->mergeConfigFrom(__DIR__.'/../config/protector.php', 'protector'); // Register the main class to use with the facade. $this->app->singleton('protector', function () { diff --git a/src/Traits/HasConfiguration.php b/src/Traits/HasConfiguration.php index fda127d..5065e2a 100644 --- a/src/Traits/HasConfiguration.php +++ b/src/Traits/HasConfiguration.php @@ -71,7 +71,6 @@ trait HasConfiguration */ protected bool $removeAutoIncrementingState = false; - /** * Sets the auth token for Laravel Sanctum authentication. */ @@ -123,7 +122,7 @@ public function withoutData(): static /** * @throws InvalidConnectionException */ - public function withConnectionName(string $connectionName = null): static + public function withConnectionName(?string $connectionName = null): static { $this->connectionName = $connectionName ?? config('database.default'); @@ -148,7 +147,6 @@ public function withoutTablespaces(): static return $this; } - public function withMaxPacketLength(string $maxPacketLength): static { $this->maxPacketLength = $maxPacketLength; diff --git a/tests/TestCase.php b/tests/TestCase.php index 7d1a359..d358150 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,7 +5,6 @@ use Cybex\Protector\Protector; use Cybex\Protector\ProtectorServiceProvider; use Illuminate\Contracts\Filesystem\Filesystem; -use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Storage; use Orchestra\Testbench\TestCase as OrchestraTestCase; use ReflectionClass; @@ -29,7 +28,6 @@ protected function setUp(): void } /** - * @param $app * @return string[] */ protected function getPackageProviders($app): array @@ -51,10 +49,6 @@ protected function getAccessibleReflectionMethod(string $method): ReflectionMeth /** * Allows a test to call a protected method. - * - * @param string $methodName - * @param array $params - * @return mixed */ protected function runProtectedMethod(string $methodName, array $params = []): mixed { @@ -76,7 +70,7 @@ protected function getFakeDumpDisk(): Filesystem $disk = $this->getDumpDisk(); $baseDirectory = $this->protector->getBaseDirectory(); - foreach (glob(getcwd() . '/tests/dumps/*.sql') as $filename) { + foreach (glob(getcwd().'/tests/dumps/*.sql') as $filename) { Storage::disk('local')->putFileAs($baseDirectory, $filename, basename($filename)); } diff --git a/tests/feature/ExportDumpTest.php b/tests/feature/ExportDumpTest.php index 53c9608..4866a2b 100644 --- a/tests/feature/ExportDumpTest.php +++ b/tests/feature/ExportDumpTest.php @@ -15,7 +15,9 @@ class ExportDumpTest extends TestCase protected Filesystem $disk; protected string $baseDirectory; + protected string $filePath; + protected string $emptyDumpPath; protected function setUp(): void @@ -25,7 +27,7 @@ protected function setUp(): void $this->disk = $this->getFakeDumpDisk(); $this->baseDirectory = Config::get('protector.baseDirectory'); - $this->filePath = sprintf('%s/dump.sql', $this->baseDirectory); + $this->filePath = sprintf('%s/dump.sql', $this->baseDirectory); $this->emptyDumpPath = 'testDumps/dump.sql'; } @@ -36,7 +38,7 @@ public function createDestinationFilePath() { $this->disk->deleteDirectory(Config::get('protector.baseDirectory')); - $filePath = $this->protector->createDestinationFilePath(__FUNCTION__); + $filePath = $this->protector->createDestinationFilePath(__FUNCTION__); $destinationFilePath = $this->disk->path($filePath); $this->runProtectedMethod('createDirectory', [$filePath, $this->disk]); @@ -50,7 +52,7 @@ public function createDestinationFilePathWithSubFolder() { $this->disk->deleteDirectory(Config::get('protector.baseDirectory')); - $filePath = $this->protector->createDestinationFilePath(__FUNCTION__, __FUNCTION__); + $filePath = $this->protector->createDestinationFilePath(__FUNCTION__, __FUNCTION__); $destinationFilePath = $this->disk->path($filePath); $this->runProtectedMethod('createDirectory', [$filePath, $this->disk]); @@ -99,10 +101,10 @@ public function failGeneratingDumpWhenTryingToConnectToDatabase() { // Provide an database connection to a non-existing database. Config::set('database.connections.invalid', [ - 'driver' => 'mysql', - 'url' => env('DATABASE_URL'), - 'host' => env('DB_HOST', '127.0.0.1'), - 'port' => env('DB_PORT', '3306'), + 'driver' => 'mysql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), 'database' => 'invalid_database_name', 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), diff --git a/tests/feature/ImportDumpCommandTest.php b/tests/feature/ImportDumpCommandTest.php index 60ae583..f97464b 100644 --- a/tests/feature/ImportDumpCommandTest.php +++ b/tests/feature/ImportDumpCommandTest.php @@ -16,8 +16,11 @@ class ImportDumpCommandTest extends TestCase protected Filesystem $disk; protected string $serverUrl; + protected string $shouldDownloadDump; + protected string $shouldImportDump; + protected static string $baseDirectory = 'dumps'; protected function setUp(): void @@ -43,7 +46,7 @@ protected function setUp(): void */ public function failOnProductionEnvironment() { - $this->app->detectEnvironment(fn() => 'production'); + $this->app->detectEnvironment(fn () => 'production'); $this->expectException(InvalidEnvironmentException::class); @@ -98,7 +101,7 @@ public function getRemoteDumpOnImportDumpCommand() $this->artisan('protector:import --remote') ->expectsConfirmation($this->shouldImportDump); - $this->assertFileExists($this->disk->path(static::$baseDirectory . '/remote_dump.sql')); + $this->assertFileExists($this->disk->path(static::$baseDirectory.'/remote_dump.sql')); } /** @@ -185,13 +188,13 @@ public function failChooseImportDumpOnNoFilesInBaseDirectory() */ public function chooseImportDumpWithOnlyOneFileInBaseDirectory() { - $this->protector->flush(static::$baseDirectory . '/dump.sql'); + $this->protector->flush(static::$baseDirectory.'/dump.sql'); $this->assertCount(1, $this->protector->getDumpFiles()); $this->artisan('protector:import') ->expectsChoice($this->shouldDownloadDump, 2, ['Download remote dump', 'Import existing local dump']) - ->expectsOutput('Using file "' . static::$baseDirectory . '/dump.sql" because there are no other dumps.') + ->expectsOutput('Using file "'.static::$baseDirectory.'/dump.sql" because there are no other dumps.') ->expectsConfirmation($this->shouldImportDump); } } diff --git a/tests/feature/ImportDumpTest.php b/tests/feature/ImportDumpTest.php index 43065ec..aadba06 100644 --- a/tests/feature/ImportDumpTest.php +++ b/tests/feature/ImportDumpTest.php @@ -14,8 +14,11 @@ class ImportDumpTest extends TestCase { protected Filesystem $disk; + protected static string $baseDirectory = 'dumps'; + protected string $filePath; + protected Protector $protector; protected function setUp(): void @@ -28,14 +31,14 @@ protected function setUp(): void $this->disk = $this->getFakeDumpDisk(); - $this->filePath = getcwd() . '/tests/dumps/dump.sql'; + $this->filePath = getcwd().'/tests/dumps/dump.sql'; } public static function provideDumpMetadata(): array { return [ [ - static::$baseDirectory . "/dump.sql", + static::$baseDirectory.'/dump.sql', [ 'meta' => [ 'database' => 'protector-tests', @@ -54,13 +57,13 @@ public static function provideDumpMetadata(): array 'yday' => 179, 'weekday' => 'Wednesday', 'month' => 'June', - 0 => 1656506604 - ] - ] - ] + 0 => 1656506604, + ], + ], + ], ], [ - static::$baseDirectory . "/dumpWithGit.sql", + static::$baseDirectory.'/dumpWithGit.sql', [ 'meta' => [ 'database' => 'protector-tests', @@ -79,18 +82,18 @@ public static function provideDumpMetadata(): array 'yday' => 179, 'weekday' => 'Wednesday', 'month' => 'June', - 0 => 1656506604 - ] - ] - ] + 0 => 1656506604, + ], + ], + ], ], [ - static::$baseDirectory . "/dumpWithoutMetadata.sql", - [] + static::$baseDirectory.'/dumpWithoutMetadata.sql', + [], ], [ - static::$baseDirectory . "/dumpWithIncorrectMetadata.sql", - false + static::$baseDirectory.'/dumpWithIncorrectMetadata.sql', + false, ], ]; } @@ -99,13 +102,13 @@ public static function provideEmptyDumpsWhenReceivingTheLatestDumpName(): array { return [ [ - static::$baseDirectory . '/dump.sql', - false + static::$baseDirectory.'/dump.sql', + false, ], [ - static::$baseDirectory . '/secondDump.sql', - true - ] + static::$baseDirectory.'/secondDump.sql', + true, + ], ]; } @@ -114,12 +117,12 @@ public static function provideEmptyDumpsForFlushingDumps(): array return [ [ [], - null + null, ], [ - [static::$baseDirectory . '/emptyDump.sql'], - static::$baseDirectory . '/emptyDump.sql' - ] + [static::$baseDirectory.'/emptyDump.sql'], + static::$baseDirectory.'/emptyDump.sql', + ], ]; } @@ -128,7 +131,7 @@ public static function provideEmptyDumpsForFlushingDumps(): array */ public function failOnProductionEnvironment() { - $this->app->detectEnvironment(fn() => 'production'); + $this->app->detectEnvironment(fn () => 'production'); $this->expectException(InvalidEnvironmentException::class); $this->protector->importDump($this->filePath); @@ -171,6 +174,7 @@ public function throwsExceptionOnMysqlFailedShellCommand() /** * @test + * * @dataProvider provideEmptyDumpsWhenReceivingTheLatestDumpName */ public function canReturnLatestFileName(string $expectedFileName, bool $shouldModify) @@ -197,6 +201,7 @@ public function throwsExceptionIfNoFileExists() /** * @test + * * @dataProvider provideDumpMetadata */ public function verifyDumpDateMetaData($filePath, $expectedMetaData) @@ -209,11 +214,12 @@ public function verifyDumpDateMetaData($filePath, $expectedMetaData) */ public function failGetDumpMetaDataOnResponseHasNotEnoughLines() { - $this->assertEquals(false, $this->protector->getDumpMetaData(static::$baseDirectory . '/emptyDump.sql')); + $this->assertEquals(false, $this->protector->getDumpMetaData(static::$baseDirectory.'/emptyDump.sql')); } /** * @test + * * @dataProvider provideEmptyDumpsForFlushingDumps */ public function flushDumps($expected, $excludeFromFlush) diff --git a/tests/feature/RemoteDumpTest.php b/tests/feature/RemoteDumpTest.php index 894e51b..245897e 100644 --- a/tests/feature/RemoteDumpTest.php +++ b/tests/feature/RemoteDumpTest.php @@ -18,6 +18,7 @@ class RemoteDumpTest extends TestCase protected Filesystem $disk; protected string $serverUrl; + protected string $baseDirectory; protected function setUp(): void @@ -135,7 +136,7 @@ public function htaccessIsInRequestHeaderWhenSpecified() $this->protector->getRemoteDump(); Http::assertSent(function ($request) { - return $request->hasHeader('Authorization', 'Basic ' . base64_encode('1234:1234')); + return $request->hasHeader('Authorization', 'Basic '.base64_encode('1234:1234')); }); } @@ -329,7 +330,7 @@ public function canResolveBaseDirectoryFromClosure() { $functionName = __FUNCTION__; - Config::set('protector.baseDirectory', fn() => $functionName); + Config::set('protector.baseDirectory', fn () => $functionName); $result = $this->runProtectedMethod('getConfigValueForKey', ['baseDirectory']); @@ -338,6 +339,7 @@ public function canResolveBaseDirectoryFromClosure() /** * Sets the env key name for the private key. + * * @test */ public function validateUsersPrivateKeyName() From b83d9f1a543cb548e7fbeae7fcf41cdc104c89ff Mon Sep 17 00:00:00 2001 From: Gael Connan Date: Fri, 15 Mar 2024 17:25:31 +0100 Subject: [PATCH 3/3] add pint.json --- docker-compose.yml | 3 ++ pint.json | 37 ++++++++++++++++++++++ src/Classes/MySqlSchemaStateProxy.php | 16 +++++----- src/Commands/CreateToken.php | 2 +- src/Commands/ImportDump.php | 17 +++++----- src/Protector.php | 42 ++++++++++++------------- src/ProtectorServiceProvider.php | 4 +-- tests/TestCase.php | 2 +- tests/feature/ExportDumpTest.php | 3 -- tests/feature/ImportDumpCommandTest.php | 10 ++---- tests/feature/ImportDumpTest.php | 23 ++++++-------- tests/feature/RemoteDumpTest.php | 4 +-- 12 files changed, 95 insertions(+), 68 deletions(-) create mode 100644 pint.json diff --git a/docker-compose.yml b/docker-compose.yml index b51dc75..6215103 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: - '.:/var/www/html' networks: - internal + - shared depends_on: - mysql_testing mysql_testing: @@ -40,3 +41,5 @@ services: networks: internal: internal: true + shared: + external: true diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..0832b6e --- /dev/null +++ b/pint.json @@ -0,0 +1,37 @@ +{ + "preset": "laravel", + "rules": { + "blank_line_before_statement": { + "statements": [ + "break", + "continue", + "do", + "exit", + "for", + "foreach", + "if", + "phpdoc", + "return", + "switch", + "throw", + "try", + "while", + "yield", + "yield_from" + ] + }, + "class_attributes_separation": { + "elements": { + "const": "none", + "property": "none" + } + }, + "concat_space": { + "spacing": "one" + }, + "no_superfluous_phpdoc_tags": true, + "not_operator_with_successor_space": false, + "phpdoc_separation": true, + "phpdoc_trim_consecutive_blank_line_separation": true + } +} diff --git a/src/Classes/MySqlSchemaStateProxy.php b/src/Classes/MySqlSchemaStateProxy.php index a03e67a..aec9c39 100644 --- a/src/Classes/MySqlSchemaStateProxy.php +++ b/src/Classes/MySqlSchemaStateProxy.php @@ -45,14 +45,14 @@ public function load($path) */ protected function getCommandString(): string { - $command = 'mysqldump '.$this->schemaState->connectionString().' '; + $command = 'mysqldump ' . $this->schemaState->connectionString() . ' '; $conditionalParameters = [ - '--set-gtid-purged=OFF' => ! $this->schemaState->connection->isMaria(), - '--no-create-db' => ! $this->protector->shouldCreateDb(), - '--skip-comments' => ! $this->protector->shouldDumpComments(), - '--skip-set-charset' => ! $this->protector->shouldDumpCharsets(), - '--no-data' => ! $this->protector->shouldDumpData(), + '--set-gtid-purged=OFF' => !$this->schemaState->connection->isMaria(), + '--no-create-db' => !$this->protector->shouldCreateDb(), + '--skip-comments' => !$this->protector->shouldDumpComments(), + '--skip-set-charset' => !$this->protector->shouldDumpCharsets(), + '--no-data' => !$this->protector->shouldDumpData(), ]; $parameters = [ @@ -61,11 +61,11 @@ protected function getCommandString(): string '--tz-utc', '--column-statistics=0', '--result-file="${:LARAVEL_LOAD_PATH}"', - '--max-allowed-packet='.$this->protector->getMaxPacketLength(), + '--max-allowed-packet=' . $this->protector->getMaxPacketLength(), ...array_keys(array_filter($conditionalParameters)), '"${:LARAVEL_LOAD_DATABASE}"', ]; - return $command.implode(' ', $parameters); + return $command . implode(' ', $parameters); } } diff --git a/src/Commands/CreateToken.php b/src/Commands/CreateToken.php index 6047c2a..697149b 100644 --- a/src/Commands/CreateToken.php +++ b/src/Commands/CreateToken.php @@ -37,7 +37,7 @@ public function handle() $user->tokens()->whereAbilities('["protector:import"]')->delete(); $userInformation = sprintf('%s: %s (%s)', $user->id, $user->name, $user->email); - if (! $user->protector_public_key && ! $publicKey) { + if (!$user->protector_public_key && !$publicKey) { $this->error( 'The user doesn\'t have a protector public key and none was specified. Please provide a public key for the user.' ); diff --git a/src/Commands/ImportDump.php b/src/Commands/ImportDump.php index bef8bd6..ffc1915 100644 --- a/src/Commands/ImportDump.php +++ b/src/Commands/ImportDump.php @@ -44,7 +44,6 @@ class ImportDump extends Command protected $description = 'Imports a local or remote database dump.'; protected const DOWNLOAD_REMOTE_DUMP = 'Download remote dump'; - protected const IMPORT_EXISTING_LOCAL_DUMP = 'Import existing local dump'; protected ?Protector $protector = null; @@ -67,13 +66,13 @@ public function handle(): int $optionLatest = $this->option('latest'); $optionConnection = $this->option('connection'); - if (App::environment('production') && ! $this->option('allow-production')) { + if (App::environment('production') && !$this->option('allow-production')) { throw new InvalidEnvironmentException( 'Import is not allowed on production systems! Use --allow-production' ); } - if ($optionForce && ! ($optionRemote || $optionFile || $optionDump || $optionLatest)) { + if ($optionForce && !($optionRemote || $optionFile || $optionDump || $optionLatest)) { $this->error('Nothing to import.'); return self::FAILURE; @@ -82,7 +81,7 @@ public function handle(): int $this->protector->withConnectionName($optionConnection); $shouldImportLocalDump = $optionFile || $optionDump || $optionLatest; - $shouldDownloadDump = $optionRemote || (! $shouldImportLocalDump && $this->userWantsRemoteDump()); + $shouldDownloadDump = $optionRemote || (!$shouldImportLocalDump && $this->userWantsRemoteDump()); if ($shouldDownloadDump) { $importFilePath = $this->getRemoteDump(); @@ -98,7 +97,7 @@ public function handle(): int } if (empty($localFilePath)) { - if (! $importFilePath) { + if (!$importFilePath) { $this->error('Found no file to import.'); return self::FAILURE; @@ -109,7 +108,7 @@ public function handle(): int $this->importDump($localFilePath, $optionForce); - if (! $optionFile) { + if (!$optionFile) { unlink($localFilePath); } @@ -200,7 +199,7 @@ public function getMetaDataForFiles(array $directoryFiles): Collection foreach ($directoryFiles as $directoryFile) { $metaData = $this->protector->getDumpMetaData($directoryFile); - if ($this->option('ignore-connection-filter') || (! is_array($metaData) || empty($metaData))) { + if ($this->option('ignore-connection-filter') || (!is_array($metaData) || empty($metaData))) { $matchingFiles->push([ 'path' => $directoryFile, 'file' => basename($directoryFile), @@ -306,11 +305,11 @@ public function getConnectionFiles(?string $connectionName = null): Collection $filesByConnection = $sortedFiles->groupBy('connection'); - if ($connectionName && ! $filesByConnection->has($connectionName)) { + if ($connectionName && !$filesByConnection->has($connectionName)) { throw new InvalidConnectionException(); } - if (! $connectionName) { + if (!$connectionName) { $connectionName = $this->chooseConnectionName($filesByConnection->keys()); } diff --git a/src/Protector.php b/src/Protector.php index 6275491..1b2feaa 100644 --- a/src/Protector.php +++ b/src/Protector.php @@ -70,15 +70,15 @@ public function importDump(string $sourceFilePath, array $options = []): void $this->guardExecEnabled(); // Production environment is not allowed unless set in options. - if (App::environment('production') && ! Arr::get($options, 'allow-production')) { + if (App::environment('production') && !Arr::get($options, 'allow-production')) { throw new InvalidEnvironmentException('Production environment is not allowed and option was not set.'); } - if (! $this->connectionConfig) { + if (!$this->connectionConfig) { throw new InvalidConnectionException('Connection is not configured properly'); } - if (! file_exists($sourceFilePath)) { + if (!file_exists($sourceFilePath)) { throw new FileNotFoundException($sourceFilePath); } @@ -145,7 +145,7 @@ public function createDestinationFilePath(string $fileName, ?string $subFolder = */ public function createDump(array $options = []): string { - if (! $this->connectionConfig) { + if (!$this->connectionConfig) { throw new InvalidConnectionException('Connection is not configured properly.'); } @@ -183,7 +183,7 @@ public function getDumpMetaData(string $dumpFile): bool|array $decodedData = json_decode($matches['data'], true); // We store json-encoded arrays, if we do not get an array back, that means something went wrong. - if (! is_array($decodedData)) { + if (!is_array($decodedData)) { return false; } @@ -216,13 +216,13 @@ public function getRemoteDump(): string { $disk = $this->getDisk(); - if ($this->shouldEncrypt() && ! $this->getPrivateKey()) { + if ($this->shouldEncrypt() && !$this->getPrivateKey()) { throw new InvalidConfigurationException( 'For using Laravel Sanctum a crypto keypair is required. There was none found in your .env file.' ); } - if (! $serverUrl = $this->getServerUrl()) { + if (!$serverUrl = $this->getServerUrl()) { throw new InvalidConfigurationException('Server url is not set or invalid.'); } @@ -248,14 +248,14 @@ public function getRemoteDump(): string } } - if (! $response->ok()) { + if (!$response->ok()) { $httpCode = $response->status(); throw match ($httpCode) { - 401, 403 => new UnauthorizedHttpException('', $httpCode.' Unauthorized access'), - 404 => new NotFoundHttpException('404 Not found: '.$serverUrl), + 401, 403 => new UnauthorizedHttpException('', $httpCode . ' Unauthorized access'), + 404 => new NotFoundHttpException('404 Not found: ' . $serverUrl), 500 => new FailedRemoteDatabaseFetchingException($response->header('message')), - default => new HttpException($httpCode, 'Status code '.$httpCode), + default => new HttpException($httpCode, 'Status code ' . $httpCode), }; } @@ -330,7 +330,7 @@ protected function generateDump(array $options = []): ?string $schemaStateProxy->dump($connection, $tempFile); - if (! filesize($tempFile)) { + if (!filesize($tempFile)) { unlink($tempFile); $tempFile = null; @@ -386,7 +386,7 @@ public function createFilename(): string */ public function getMetaData(bool $refresh = false): array { - if (! $refresh && $this->metaDataCache) { + if (!$refresh && $this->metaDataCache) { return $this->metaDataCache; } @@ -422,7 +422,7 @@ protected function tail(string $file, int $lines, int $buffer = 1024): array // Open file-handle. $fileHandle = $this->getDisk()->readStream($file); - if (! is_resource($fileHandle)) { + if (!is_resource($fileHandle)) { throw new FileNotFoundException($file); } @@ -441,7 +441,7 @@ protected function tail(string $file, int $lines, int $buffer = 1024): array fseek($fileHandle, -$seekLength, SEEK_CUR); // Get the next content-chunk by using the according length. - $contents = ($chunk = fread($fileHandle, $seekLength)).$contents; + $contents = ($chunk = fread($fileHandle, $seekLength)) . $contents; // Reset pointer to the position before reading the current chunk. fseek($fileHandle, -mb_strlen($chunk, 'UTF-8'), SEEK_CUR); @@ -491,7 +491,7 @@ public function generateFileDownloadResponse( $shouldEncrypt = $this->shouldEncrypt(); // Only proceed when either Laravel Sanctum is turned off or the user's token is valid. - if (! $shouldEncrypt || $request->user()?->tokenCan('protector:import')) { + if (!$shouldEncrypt || $request->user()?->tokenCan('protector:import')) { if ($this->withConnectionName($connectionName)) { try { $serverFilePath = $this->createDump(); @@ -506,7 +506,7 @@ public function generateFileDownloadResponse( function () use ($publicKey, $serverFilePath, $chunkSize, $shouldEncrypt) { $inputHandle = fopen($serverFilePath, 'rb'); - while (! feof($inputHandle)) { + while (!feof($inputHandle)) { $chunk = fread($inputHandle, $chunkSize); // Encrypt the data when Laravel Sanctum is active. @@ -672,7 +672,7 @@ public function createTempFilePath(string $diskFilePath): string $stream = $this->getDisk()->readStream($diskFilePath); - if (! is_resource($stream)) { + if (!is_resource($stream)) { fclose($handle); throw new FileNotFoundException($diskFilePath); @@ -711,7 +711,7 @@ protected function shouldEncrypt(): bool */ public function guardExecEnabled(): void { - if (! function_exists('exec')) { + if (!function_exists('exec')) { throw new ShellAccessDeniedException(); } } @@ -749,7 +749,7 @@ protected function writeDumpFile( $outputHandle = fopen($this->getDisk()->path($destinationFilePath), 'wb'); // Stop when EOF is reached or an empty chunk was read. - while (! feof($resource) && $chunk = stream_get_contents($resource, $chunkSize)) { + while (!feof($resource) && $chunk = stream_get_contents($resource, $chunkSize)) { if ($sanctumEnabled) { $chunk = $this->decryptString($chunk); } @@ -777,7 +777,7 @@ protected function getProxyForSchemaState($schemaState): SchemaState MySqlSchemaState::class => app(MySqlSchemaStateProxy::class, [$schemaState, $this]), // PostgresSchemaState::class => app('PostgresSchemaStateProxy', [$schemaState, $this]), // SqliteSchemaState::class => app('SqliteSchemaStateProxy', [$schemaState, $this]), - default => throw new UnsupportedDatabaseException('Unsupported database schema state: '.class_basename($schemaState)), + default => throw new UnsupportedDatabaseException('Unsupported database schema state: ' . class_basename($schemaState)), }; } } diff --git a/src/ProtectorServiceProvider.php b/src/ProtectorServiceProvider.php index 497edf7..0b22937 100644 --- a/src/ProtectorServiceProvider.php +++ b/src/ProtectorServiceProvider.php @@ -27,7 +27,7 @@ public function boot(): void // Publish package config to app config space. $this->publishes([ - __DIR__.'/../config/protector.php' => config_path('protector.php'), + __DIR__ . '/../config/protector.php' => config_path('protector.php'), ], 'protector.config'); $this->publishMigrations(); @@ -39,7 +39,7 @@ public function boot(): void public function register(): void { // Automatically apply the package configuration. - $this->mergeConfigFrom(__DIR__.'/../config/protector.php', 'protector'); + $this->mergeConfigFrom(__DIR__ . '/../config/protector.php', 'protector'); // Register the main class to use with the facade. $this->app->singleton('protector', function () { diff --git a/tests/TestCase.php b/tests/TestCase.php index d358150..a27036e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -70,7 +70,7 @@ protected function getFakeDumpDisk(): Filesystem $disk = $this->getDumpDisk(); $baseDirectory = $this->protector->getBaseDirectory(); - foreach (glob(getcwd().'/tests/dumps/*.sql') as $filename) { + foreach (glob(getcwd() . '/tests/dumps/*.sql') as $filename) { Storage::disk('local')->putFileAs($baseDirectory, $filename, basename($filename)); } diff --git a/tests/feature/ExportDumpTest.php b/tests/feature/ExportDumpTest.php index 4866a2b..166b739 100644 --- a/tests/feature/ExportDumpTest.php +++ b/tests/feature/ExportDumpTest.php @@ -13,11 +13,8 @@ class ExportDumpTest extends TestCase { protected Filesystem $disk; - protected string $baseDirectory; - protected string $filePath; - protected string $emptyDumpPath; protected function setUp(): void diff --git a/tests/feature/ImportDumpCommandTest.php b/tests/feature/ImportDumpCommandTest.php index f97464b..8315f64 100644 --- a/tests/feature/ImportDumpCommandTest.php +++ b/tests/feature/ImportDumpCommandTest.php @@ -14,13 +14,9 @@ class ImportDumpCommandTest extends TestCase { protected Filesystem $disk; - protected string $serverUrl; - protected string $shouldDownloadDump; - protected string $shouldImportDump; - protected static string $baseDirectory = 'dumps'; protected function setUp(): void @@ -101,7 +97,7 @@ public function getRemoteDumpOnImportDumpCommand() $this->artisan('protector:import --remote') ->expectsConfirmation($this->shouldImportDump); - $this->assertFileExists($this->disk->path(static::$baseDirectory.'/remote_dump.sql')); + $this->assertFileExists($this->disk->path(static::$baseDirectory . '/remote_dump.sql')); } /** @@ -188,13 +184,13 @@ public function failChooseImportDumpOnNoFilesInBaseDirectory() */ public function chooseImportDumpWithOnlyOneFileInBaseDirectory() { - $this->protector->flush(static::$baseDirectory.'/dump.sql'); + $this->protector->flush(static::$baseDirectory . '/dump.sql'); $this->assertCount(1, $this->protector->getDumpFiles()); $this->artisan('protector:import') ->expectsChoice($this->shouldDownloadDump, 2, ['Download remote dump', 'Import existing local dump']) - ->expectsOutput('Using file "'.static::$baseDirectory.'/dump.sql" because there are no other dumps.') + ->expectsOutput('Using file "' . static::$baseDirectory . '/dump.sql" because there are no other dumps.') ->expectsConfirmation($this->shouldImportDump); } } diff --git a/tests/feature/ImportDumpTest.php b/tests/feature/ImportDumpTest.php index aadba06..2c1aa98 100644 --- a/tests/feature/ImportDumpTest.php +++ b/tests/feature/ImportDumpTest.php @@ -14,11 +14,8 @@ class ImportDumpTest extends TestCase { protected Filesystem $disk; - protected static string $baseDirectory = 'dumps'; - protected string $filePath; - protected Protector $protector; protected function setUp(): void @@ -31,14 +28,14 @@ protected function setUp(): void $this->disk = $this->getFakeDumpDisk(); - $this->filePath = getcwd().'/tests/dumps/dump.sql'; + $this->filePath = getcwd() . '/tests/dumps/dump.sql'; } public static function provideDumpMetadata(): array { return [ [ - static::$baseDirectory.'/dump.sql', + static::$baseDirectory . '/dump.sql', [ 'meta' => [ 'database' => 'protector-tests', @@ -63,7 +60,7 @@ public static function provideDumpMetadata(): array ], ], [ - static::$baseDirectory.'/dumpWithGit.sql', + static::$baseDirectory . '/dumpWithGit.sql', [ 'meta' => [ 'database' => 'protector-tests', @@ -88,11 +85,11 @@ public static function provideDumpMetadata(): array ], ], [ - static::$baseDirectory.'/dumpWithoutMetadata.sql', + static::$baseDirectory . '/dumpWithoutMetadata.sql', [], ], [ - static::$baseDirectory.'/dumpWithIncorrectMetadata.sql', + static::$baseDirectory . '/dumpWithIncorrectMetadata.sql', false, ], ]; @@ -102,11 +99,11 @@ public static function provideEmptyDumpsWhenReceivingTheLatestDumpName(): array { return [ [ - static::$baseDirectory.'/dump.sql', + static::$baseDirectory . '/dump.sql', false, ], [ - static::$baseDirectory.'/secondDump.sql', + static::$baseDirectory . '/secondDump.sql', true, ], ]; @@ -120,8 +117,8 @@ public static function provideEmptyDumpsForFlushingDumps(): array null, ], [ - [static::$baseDirectory.'/emptyDump.sql'], - static::$baseDirectory.'/emptyDump.sql', + [static::$baseDirectory . '/emptyDump.sql'], + static::$baseDirectory . '/emptyDump.sql', ], ]; } @@ -214,7 +211,7 @@ public function verifyDumpDateMetaData($filePath, $expectedMetaData) */ public function failGetDumpMetaDataOnResponseHasNotEnoughLines() { - $this->assertEquals(false, $this->protector->getDumpMetaData(static::$baseDirectory.'/emptyDump.sql')); + $this->assertEquals(false, $this->protector->getDumpMetaData(static::$baseDirectory . '/emptyDump.sql')); } /** diff --git a/tests/feature/RemoteDumpTest.php b/tests/feature/RemoteDumpTest.php index 245897e..2f75cf5 100644 --- a/tests/feature/RemoteDumpTest.php +++ b/tests/feature/RemoteDumpTest.php @@ -16,9 +16,7 @@ class RemoteDumpTest extends TestCase { protected Filesystem $disk; - protected string $serverUrl; - protected string $baseDirectory; protected function setUp(): void @@ -136,7 +134,7 @@ public function htaccessIsInRequestHeaderWhenSpecified() $this->protector->getRemoteDump(); Http::assertSent(function ($request) { - return $request->hasHeader('Authorization', 'Basic '.base64_encode('1234:1234')); + return $request->hasHeader('Authorization', 'Basic ' . base64_encode('1234:1234')); }); }