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
     });
 }
Exemple #4
0
            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();
            }
Exemple #5
0
            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();
            }