refactor: Update PrivateKey model to improve code readability and maintainability
This commit is contained in:
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use OpenApi\Attributes as OA;
|
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use OpenApi\Attributes as OA;
|
||||||
use phpseclib3\Crypt\PublicKeyLoader;
|
use phpseclib3\Crypt\PublicKeyLoader;
|
||||||
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
|
|
||||||
|
|
||||||
#[OA\Schema(
|
#[OA\Schema(
|
||||||
description: 'Private Key model',
|
description: 'Private Key model',
|
||||||
@@ -45,7 +45,7 @@ class PrivateKey extends BaseModel
|
|||||||
static::saving(function ($key) {
|
static::saving(function ($key) {
|
||||||
$key->private_key = formatPrivateKey($key->private_key);
|
$key->private_key = formatPrivateKey($key->private_key);
|
||||||
|
|
||||||
if (!self::validatePrivateKey($key->private_key)) {
|
if (! self::validatePrivateKey($key->private_key)) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'private_key' => ['The private key is invalid.'],
|
'private_key' => ['The private key is invalid.'],
|
||||||
]);
|
]);
|
||||||
@@ -73,6 +73,7 @@ class PrivateKey extends BaseModel
|
|||||||
public static function ownedByCurrentTeam(array $select = ['*'])
|
public static function ownedByCurrentTeam(array $select = ['*'])
|
||||||
{
|
{
|
||||||
$selectArray = collect($select)->concat(['id']);
|
$selectArray = collect($select)->concat(['id']);
|
||||||
|
|
||||||
return self::whereTeamId(currentTeam()->id)->select($selectArray->all());
|
return self::whereTeamId(currentTeam()->id)->select($selectArray->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +81,7 @@ class PrivateKey extends BaseModel
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
PublicKeyLoader::load($privateKey);
|
PublicKeyLoader::load($privateKey);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -91,13 +93,14 @@ class PrivateKey extends BaseModel
|
|||||||
$privateKey = new self($data);
|
$privateKey = new self($data);
|
||||||
$privateKey->save();
|
$privateKey->save();
|
||||||
$privateKey->storeInFileSystem();
|
$privateKey->storeInFileSystem();
|
||||||
|
|
||||||
return $privateKey;
|
return $privateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateNewKeyPair($type = 'rsa')
|
public static function generateNewKeyPair($type = 'rsa')
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$instance = new self();
|
$instance = new self;
|
||||||
$instance->rateLimit(10);
|
$instance->rateLimit(10);
|
||||||
$name = generate_random_name();
|
$name = generate_random_name();
|
||||||
$description = 'Created by Coolify';
|
$description = 'Created by Coolify';
|
||||||
@@ -110,7 +113,7 @@ class PrivateKey extends BaseModel
|
|||||||
'public_key' => $keyPair['public'],
|
'public_key' => $keyPair['public'],
|
||||||
];
|
];
|
||||||
} catch (\Throwable $e) {
|
} 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 {
|
try {
|
||||||
$key = PublicKeyLoader::load($privateKey);
|
$key = PublicKeyLoader::load($privateKey);
|
||||||
|
|
||||||
return $key->getPublicKey()->toString('OpenSSH', ['comment' => '']);
|
return $key->getPublicKey()->toString('OpenSSH', ['comment' => '']);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return null;
|
return null;
|
||||||
@@ -138,7 +142,11 @@ class PrivateKey extends BaseModel
|
|||||||
public function storeInFileSystem()
|
public function storeInFileSystem()
|
||||||
{
|
{
|
||||||
$filename = "ssh_key@{$this->uuid}";
|
$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);
|
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}";
|
return "/var/www/html/storage/app/ssh/keys/{$filename}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +165,7 @@ class PrivateKey extends BaseModel
|
|||||||
{
|
{
|
||||||
$this->update($data);
|
$this->update($data);
|
||||||
$this->storeInFileSystem();
|
$this->storeInFileSystem();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,10 +199,12 @@ class PrivateKey extends BaseModel
|
|||||||
|
|
||||||
public function safeDelete()
|
public function safeDelete()
|
||||||
{
|
{
|
||||||
if (!$this->isInUse()) {
|
if (! $this->isInUse()) {
|
||||||
$this->delete();
|
$this->delete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +213,7 @@ class PrivateKey extends BaseModel
|
|||||||
try {
|
try {
|
||||||
$key = PublicKeyLoader::load($privateKey);
|
$key = PublicKeyLoader::load($privateKey);
|
||||||
$publicKey = $key->getPublicKey();
|
$publicKey = $key->getPublicKey();
|
||||||
|
|
||||||
return $publicKey->getFingerprint('sha256');
|
return $publicKey->getFingerprint('sha256');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use App\Models\PrivateKey;
|
use App\Models\PrivateKey;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Illuminate\Support\Facades\Process;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class PopulateSshKeysDirectorySeeder extends Seeder
|
class PopulateSshKeysDirectorySeeder extends Seeder
|
||||||
{
|
{
|
||||||
@@ -12,11 +13,17 @@ class PopulateSshKeysDirectorySeeder extends Seeder
|
|||||||
{
|
{
|
||||||
Storage::disk('ssh-keys')->deleteDirectory('');
|
Storage::disk('ssh-keys')->deleteDirectory('');
|
||||||
Storage::disk('ssh-keys')->makeDirectory('');
|
Storage::disk('ssh-keys')->makeDirectory('');
|
||||||
|
Storage::disk('ssh-mux')->deleteDirectory('');
|
||||||
|
Storage::disk('ssh-mux')->makeDirectory('');
|
||||||
|
|
||||||
PrivateKey::chunk(100, function ($keys) {
|
PrivateKey::chunk(100, function ($keys) {
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
|
echo 'Storing key: '.$key->name."\n";
|
||||||
$key->storeInFileSystem();
|
$key->storeInFileSystem();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Process::run('chown -R 9999:9999 '.storage_path('app/ssh/keys'));
|
||||||
|
Process::run('chown -R 9999:9999 '.storage_path('app/ssh/mux'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -123,6 +123,7 @@ class ProductionSeeder extends Seeder
|
|||||||
]);
|
]);
|
||||||
$server->update(['user' => $user]);
|
$server->update(['user' => $user]);
|
||||||
echo "SSH key found for the Coolify host machine (localhost).\n";
|
echo "SSH key found for the Coolify host machine (localhost).\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PrivateKey::create(
|
PrivateKey::create(
|
||||||
[
|
[
|
||||||
|
Reference in New Issue
Block a user