Skip to content

Commit

Permalink
feat: revamp key generation command (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
rjindael committed Aug 14, 2023
1 parent b16532a commit 2172b89
Showing 1 changed file with 105 additions and 14 deletions.
119 changes: 105 additions & 14 deletions src/Commands/GenerateKeyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,117 @@
namespace Spatie\LaravelCipherSweet\Commands;

use Illuminate\Console\Command;
use ParagonIE\ConstantTime\Hex;
use Illuminate\Console\ConfirmableTrait;

#[AsCommand(name: 'ciphersweet:generate-key')]

Check failure on line 8 in src/Commands/GenerateKeyCommand.php

View workflow job for this annotation

GitHub Actions / phpstan

Attribute class Spatie\LaravelCipherSweet\Commands\AsCommand does not exist.

Check failure on line 8 in src/Commands/GenerateKeyCommand.php

View workflow job for this annotation

GitHub Actions / phpstan

Attribute class Spatie\LaravelCipherSweet\Commands\AsCommand does not exist.
class GenerateKeyCommand extends Command
{
protected $signature = 'ciphersweet:generate-key';
use ConfirmableTrait;

protected $description = 'Generate a CipherSweet encryption key';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ciphersweet:generate-key
{--show : Display the CipherSweet key instead of modifying files}
{--force : Force the operation to run when in production}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Set the CipherSweet key';

/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$encryptionKey = Hex::encode(random_bytes(32));

$this->info('Here is your new encryption key');
$this->info('');
$this->info($encryptionKey);
$this->info('');
$this->info('First, you should add this line to your .env file');
$this->info("CIPHERSWEET_KEY={$encryptionKey}");
$this->info('');
$this->info('Next, you may encrypt your model values using this command');
$this->info("ciphersweet:encrypt <MODEL-CLASS> {$encryptionKey}");
$key = $this->generateRandomKey();

if ($this->option('show')) {
$this->line('<comment>' . $key . '</comment>');
return;
}

if (!$this->setKeyInEnvironmentFile($key)) {
return;
}

$this->laravel['config']['ciphersweet.providers.string.key'] = $key;

$this->components->info('CipherSweet key set successfully.');
}

/**
* Generate a random CipherSweet key.
*
* @return string
*/
protected function generateRandomKey(): string
{
return bin2hex(random_bytes(32));
}

/**
* Set the CipherSweet key in the environment file.
*
* @param string $key
* @return bool
*/
protected function setKeyInEnvironmentFile($key): bool
{
$currentKey = $this->laravel['config']['ciphersweet.providers.string.key'];

if (strlen($currentKey) !== 0 && (!$this->confirmToProceed())) {
return false;
}

if (!$this->writeNewEnvironmentFileWith($key)) {
return false;
}

return true;
}

/**
* Write a new environment file with the given CipherSweet key.
*
* @param string $key
* @return bool
*/
protected function writeNewEnvironmentFileWith($key)
{
$replaced = preg_replace(
$this->keyReplacementPattern(),
'CIPHERSWEET_KEY=' . $key,
$input = file_get_contents($this->laravel->environmentFilePath())
);

if ($replaced === $input || $replaced === null) {
$this->error('Unable to set CipherSweet key. No CIPHERSWEET_KEY variable was found in the .env file.');

return false;
}

file_put_contents($this->laravel->environmentFilePath(), $replaced);

return true;
}

/**
* Get a regex pattern that will match env CIPHERSWEET_KEY with any random key.
*
* @return string
*/
protected function keyReplacementPattern()
{
$escaped = preg_quote('=' . $this->laravel['config']['ciphersweet.providers.string.key'], '/');

return "/^CIPHERSWEET_KEY{$escaped}/m";
}
}

0 comments on commit 2172b89

Please sign in to comment.