refactor: Update PrivateKey model to improve code readability and maintainability

This commit is contained in:
Andras Bacsai
2024-09-20 12:27:55 +02:00
parent b81f9114d9
commit 5b00b66f24
3 changed files with 36 additions and 16 deletions

View File

@@ -2,11 +2,11 @@
namespace App\Models;
use OpenApi\Attributes as OA;
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\ValidationException;
use OpenApi\Attributes as OA;
use phpseclib3\Crypt\PublicKeyLoader;
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
#[OA\Schema(
description: 'Private Key model',
@@ -44,8 +44,8 @@ class PrivateKey extends BaseModel
{
static::saving(function ($key) {
$key->private_key = formatPrivateKey($key->private_key);
if (!self::validatePrivateKey($key->private_key)) {
if (! self::validatePrivateKey($key->private_key)) {
throw ValidationException::withMessages([
'private_key' => ['The private key is invalid.'],
]);
@@ -73,6 +73,7 @@ class PrivateKey extends BaseModel
public static function ownedByCurrentTeam(array $select = ['*'])
{
$selectArray = collect($select)->concat(['id']);
return self::whereTeamId(currentTeam()->id)->select($selectArray->all());
}
@@ -80,6 +81,7 @@ class PrivateKey extends BaseModel
{
try {
PublicKeyLoader::load($privateKey);
return true;
} catch (\Throwable $e) {
return false;
@@ -91,18 +93,19 @@ class PrivateKey extends BaseModel
$privateKey = new self($data);
$privateKey->save();
$privateKey->storeInFileSystem();
return $privateKey;
}
public static function generateNewKeyPair($type = 'rsa')
{
try {
$instance = new self();
$instance = new self;
$instance->rateLimit(10);
$name = generate_random_name();
$description = 'Created by Coolify';
$keyPair = generateSSHKey($type === 'ed25519' ? 'ed25519' : 'rsa');
return [
'name' => $name,
'description' => $description,
@@ -110,7 +113,7 @@ class PrivateKey extends BaseModel
'public_key' => $keyPair['public'],
];
} catch (\Throwable $e) {
throw new \Exception("Failed to generate new {$type} key: " . $e->getMessage());
throw new \Exception("Failed to generate new {$type} key: ".$e->getMessage());
}
}
@@ -118,6 +121,7 @@ class PrivateKey extends BaseModel
{
try {
$key = PublicKeyLoader::load($privateKey);
return $key->getPublicKey()->toString('OpenSSH', ['comment' => '']);
} catch (\Throwable $e) {
return null;
@@ -128,7 +132,7 @@ class PrivateKey extends BaseModel
{
$isValid = self::validatePrivateKey($privateKey);
$publicKey = $isValid ? self::extractPublicKeyFromPrivate($privateKey) : '';
return [
'isValid' => $isValid,
'publicKey' => $publicKey,
@@ -138,12 +142,16 @@ class PrivateKey extends BaseModel
public function storeInFileSystem()
{
$filename = "ssh_key@{$this->uuid}";
echo 'Storing key: '.$filename."\n".'Private key: '.$this->private_key."\n";
Storage::disk('ssh-keys')->put($filename, $this->private_key);
$file = Storage::disk('ssh-keys')->get($filename);
echo 'File: '.$file."\n";
return "/var/www/html/storage/app/ssh/keys/{$filename}";
}
public static function deleteFromStorage(self $privateKey)
{
{
$filename = "ssh_key@{$privateKey->uuid}";
Storage::disk('ssh-keys')->delete($filename);
}
@@ -157,6 +165,7 @@ class PrivateKey extends BaseModel
{
$this->update($data);
$this->storeInFileSystem();
return $this;
}
@@ -182,18 +191,20 @@ class PrivateKey extends BaseModel
public function isInUse()
{
return $this->servers()->exists()
|| $this->applications()->exists()
|| $this->githubApps()->exists()
return $this->servers()->exists()
|| $this->applications()->exists()
|| $this->githubApps()->exists()
|| $this->gitlabApps()->exists();
}
public function safeDelete()
{
if (!$this->isInUse()) {
if (! $this->isInUse()) {
$this->delete();
return true;
}
return false;
}
@@ -202,6 +213,7 @@ class PrivateKey extends BaseModel
try {
$key = PublicKeyLoader::load($privateKey);
$publicKey = $key->getPublicKey();
return $publicKey->getFingerprint('sha256');
} catch (\Throwable $e) {
return null;
@@ -211,7 +223,7 @@ class PrivateKey extends BaseModel
private static function fingerprintExists($fingerprint, $excludeId = null)
{
$query = self::where('fingerprint', $fingerprint);
if ($excludeId) {
$query->where('id', '!=', $excludeId);
}

View File

@@ -2,9 +2,10 @@
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Storage;
use App\Models\PrivateKey;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Process;
use Illuminate\Support\Facades\Storage;
class PopulateSshKeysDirectorySeeder extends Seeder
{
@@ -12,11 +13,17 @@ class PopulateSshKeysDirectorySeeder extends Seeder
{
Storage::disk('ssh-keys')->deleteDirectory('');
Storage::disk('ssh-keys')->makeDirectory('');
Storage::disk('ssh-mux')->deleteDirectory('');
Storage::disk('ssh-mux')->makeDirectory('');
PrivateKey::chunk(100, function ($keys) {
foreach ($keys as $key) {
echo 'Storing key: '.$key->name."\n";
$key->storeInFileSystem();
}
});
Process::run('chown -R 9999:9999 '.storage_path('app/ssh/keys'));
Process::run('chown -R 9999:9999 '.storage_path('app/ssh/mux'));
}
}

View File

@@ -123,6 +123,7 @@ class ProductionSeeder extends Seeder
]);
$server->update(['user' => $user]);
echo "SSH key found for the Coolify host machine (localhost).\n";
} else {
PrivateKey::create(
[