public async Task OneResult() { // Arrange var vulnerability = new SecurityVulnerability(); var advisory = new SecurityAdvisory { Vulnerabilities = new ConnectionResponseData <SecurityVulnerability> { Edges = new[] { new Edge <SecurityVulnerability> { Node = vulnerability } } } }; var response = CreateResponseFromEdges(new[] { new Edge <SecurityAdvisory> { Node = advisory } }); SetupFirstQueryResult(response); // Act var results = await _service.GetAdvisoriesSinceAsync( _lastUpdated, _token); // Assert Assert.Single(results, advisory); _queryBuilderMock.Verify(); _queryServiceMock.Verify(); }
public async Task DedupesIdenticalVulnerabilities() { // Arrange var id = "identical"; var range = "(,)"; var firstVulnerability = new SecurityVulnerability { Package = new SecurityVulnerabilityPackage { Name = id }, VulnerableVersionRange = range }; var secondVulnerability = new SecurityVulnerability { Package = new SecurityVulnerabilityPackage { Name = id }, VulnerableVersionRange = range }; var advisory = new SecurityAdvisory { Vulnerabilities = new ConnectionResponseData <SecurityVulnerability> { Edges = new[] { new Edge <SecurityVulnerability> { Node = firstVulnerability }, new Edge <SecurityVulnerability> { Node = secondVulnerability } } } }; var response = CreateResponseFromEdges(new[] { new Edge <SecurityAdvisory> { Node = advisory } }); SetupFirstQueryResult(response); // Act var results = await _service.GetAdvisoriesSinceAsync( _cursorMock.Object, _token); // Assert Assert.Single(results, advisory); Assert.Single(results.Single().Vulnerabilities.Edges); var node = results.Single().Vulnerabilities.Edges.Single().Node; Assert.Equal(id, node.Package.Name); Assert.Equal(range, node.VulnerableVersionRange); _cursorMock.Verify(); _queryBuilderMock.Verify(); _queryServiceMock.Verify(); }
private VulnerablePackageVersionRange FromVulnerability(PackageVulnerability vulnerability, SecurityVulnerability securityVulnerability) { return(new VulnerablePackageVersionRange { Vulnerability = vulnerability, PackageId = securityVulnerability.Package.Name, PackageVersionRange = _gitHubVersionRangeParser.ToNuGetVersionRange(securityVulnerability.VulnerableVersionRange).ToNormalizedString(), FirstPatchedPackageVersion = securityVulnerability.FirstPatchedVersion?.Identifier }); }
public async Task IngestsAdvisory(bool withdrawn) { // Arrange var securityVulnerability = new SecurityVulnerability { Package = new SecurityVulnerabilityPackage { Name = "crested.gecko" }, VulnerableVersionRange = "homeOnTheRange" }; var advisory = new SecurityAdvisory { DatabaseId = 1, GhsaId = "ghsa", Severity = "CRITICAL", References = new[] { new SecurityAdvisoryReference { Url = "https://vulnerable" } }, WithdrawnAt = withdrawn ? new DateTime() : (DateTime?)null, Vulnerabilities = new ConnectionResponseData <SecurityVulnerability> { Edges = new[] { new Edge <SecurityVulnerability> { Node = securityVulnerability } } } }; securityVulnerability.Advisory = advisory; var versionRange = VersionRange.Parse("[1.0.0, 1.0.0]"); GitHubVersionRangeParserMock .Setup(x => x.ToNuGetVersionRange(securityVulnerability.VulnerableVersionRange)) .Returns(versionRange); PackageVulnerabilityServiceMock .Setup(x => x.UpdateVulnerabilityAsync(It.IsAny <PackageVulnerability>(), withdrawn)) .Callback <PackageVulnerability, bool>((vulnerability, wasWithdrawn) => { Assert.Equal(advisory.DatabaseId, vulnerability.GitHubDatabaseKey); Assert.Equal(PackageVulnerabilitySeverity.Critical, vulnerability.Severity); Assert.Equal(advisory.References.Single().Url, vulnerability.ReferenceUrl); var packageVulnerability = vulnerability.AffectedRanges.Single(); Assert.Equal(securityVulnerability.Package.Name, packageVulnerability.PackageId); Assert.Equal(versionRange.ToNormalizedString(), packageVulnerability.PackageVersionRange); }) .Returns(Task.CompletedTask) .Verifiable(); // Act await Ingestor.IngestAsync(new[] { advisory }); // Assert PackageVulnerabilityServiceMock.Verify(); }
public async Task IngestsAdvisory(bool withdrawn, bool vulnerabilityHasFirstPatchedVersion) { // Arrange var securityVulnerability = new SecurityVulnerability { Package = new SecurityVulnerabilityPackage { Name = "crested.gecko" }, VulnerableVersionRange = "homeOnTheRange", FirstPatchedVersion = vulnerabilityHasFirstPatchedVersion ? new SecurityVulnerabilityPackageVersion { Identifier = "1.2.3" } : null }; var advisory = new SecurityAdvisory { DatabaseId = 1, Permalink = "https://example/advisories/GHSA-6543-dcba-0987", Severity = "CRITICAL", WithdrawnAt = withdrawn ? new DateTimeOffset() : (DateTimeOffset?)null, Vulnerabilities = new ConnectionResponseData <SecurityVulnerability> { Edges = new[] { new Edge <SecurityVulnerability> { Node = securityVulnerability } } } }; securityVulnerability.Advisory = advisory; var versionRange = VersionRange.Parse("[1.0.0, 1.0.0]"); GitHubVersionRangeParserMock .Setup(x => x.ToNuGetVersionRange(securityVulnerability.VulnerableVersionRange)) .Returns(versionRange); PackageVulnerabilityServiceMock .Setup(x => x.UpdateVulnerabilityAsync(It.IsAny <PackageVulnerability>(), withdrawn)) .Callback <PackageVulnerability, bool>((vulnerability, wasWithdrawn) => { Assert.Equal(advisory.DatabaseId, vulnerability.GitHubDatabaseKey); Assert.Equal(PackageVulnerabilitySeverity.Critical, vulnerability.Severity); Assert.Equal(advisory.Permalink, vulnerability.AdvisoryUrl); var range = vulnerability.AffectedRanges.Single(); Assert.Equal(securityVulnerability.Package.Name, range.PackageId); Assert.Equal(versionRange.ToNormalizedString(), range.PackageVersionRange); Assert.Equal(securityVulnerability.FirstPatchedVersion?.Identifier, range.FirstPatchedPackageVersion); }) .Returns(Task.CompletedTask) .Verifiable(); // Act await Ingestor.IngestAsync(new[] { advisory }); // Assert PackageVulnerabilityServiceMock.Verify(); }