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.
This commit is contained in:
Daeng Deni Mardaeni
2025-07-12 13:41:46 +07:00
parent c264d63fa6
commit 92afe58e66
4 changed files with 98 additions and 14 deletions

View File

@@ -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}");

View File

@@ -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}";

View File

@@ -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

View File

@@ -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}");