public async Task ExpiredThresholdCausesRecordUpdate()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser   = new ConfigurationParser("config.sample.yaml");
            var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var id             = this.GetCveId();
            var now            = DateTime.UtcNow;
            var expirationDate = now.AddDays(-(parser.Get().Cache.CveTtl + 1));
            var oldCve         = new CveEntity
            {
                CveId       = id,
                Severity    = joseki.db.entities.CveSeverity.Medium,
                PackageName = Guid.NewGuid().ToString(),
                Title       = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString(),
                Remediation = Guid.NewGuid().ToString(),
                References  = Guid.NewGuid().ToString(),
                DateUpdated = expirationDate,
                DateCreated = expirationDate,
            };

            // this is the hack -_-
            // Use sync version, because it does not update DateUpdated & DateCreated
            context.Cve.Add(oldCve);
            context.SaveChanges();

            var newCve = new CVE
            {
                Id          = id,
                Description = Guid.NewGuid().ToString(),
                Remediation = Guid.NewGuid().ToString(),
                Severity    = CveSeverity.High,
                PackageName = Guid.NewGuid().ToString(),
                Title       = Guid.NewGuid().ToString(),
                References  = Guid.NewGuid().ToString(),
            };

            // Act & Assert
            context.Cve.Count().Should().Be(1, "context should have the only one record before GetOrAddItem");
            await cveCache.GetOrAddItem(id, () => newCve);

            var actualEntity = await context.Cve.FirstAsync(i => i.CveId == id);

            actualEntity.Description.Should().Be(newCve.Description);
            actualEntity.Remediation.Should().Be(newCve.Remediation);
            actualEntity.PackageName.Should().Be(newCve.PackageName);
            actualEntity.Title.Should().Be(newCve.Title);
            actualEntity.References.Should().Be(newCve.References);
            actualEntity.Severity.Should().Be(joseki.db.entities.CveSeverity.High);
            actualEntity.DateUpdated.Should().BeOnOrAfter(now);
        }
        public async Task ProcessScanResultWithoutCVEs()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser   = new ConfigurationParser("config.sample.yaml");
            var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var blobsMock = new Mock <IBlobStorageProcessor>(MockBehavior.Strict);
            var dbMock    = new Mock <IJosekiDatabase>();

            var processor = new TrivyAuditProcessor(blobsMock.Object, dbMock.Object, cveCache);

            var container = new ScannerContainer(Path.Combine("audits", "samples", "trivy"))
            {
                Metadata = new ScannerMetadata
                {
                    Type = ScannerType.Trivy,
                    Id   = Guid.NewGuid().ToString(),
                },
            };
            var audit = new AuditBlob {
                Name = "meta_no_cve.json", ParentContainer = container
            };

            blobsMock
            .Setup(i => i.GetUnprocessedAudits(container))
            .ReturnsAsync(new[] { audit })
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/{audit.Name}"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/{audit.Name}"))
            .Verifiable();
            blobsMock
            .Setup(i => i.DownloadFile($"{container.Name}/result_no_cves.json"))
            .ReturnsAsync(File.OpenRead($"{container.Name}/result_no_cves.json"))
            .Verifiable();
            blobsMock
            .Setup(i => i.MarkAsProcessed(audit))
            .Returns(Task.CompletedTask)
            .Verifiable();

            // Act & Assert
            await processor.Process(container, CancellationToken.None);

            blobsMock.Verify();

            dbMock.Verify(i => i.SaveImageScanResult(It.Is <ImageScanResultWithCVEs>(a => VerifyNoCveScan(a))));
        }
        public async Task GetNotExistingItemAddOneRecordToDb()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser   = new ConfigurationParser("config.sample.yaml");
            var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var id  = this.GetCveId();
            var cve = new CVE {
                Id = id, Description = Guid.NewGuid().ToString(),
            };

            // Act & Assert
            context.Cve.Count().Should().Be(0, "context should be empty before GetOrAddItem");
            await cveCache.GetOrAddItem(id, () => cve);

            context.Cve.Count().Should().Be(1, "context should have a single value after GetOrAddItem");
        }
        public async Task GetExistingItemDoesNotAddNewRecords()
        {
            // Arrange
            await using var context = JosekiTestsDb.CreateUniqueContext();
            var parser   = new ConfigurationParser("config.sample.yaml");
            var cveCache = new CveCache(parser, context, new MemoryCache(new MemoryCacheOptions()));

            var id  = this.GetCveId();
            var cve = new CVE {
                Id = id, Description = Guid.NewGuid().ToString(),
            };

            context.Cve.Add(cve.ToEntity());
            await context.SaveChangesAsync();

            // Act & Assert
            context.Cve.Count().Should().Be(1, "context should have the only one record before GetOrAddItem");
            await cveCache.GetOrAddItem(id, () => cve);

            context.Cve.Count().Should().Be(1, "context should still have the only one record after GetOrAddItem");
        }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TrivyAuditProcessor"/> class.
 /// </summary>
 /// <param name="blobStorage">Blob Storage implementation.</param>
 /// <param name="db">Joseki database implementation.</param>
 /// <param name="cache">CVE cache object.</param>
 public TrivyAuditProcessor(IBlobStorageProcessor blobStorage, IJosekiDatabase db, CveCache cache)
 {
     this.blobStorage = blobStorage;
     this.db          = db;
     this.cache       = cache;
 }