diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 7036b1a31..29780f164 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -36,12 +36,33 @@ class StartPostgresql "echo 'Creating directories.'", "mkdir -p $this->configuration_dir", "mkdir -p $this->configuration_dir/docker-entrypoint-initdb.d/", - "mkdir -p $this->configuration_dir/ssl", "echo 'Directories created successfully.'", ]; - if ($this->database->enable_ssl) { + if (! $this->database->enable_ssl) { + $this->commands[] = "rm -rf $this->configuration_dir/ssl"; + + SslCertificate::where('resource_type', $this->database->getMorphClass()) + ->where('resource_id', $this->database->id) + ->delete(); + + $this->database->fileStorages() + ->where('resource_type', $this->database->getMorphClass()) + ->where('resource_id', $this->database->id) + ->get() + ->filter(function ($storage) { + return in_array($storage->mount_path, [ + '/var/lib/postgresql/certs/server.crt', + '/var/lib/postgresql/certs/server.key', + ]); + }) + ->each(function ($storage) { + $storage->delete(); + }); + } else { $this->commands[] = "echo 'Setting up SSL for this database.'"; + $this->commands[] = "rm -rf $this->configuration_dir/ssl"; + $this->commands[] = "mkdir -p $this->configuration_dir/ssl"; $server = $this->database->destination->server; $caCert = SslCertificate::where('server_id', $server->id)->firstOrFail(); @@ -57,8 +78,8 @@ class StartPostgresql serverId: $server->id, caCert: $caCert->ssl_certificate, caKey: $caCert->ssl_private_key, + configurationDir: $this->configuration_dir, ); - $this->addSslFilesToFileStorage(); } } @@ -300,27 +321,4 @@ class StartPostgresql $content_base64 = base64_encode($content); $this->commands[] = "echo '{$content_base64}' | base64 -d | tee $config_file_path > /dev/null"; } - - private function addSslFilesToFileStorage() - { - if (! $this->ssl_certificate) { - return; - } - - $this->database->fileStorages()->create([ - 'fs_path' => $this->configuration_dir.'/ssl/server.crt', - 'mount_path' => '/var/lib/postgresql/certs/server.crt', - 'content' => $this->ssl_certificate->ssl_certificate, - 'is_directory' => false, - 'chmod' => '644', - ]); - - $this->database->fileStorages()->create([ - 'fs_path' => $this->configuration_dir.'/ssl/server.key', - 'mount_path' => '/var/lib/postgresql/certs/server.key', - 'content' => $this->ssl_certificate->ssl_private_key, - 'is_directory' => false, - 'chmod' => '600', - ]); - } } diff --git a/app/Helpers/SslHelper.php b/app/Helpers/SslHelper.php index ffa2279e8..960c90a1b 100644 --- a/app/Helpers/SslHelper.php +++ b/app/Helpers/SslHelper.php @@ -23,7 +23,8 @@ class SslHelper int $validityDays = 365, ?string $caCert = null, ?string $caKey = null, - bool $isCaCertificate = false + bool $isCaCertificate = false, + ?string $configurationDir = null ): SslCertificate { try { @@ -101,17 +102,58 @@ class SslHelper ->where('server_id', $serverId) ->delete(); - return SslCertificate::create([ + $sslCertificate = SslCertificate::create([ 'ssl_certificate' => $certificateStr, 'ssl_private_key' => $privateKeyStr, 'resource_type' => $resourceType, 'resource_id' => $resourceId, 'server_id' => $serverId, + 'configuration_dir' => $configurationDir, 'valid_until' => CarbonImmutable::now()->addDays($validityDays), 'is_ca_certificate' => $isCaCertificate, 'common_name' => $commonName, 'subject_alternative_names' => $subjectAlternativeNames, ]); + + if ($configurationDir && $resourceType && $resourceId) { + $model = app($resourceType)->find($resourceId); + + $model->fileStorages() + ->where('resource_type', $model->getMorphClass()) + ->where('resource_id', $model->id) + ->get() + ->filter(function ($storage) { + return in_array($storage->mount_path, [ + '/var/lib/postgresql/certs/server.crt', + '/var/lib/postgresql/certs/server.key', + ]); + }) + ->each(function ($storage) { + $storage->delete(); + }); + + $model->fileStorages()->create([ + 'fs_path' => $configurationDir.'/ssl/server.crt', + 'mount_path' => '/var/lib/postgresql/certs/server.crt', + 'content' => $certificateStr, + 'is_directory' => false, + 'chmod' => '644', + 'resource_type' => $resourceType, + 'resource_id' => $resourceId, + ]); + + $model->fileStorages()->create([ + 'fs_path' => $configurationDir.'/ssl/server.key', + 'mount_path' => '/var/lib/postgresql/certs/server.key', + 'content' => $privateKeyStr, + 'is_directory' => false, + 'chmod' => '600', + 'resource_type' => $resourceType, + 'resource_id' => $resourceId, + ]); + } + + return $sslCertificate; } catch (\Throwable $e) { throw new \RuntimeException('SSL Certificate generation failed: '.$e->getMessage(), 0, $e); } diff --git a/app/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php index f0e3d064e..cb8cefc76 100644 --- a/app/Livewire/Project/Database/Postgresql/General.php +++ b/app/Livewire/Project/Database/Postgresql/General.php @@ -144,6 +144,7 @@ class General extends Component serverId: $existingCert->server_id, caCert: $caCert->ssl_certificate, caKey: $caCert->ssl_private_key, + configurationDir: $existingCert->configuration_dir, ); $this->dispatch('success', 'SSL certificates have been regenerated. Please restart the database for changes to take effect.'); diff --git a/app/Models/SslCertificate.php b/app/Models/SslCertificate.php index 7298afd6c..cf9395a5d 100644 --- a/app/Models/SslCertificate.php +++ b/app/Models/SslCertificate.php @@ -9,6 +9,7 @@ class SslCertificate extends Model protected $fillable = [ 'ssl_certificate', 'ssl_private_key', + 'configuration_dir', 'resource_type', 'resource_id', 'server_id', diff --git a/database/migrations/2025_01_27_153741_create_ssl_certificates_table.php b/database/migrations/2025_01_27_153741_create_ssl_certificates_table.php index 023482055..1e7da5eb0 100644 --- a/database/migrations/2025_01_27_153741_create_ssl_certificates_table.php +++ b/database/migrations/2025_01_27_153741_create_ssl_certificates_table.php @@ -12,6 +12,7 @@ return new class extends Migration $table->id(); $table->text('ssl_certificate'); $table->text('ssl_private_key'); + $table->text('configuration_dir')->nullable(); $table->string('resource_type')->nullable(); $table->unsignedBigInteger('resource_id')->nullable(); $table->unsignedBigInteger('server_id');