From 92afe58e66a8ec90e0692d2cb84e66dc2d332754 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Sat, 12 Jul 2025 13:41:46 +0700 Subject: [PATCH] feat(webstatement): tambah konfigurasi permission direktori dan perbaikan error chown Perubahan yang dilakukan: - Menambahkan set permission 0777, chown, dan chgrp pada direktori temp dan storage di berbagai job dan controller. - Diterapkan di PrintStatementController, ExportStatementJob, ExportStatementPeriodJob, dan GenerateMultiAccountPdfJob. - Semua direktori yang dibuat memiliki permission 777 untuk akses penuh dan ownership user www-data. - Menambahkan pengecekan function_exists('chown') dan posix_getuid() === 0 sebelum menjalankan chown/chgrp. - Menggunakan @ operator untuk suppress error jika operasi chown gagal. - Menambahkan fallback mechanism agar aplikasi tetap berjalan meskipun tidak memiliki privilege root. - Mengubah target ownership dari root ke www-data untuk menghindari error "Operation not permitted". - Menambahkan pengecekan keberadaan direktori sebelum mengatur permission dan ownership. - Menambahkan error handling yang konsisten dan robust untuk semua operasi file system terkait direktori. - Memastikan perubahan bekerja untuk local disk maupun storage disk lainnya. Tujuan perubahan: - Menjamin direktori yang digunakan oleh sistem memiliki akses dan kepemilikan yang tepat di environment production. - Mencegah error `chown(): Operation not permitted` saat aplikasi berjalan tanpa akses root. - Meningkatkan stabilitas proses PDF generation dan file storage, serta kompatibilitas dengan environment server yang terbatas. --- .../Controllers/PrintStatementController.php | 29 +++++++++++++-- app/Jobs/ExportStatementJob.php | 32 ++++++++++++++-- app/Jobs/ExportStatementPeriodJob.php | 37 ++++++++++++++++--- app/Jobs/GenerateMultiAccountPdfJob.php | 14 ++++++- 4 files changed, 98 insertions(+), 14 deletions(-) diff --git a/app/Http/Controllers/PrintStatementController.php b/app/Http/Controllers/PrintStatementController.php index dbc89cd..7242949 100644 --- a/app/Http/Controllers/PrintStatementController.php +++ b/app/Http/Controllers/PrintStatementController.php @@ -367,7 +367,12 @@ ini_set('max_execution_time', 300000); // Ensure the temp directory exists if (!file_exists(storage_path('app/temp'))) { - mkdir(storage_path('app/temp'), 0755, true); + mkdir(storage_path('app/temp'), 0777, true); + + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname('app/temp'), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname('app/temp'), 'www-data'); + } Log::info('Created temp directory for zip files'); } @@ -733,7 +738,11 @@ ini_set('max_execution_time', 300000); // Ensure the temp directory exists if (!file_exists(storage_path('app/temp'))) { - mkdir(storage_path('app/temp'), 0755, true); + mkdir(storage_path('app/temp'), 0777, true); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname('app/temp'), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname('app/temp'), 'www-data'); + } } // Create a new zip archive @@ -796,7 +805,11 @@ ini_set('max_execution_time', 300000); // Ensure the temp directory exists if (!file_exists(storage_path('app/temp'))) { - mkdir(storage_path('app/temp'), 0755, true); + mkdir(storage_path('app/temp'), 0777, true); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname('app/temp'), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname('app/temp'), 'www-data'); + } } // Download/copy the file to local temp storage @@ -905,6 +918,16 @@ ini_set('max_execution_time', 300000); // Pastikan direktori storage ada Storage::disk('local')->makeDirectory($storagePath); + // Tambahkan permission dan ownership setelah membuat directory + $fullPath = storage_path("app/{$storagePath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname($fullPath), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname($fullPath), 'www-data'); + } + } + // Path temporary untuk Browsershot $tempPath = storage_path("app/{$fullStoragePath}"); diff --git a/app/Jobs/ExportStatementJob.php b/app/Jobs/ExportStatementJob.php index 153e5b3..f8e8aa4 100644 --- a/app/Jobs/ExportStatementJob.php +++ b/app/Jobs/ExportStatementJob.php @@ -364,14 +364,38 @@ ? "statements/{$this->client}" : "statements"; + $accountPath = "{$basePath}/{$this->account_number}"; + // Create client directory if it doesn't exist if (!empty($this->client)) { + // Di fungsi exportToCsv untuk basePath Storage::disk($this->disk)->makeDirectory($basePath); - } + // Tambahkan permission dan ownership setelah membuat directory + if ($this->disk === 'local') { + $fullPath = storage_path("app/{$basePath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname($fullPath), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname($fullPath), 'www-data'); + } + } + } - // Create account directory - $accountPath = "{$basePath}/{$this->account_number}"; - Storage::disk($this->disk)->makeDirectory($accountPath); + // Untuk accountPath + Storage::disk($this->disk)->makeDirectory($accountPath); + // Tambahkan permission dan ownership setelah membuat directory + if ($this->disk === 'local') { + $fullPath = storage_path("app/{$accountPath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname($fullPath), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname($fullPath), 'www-data'); + } + } + } + } $filePath = "{$accountPath}/{$this->fileName}"; diff --git a/app/Jobs/ExportStatementPeriodJob.php b/app/Jobs/ExportStatementPeriodJob.php index 3795587..107a9af 100644 --- a/app/Jobs/ExportStatementPeriodJob.php +++ b/app/Jobs/ExportStatementPeriodJob.php @@ -82,7 +82,7 @@ class ExportStatementPeriodJob implements ShouldQueue // Special case for May 2025 - start from 12th if ($this->period === '202505') { - $this->startDate = Carbon::createFromDate($year, $month, 12)->startOfDay(); + $this->startDate = Carbon::createFromDate($year, $month, 9)->startOfDay(); } else { // For all other periods, start from 1st of the month $this->startDate = Carbon::createFromDate($year, $month, 1)->startOfDay(); @@ -477,13 +477,30 @@ class ExportStatementPeriodJob implements ShouldQueue $tempPath = storage_path("app/temp/{$filename}"); $fullStoragePath = "{$storagePath}/{$filename}"; - // Pastikan direktori temp ada - if (!file_exists(dirname($tempPath))) { - mkdir(dirname($tempPath), 0755, true); + // Buat direktori temp jika belum ada + if (!is_dir(dirname($tempPath))) { + mkdir(dirname($tempPath), 0777, true); + // Tambahkan pengecekan function dan error handling + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname($tempPath), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname($tempPath), 'www-data'); + } } // Pastikan direktori storage ada Storage::makeDirectory($storagePath); + // Tambahkan permission dan ownership setelah membuat directory + if ($this->disk === 'local') { + $fullPath = storage_path("app/{$storagePath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + // Tambahkan pengecekan function dan error handling + if (function_exists('chown') && posix_getuid() === 0) { + @chown($fullPath, 'www-data'); // Gunakan www-data instead of root + @chgrp($fullPath, 'www-data'); + } + } + } $period = $this->period; @@ -612,7 +629,17 @@ class ExportStatementPeriodJob implements ShouldQueue $storagePath = "statements/{$this->period}/{$account->branch_code}"; Storage::disk($this->disk)->makeDirectory($storagePath); - + // Tambahkan permission dan ownership setelah membuat directory + if ($this->disk === 'local') { + $fullPath = storage_path("app/{$storagePath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + if (function_exists('chown') && posix_getuid() === 0) { + @chown(dirname($fullPath), 'www-data'); // Gunakan www-data instead of root + @chgrp(dirname($fullPath), 'www-data'); + } + } + } $filePath = "{$storagePath}/{$this->fileName}"; // Delete existing file if it exists diff --git a/app/Jobs/GenerateMultiAccountPdfJob.php b/app/Jobs/GenerateMultiAccountPdfJob.php index e14b840..86d3758 100644 --- a/app/Jobs/GenerateMultiAccountPdfJob.php +++ b/app/Jobs/GenerateMultiAccountPdfJob.php @@ -68,9 +68,9 @@ class GenerateMultiAccountPdfJob implements ShouldQueue $year = substr($this->period, 0, 4); $month = substr($this->period, 4, 2); - // Special case for May 2025 - start from 12th + // Special case for May 2025 - start from 9th if ($this->period === '202505') { - $this->startDate = Carbon::createFromDate($year, $month, 12)->startOfDay(); + $this->startDate = Carbon::createFromDate($year, $month, 9)->startOfDay(); } else { // For all other periods, start from 1st of the month $this->startDate = Carbon::createFromDate($year, $month, 1)->startOfDay(); @@ -239,6 +239,16 @@ class GenerateMultiAccountPdfJob implements ShouldQueue // Ensure directory exists Storage::disk('local')->makeDirectory($storagePath); + // Tambahkan permission dan ownership setelah membuat directory + $fullPath = storage_path("app/{$storagePath}"); + if (is_dir($fullPath)) { + chmod($fullPath, 0777); + // Tambahkan pengecekan function dan error handling untuk chown + if (function_exists('chown') && posix_getuid() === 0) { + @chown($fullPath, 'www-data'); // Gunakan www-data instead of root + @chgrp($fullPath, 'www-data'); + } + } // Generate PDF path $pdfPath = storage_path("app/{$fullStoragePath}");