protected function scanFile(FileRecord $file) { $virusTotal = new VirusTotalFile(config('virustotal.api_key')); if ($file->shouldCheckScan()) { $this->info(sprintf('Checking scan for file: %s (#%d)', $file->client_name, $file->id)); $this->throttler->throttle(1); $result = $virusTotal->getReport($file->hash); $file->scan_checked_at = Carbon::now(); $file->save(); if ($result['response_code'] === 1) { $scannedAt = new Carbon($result['scan_date']); $cutoff = new Carbon('-2 weeks'); // Check if this scan record already exists in DB $exists = Scan::where('virustotal_scan_id', '=', $result['scan_id'])->count() > 0; if ($scannedAt->gte($cutoff) && !$exists) { /** @var Scan $scan */ $scan = Scan::create(['file_record_id' => $file->id, 'virustotal_scan_id' => $result['scan_id'], 'total' => $result['total'], 'positives' => $result['positives'], 'scanned_at' => $scannedAt, 'scans' => $result['scans']]); $this->info(sprintf('Scan result: %d/%d', $scan->positives, $scan->total)); // We now have a report from a requested scan $file->scan_requested_at = null; $file->save(); $deleted = $this->actionScanResult($file, $scan); if ($deleted) { // Nothing else to do if deleted return; } } } } if ($file->shouldScanFile()) { // Max filesize for public API is 32mb if ($file->filesize <= 32 * pow(1024, 2)) { $this->info(sprintf('Uploading file for scan: %s (#%d)', $file->client_name, $file->id)); $this->throttler->throttle(1); $result = $virusTotal->scan($file->filePath()); if ($result['response_code'] === 1) { $file->scan_requested_at = Carbon::now(); $file->save(); } } else { // TODO: private API } } elseif ($file->shouldRescanFile()) { $this->info(sprintf('Requesting re-scan for file: %s (#%d)', $file->client_name, $file->id)); $this->throttler->throttle(1); $result = $virusTotal->rescan($file->hash); if ($result['response_code'] === 1) { $file->scan_requested_at = Carbon::now(); $file->save(); } } }