using System; using System.IO; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using MalwareMultiScan.Api.Data.Configuration; using MalwareMultiScan.Api.Data.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.GridFS; namespace MalwareMultiScan.Api.Services { public class ScanResultService { private const string CollectionName = "ScanResults"; private readonly IMongoCollection _collection; private readonly GridFSBucket _bucket; private readonly ScanBackendService _scanBackendService; public ScanResultService(IMongoDatabase db, ScanBackendService scanBackendService) { _scanBackendService = scanBackendService; _collection = db.GetCollection(CollectionName); _bucket = new GridFSBucket(db); } public async Task CreateScanResult() { var scanResult = new ScanResult { Results = _scanBackendService.List.ToDictionary( k => k.Id, v => new ScanResultEntry()) }; await _collection.InsertOneAsync(scanResult); return scanResult; } public async Task GetScanResult(string id) { var result = await _collection.FindAsync( Builders.Filter.Where(r => r.Id == id)); return await result.FirstOrDefaultAsync(); } public async Task UpdateScanResultForBackend(string resultId, string backendId, bool completed = false, bool succeeded = false, string[] threats = null) { var filterScanResult = Builders.Filter.Where(r => r.Id == resultId); var updateScanResult = Builders.Update.Set(r => r.Results[backendId], new ScanResultEntry { Completed = completed, Succeeded = succeeded, Threats = threats }); await _collection.UpdateOneAsync(filterScanResult, updateScanResult); } public async Task QueueUrlScan(ScanResult result, string fileUrl) { foreach (var backend in _scanBackendService.List) await _scanBackendService.QueueUrlScan(result, backend, fileUrl); } public async Task StoreFile(string fileName, Stream fileStream) { var objectId = await _bucket.UploadFromStreamAsync( fileName, fileStream); return objectId.ToString(); } public async Task ObtainFile(string id) { if (!ObjectId.TryParse(id, out var objectId)) return null; return await _bucket.OpenDownloadStreamAsync(objectId, new GridFSDownloadOptions { Seekable = true }); } } }