ikechukwukalu / clamavfileupload
使用ClamAV进行文件上传病毒扫描
v3.0.1
2024-06-18 08:17 UTC
Requires
- php: >=8.0
- illuminate/broadcasting: ^9.0|^10.0|^11.0
- illuminate/contracts: ^9.0|^10.0|^11.0
- illuminate/database: ^9.0|^10.0|^11.0
- illuminate/events: ^9.0|^10.0|^11.0
- illuminate/http: ^9.0|^10.0|^11.0
- illuminate/queue: ^9.0|^10.0|^11.0
- illuminate/support: ^9.0|^10.0|^11.0
- symfony/http-foundation: ^5.4|^6.0|^7.0
Requires (Dev)
- mockery/mockery: ^1.0|^2.0
- orchestra/testbench: ^6.0|^7.0|^8.0|^9.0
- php-parallel-lint/php-parallel-lint: dev-develop
- phpunit/phpunit: ^9.0|^10.0|^11.0
README
这是一个简单的具有ClamAV病毒扫描功能的文件上传Laravel包。这个库是在现有的clamav php库 kissit/php-clamav-scan 上构建的。
要求
- PHP 8.0+
- Laravel 9+
- Clamav
安装步骤
composer require ikechukwukalu/clamavfileupload
php artisan vendor:publish --tag=cfu-config
CLAMD_SOCK="/var/run/clamav/clamd.sock"
CLAMD_SOCK_LEN=20000
CLAMD_IP=null
CLAMD_PORT=3310
FILE_UPLOAD_INPUT=file
FILE_UPLOAD_DISK=public
FILE_UPLOAD_LOG_SCAN_DATA=false
HASHED=false
VISIBLE=true
php artisan vendor:publish --tag=cfu-migrations
php artisan migrate
CLAMAV病毒扫描文件上传
use Ikechukwukalu\Clamavfileupload\Facades\Services\FileUpload; FileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection /** * Default settings * * 'name' => null // This is different from file name * 'input' => config('clamavfileupload.input', 'file') * 'folder' => null * 'hashed' => config('clamavfileupload.hashed', false) * 'visible' => config('clamavfileupload.visible', true) * 'disk' => config('clamavfileupload.disk', 'local') * * */ /** * You can also overwrite the default settings with custom settings */ $settings = [ 'folder' => 'pdfs' ]; $fileUpload = new FileUpload; $fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection /** * Access last scan results */ $fileUpload::getScanData() /** * Check if upload was successful */ if (!$fileUpload::isSuccessful()) { echo $fileUpload::getErrorMessage(); } /** * Make sure to save the $ref UUID so as to be * able to retrieve the uploaded file(s) from the database. */ $fileUpload::getRef() /** * Soft delete files */ /** * @param string $ref * @return bool */ FileUpload::deleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ FileUpload::deleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ FileUpload::deleteOne($id, $ref); /** * Permanently delete files from the database and disk */ /** * @param string $ref * @return bool */ FileUpload::forceDeleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ FileUpload::forceDeleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ FileUpload::forceDeleteOne($id, $ref);
队列中的CLAMAV病毒扫描文件上传
此过程将文件存储在tmp
目录中,并为clamav扫描设置队列,并将tmp
文件上传到指定的目录。在过程结束时,临时文件将从tmp
目录中删除。
- 要使用
Redis
,请在您的.env
文件中设置REDIS_CLIENT=predis
和QUEUE_CONNECTION=redis
。 php artisan queue:work
use Ikechukwukalu\Clamavfileupload\Facades\Services\QueuedFileUpload; QueuedFileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection /** * Default settings * * 'name' => null // This is different from file name * 'input' => config('clamavfileupload.input', 'file') * 'folder' => null * 'hashed' => config('clamavfileupload.hashed', false) * 'visible' => config('clamavfileupload.visible', true) * 'disk' => config('clamavfileupload.disk', 'local') * * */ /** * You can also overwrite the default settings with custom settings */ $settings = [ 'folder' => 'pdfs' ]; $fileUpload = new QueuedFileUpload; $fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection /** * Make sure to save the $ref UUID so as to be * able to retrieve the uploaded file(s) from the database. */ $fileUpload::getRef() /** * Soft delete files */ /** * @param string $ref * @return bool */ QueuedFileUpload::deleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ QueuedFileUpload::deleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ QueuedFileUpload::deleteOne($id, $ref); /** * Permanently delete files from the database and disk */ /** * @param string $ref * @return bool */ QueuedFileUpload::forceDeleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ QueuedFileUpload::forceDeleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ QueuedFileUpload::forceDeleteOne($id, $ref);
无CLAMAV病毒扫描文件上传
use Ikechukwukalu\Clamavfileupload\Facades\Services\NoClamavFileUpload; NoClamavFileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection /** * Default settings * * 'name' => null // This is different from file name * 'input' => config('clamavfileupload.input', 'file') * 'folder' => null * 'hashed' => config('clamavfileupload.hashed', false) * 'visible' => config('clamavfileupload.visible', true) * 'disk' => config('clamavfileupload.disk', 'local') * * */ /** * You can also overwrite the default settings with custom settings */ $settings = [ 'folder' => 'pdfs' ]; $fileUpload = new NoClamavFileUpload; $fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection /** * Check if upload was successful */ if (!$fileUpload::isSuccessful()) { echo $fileUpload::getErrorMessage(); } /** * Make sure to save the $ref UUID so as to be * able to retrieve the uploaded file(s) from the database. */ $fileUpload::getRef() /** * Soft delete files */ /** * @param string $ref * @return bool */ NoClamavFileUpload::deleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ NoClamavFileUpload::deleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ NoClamavFileUpload::deleteOne($id, $ref); /** * Permanently delete files from the database and disk */ /** * @param string $ref * @return bool */ NoClamavFileUpload::forceDeleteAll($ref); /** * @param array $ids * @param string $ref * @return bool */ NoClamavFileUpload::forceDeleteMultiple($ids, $ref); /** * @param int $id * @param string $ref * @return bool */ NoClamavFileUpload::forceDeleteOne($id, $ref);
哈希
如果您的.env
文件中的HASHED
参数设置为true
,则在将它们保存到数据库之前,将加密file_name
、path
和url
字段。存储的文件也将被加密。
扩展模型文件Ikechukwukalu\Clamavfileupload\Models\FileUpload
并添加以下代码可能会有所帮助
use Illuminate\Support\Facades\Crypt; protected function getFileNameAttribute($value) { if ($this->hashed) { return Crypt::decryptString($value); } return $value; } protected function getPathAttribute($value) { if ($this->hashed) { return Crypt::decryptString($value); } return $value; } protected function getRelativePathAttribute($value) { if ($this->hashed) { return Crypt::decryptString($value); } return $value; } protected function getUrlAttribute($value) { if ($this->hashed) { return Crypt::decryptString($value); } return $value; }
查看和下载加密文件的示例代码
use Illuminate\Http\Request; use Ikechukwukalu\Clamavfileupload\Models\FileUpload as FileUploadModel; use Symfony\Component\HttpFoundation\StreamedResponse; Route::get('/download/hashed/file/{id}', function (Request $request, $id): StreamedResponse { $file = FileUploadModel::where('id', $id)->first() return response()->streamDownload(function () use($file) { echo Crypt::decrypt(Storage::disk($file->disk)->get($file->relative_path)); }, "{$file->name}{$file->extension}"); }); Route::get('/view/hashed/file/{id}', function (Request $request, $id) { $file = FileUploadModel::where('id', $id)->first(); $decrypted = Crypt::decrypt(Storage::disk($file->disk)->get($file->relative_path)); header("Content-type: {$file->mime_type}"); echo $decrypted; });
事件
/** * Dispatches when FileUpload::uploadFiles() * is called. * */ \Ikechukwukalu\Clamavfileupload\Events\ClamavFileScan::class /** * Dispatches when QueuedFileUpload::uploadFiles() * is called. * * @param array $tmpFiles * @param array $settings * @param string $ref */ \Ikechukwukalu\Clamavfileupload\Events\ClamavQueuedFileScan::class /** * Dispatches when all files scanned are safe. * * @param array $scanData */ \Ikechukwukalu\Clamavfileupload\Events\FileScanPass::class /** * Dispatches when a file scanned has a problem. * * @param array $scanData */ \Ikechukwukalu\Clamavfileupload\Events\FileScanFail::class /** * Dispatches when files have been stored and saved into the Database. * * @param FileUploadModel|EloquentCollection $files * @param string $ref */ \Ikechukwukalu\Clamavfileupload\Events\SavedFilesIntoDB::class /** * Dispatches when clamav is not running. * */ \Ikechukwukalu\Clamavfileupload\Events\ClamavIsNotRunning::class /** * Dispatches when file soft delete fails. * * @param array $data */ \Ikechukwukalu\Clamavfileupload\Events\FileDeleteFail::class /** * Dispatches when file soft delete passes. * * @param array $data */ \Ikechukwukalu\Clamavfileupload\Events\FileDeletePass::class /** * Dispatches when permanent file delete from database and disk fails. * * @param array $data */ \Ikechukwukalu\Clamavfileupload\Events\FileForceDeleteFail::class /** * Dispatches when permanent file delete from database and disk passes. * * @param array $data */ \Ikechukwukalu\Clamavfileupload\Events\FileForceDeletePass::class /** * Dispatches when a QueuedFileUpload::deleteAll($ref) is called. * * @param string $ref */ \Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteAll::class /** * Dispatches when a QueuedFileUpload::deleteMultiple($ids, $ref) is called. * * @param string $ref * @param array $ids */ \Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteMultiple::class /** * Dispatches when a QueuedFileUpload::deleteOne($id, $ref) is called. * * @param string $ref * @param int|string $id */ \Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteOne::class /** * Dispatches when a QueuedFileUpload::forceDeleteAll($ref) is called. * * @param string $ref */ \Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteAll::class /** * Dispatches when a QueuedFileUpload::forceDeleteMultiple($ids, $ref) is called. * * @param string $ref * @param array $ids */ \Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteMultiple::class /** * Dispatches when a QueuedFileUpload::forceDeleteOne($id, $ref) is called. * * @param string $ref * @param int|string $id */ \Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteOne::class
注意
- 当单个文件扫描失败时,过程结束,并将删除所有上传的文件。
- 每个上传文件批次都会分配一个
$ref
UUID。 - 当使用
s3
磁盘时,文件首先存储在tmp
目录中,使用local
磁盘,然后在上传到s3
存储桶之前进行扫描。 - 始终在配置文件中将自定义的
s3
磁盘添加到s3_disk
数组中。 - 模型文件
Ikechukwukalu\Clamavfileupload\Models\FileUpload
protected $fillable = [ 'ref', 'name', 'file_name', 'size', 'extension', 'disk', 'mime_type', 'path', 'url', 'folder', 'hashed', ];
发布语言
php artisan vendor:publish --tag=cfu-lang
许可证
CFU包是开源软件,根据MIT许可证授权。