public override async Task <ValidationResult> ValidateAsync(PackageValidationMessage message, List <PackageValidationAuditEntry> auditEntries) { var temporaryFile = Path.GetTempFileName(); using (var httpClient = new HttpClient()) { try { using (var packageStream = await httpClient.GetStreamAsync(message.Package.DownloadUrl)) { using (var packageFileStream = File.Open(temporaryFile, FileMode.OpenOrCreate)) { await packageStream.CopyToAsync(packageFileStream); _logger.LogInformation($"Downloaded package from {{{TraceConstant.Url}}}", message.Package.DownloadUrl); WriteAuditEntry(auditEntries, $"Downloaded package from {message.Package.DownloadUrl}", ValidationEvent.PackageDownloaded); packageFileStream.Position = 0; using (var packageZipStream = Package.Open(packageFileStream)) { var parts = packageZipStream.GetParts(); _logger.LogInformation("Found {PartsCount} parts in package.", parts.Count()); WriteAuditEntry(auditEntries, $"Found {parts.Count()} parts in package.", ValidationEvent.UnzipSucceeeded); return(ValidationResult.Succeeded); } } } } catch (Exception ex) { _logger.TrackValidatorException(ValidatorName, message.ValidationId, ex, message.PackageId, message.PackageVersion); WriteAuditEntry(auditEntries, $"Exception thrown during validation - {ex.Message}\r\n{ex.StackTrace}", ValidationEvent.ValidatorException); return(ValidationResult.Failed); } finally { try { File.Delete(temporaryFile); } catch { // best-effort } } } }
protected string GetPackageUrl(PackageValidationMessage message) { string packageUrl; if (message.Package.DownloadUrl != null) { packageUrl = message.Package.DownloadUrl.AbsoluteUri; } else { packageUrl = BuildStorageUrl(message.Package.Id, message.PackageVersion); } return(packageUrl); }
public FactsBase() { _callbackUrl = new Uri("http://example/callback"); _packageUrlTemplate = "http://example/packages/{id}/{version}/{id}.{version}.nupkg"; _scanningService = new Mock <IVirusScanningService>(); _logger = new Mock <ILogger <VcsValidator> >(); _message = new PackageValidationMessage { PackageId = "NuGet.Versioning", PackageVersion = "3.4.0-ALPHA", ValidationId = new Guid("f470b9fb-0243-4f65-8aef-90d93dfe1a03"), Package = new NuGetPackage { Id = "NuGet.Versioning", NormalizedVersion = "3.4.0-ALPHA" } }; _auditEntries = new List <PackageValidationAuditEntry>(); _virusScanJob = new VirusScanJob { JobId = "123", RequestId = "456", RegionCode = "USW", }; _scanningService .Setup(x => x.CreateVirusScanJobAsync(It.IsAny <string>(), It.IsAny <Uri>(), It.IsAny <string>(), It.IsAny <Guid>())) .Returns(() => Task.FromResult(_virusScanJob)); _target = new VcsValidator( _callbackUrl, _packageUrlTemplate, _scanningService.Object, _logger.Object); }
public abstract Task <ValidationResult> ValidateAsync(PackageValidationMessage message, List <PackageValidationAuditEntry> auditEntries);
public override async Task <ValidationResult> ValidateAsync(PackageValidationMessage message, List <PackageValidationAuditEntry> auditEntries) { var description = $"NuGet - {message.ValidationId} - {message.PackageId} {message.PackageVersion}"; _logger.LogInformation("Submitting virus scan job with description {description}, " + $" {{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}} " + $" for package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}}", description, Name, message.ValidationId, message.PackageId, message.PackageVersion); WriteAuditEntry(auditEntries, $"Submitting virus scan job with description \"{description}\"...", ValidationEvent.BeforeVirusScanRequest); string errorMessage; try { var result = await _scanningService.CreateVirusScanJobAsync( BuildStorageUrl(message.Package.Id, message.PackageVersion), _callbackUrl, description, message.ValidationId); if (string.IsNullOrEmpty(result.ErrorMessage)) { _logger.LogInformation("Submission completed for " + $"{{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}}. " + $"package {{{TraceConstant.PackageId}}} " + $"{{{TraceConstant.PackageVersion}}} " + "Request id: {RequestId} - job id: {JobId} - region code: {RegionCode}", Name, message.ValidationId, message.PackageId, message.PackageVersion, result.RequestId, result.JobId, result.RegionCode); WriteAuditEntry(auditEntries, $"Submission completed. Request id: {result.RequestId} " + $"- job id: {result.JobId} " + $"- region code: {result.RegionCode}", ValidationEvent.VirusScanRequestSent); return(ValidationResult.Asynchronous); } else { errorMessage = result.ErrorMessage; _logger.LogError($"Submission failed for {{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}} " + $"package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}} " + "with: {ErrorMessage}", Name, message.ValidationId, message.PackageId, message.PackageVersion, errorMessage); } } catch (Exception ex) { errorMessage = ex.Message; _logger.TrackValidatorException(ValidatorName, message.ValidationId, ex, message.PackageId, message.PackageVersion); } WriteAuditEntry(auditEntries, $"Submission failed. Error message: {errorMessage}", ValidationEvent.VirusScanRequestFailed); return(ValidationResult.Failed); }
public override async Task <ValidationResult> ValidateAsync(PackageValidationMessage message, List <PackageValidationAuditEntry> auditEntries) { var description = $"NuGet - {message.ValidationId} - {message.PackageId} {message.PackageVersion}"; _logger.LogInformation("Submitting virus scan job with description {description}, " + $" {{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}} " + $" for package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}}", description, Name, message.ValidationId, message.PackageId, message.PackageVersion); WriteAuditEntry(auditEntries, $"Submitting virus scan job with description \"{description}\"...", ValidationEvent.BeforeVirusScanRequest); string errorMessage; try { var packageUrl = GetPackageUrl(message); // VCS requires a package URL that is either a direct URL to Azure Blob Storage or a UNC share file // path. Azure Blob Storage URLs with SAS tokens in them are accepted. var result = await _scanningService.CreateVirusScanJobAsync( packageUrl, _callbackUrl, description, message.ValidationId); if (IsValidJobResult(result)) { _logger.LogInformation("Submission completed for " + $"{{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}}. " + $"package {{{TraceConstant.PackageId}}} " + $"{{{TraceConstant.PackageVersion}}} " + "Request id: {RequestId} - job id: {JobId} - region code: {RegionCode}", Name, message.ValidationId, message.PackageId, message.PackageVersion, result.RequestId, result.JobId, result.RegionCode); WriteAuditEntry(auditEntries, $"Submission completed. Request id: {result.RequestId} " + $"- job id: {result.JobId} " + $"- region code: {result.RegionCode}", ValidationEvent.VirusScanRequestSent); return(ValidationResult.Asynchronous); } else { errorMessage = result.ErrorMessage ?? "The request had no request ID, job ID, and region code."; _logger.LogError($"Submission failed for {{{TraceConstant.ValidatorName}}} {{{TraceConstant.ValidationId}}} " + $"package {{{TraceConstant.PackageId}}} " + $"v. {{{TraceConstant.PackageVersion}}} " + "with: {ErrorMessage}", Name, message.ValidationId, message.PackageId, message.PackageVersion, errorMessage); WriteAuditEntry(auditEntries, $"Submission failed. Error message: {errorMessage}", ValidationEvent.VirusScanRequestFailed); throw new ValidationException(errorMessage); } } catch (Exception ex) { errorMessage = ex.Message; _logger.TrackValidatorException(ValidatorName, message.ValidationId, ex, message.PackageId, message.PackageVersion); WriteAuditEntry(auditEntries, $"Submission failed. Error message: {errorMessage}", ValidationEvent.VirusScanRequestFailed); throw; } }