/// <summary> /// Gets the repository's details and updates the status field in the dependencies /// </summary> /// <param name="repository"> A Repository object</param> /// <returns>An updated repository object with the status field.</returns> internal async Task <Repository> UpdateRepositoryStatus(Repository repository) { var vulnerabilityCount = repository?.VulnerabilityAlerts?.TotalCount; var dependencyGraphManifests = repository?.DependencyGraphManifests?.Nodes; if (dependencyGraphManifests == null) { return(repository); } // Go through the various dependency manifests in the repo foreach (var dependencyManifest in dependencyGraphManifests) { var dependencies = dependencyManifest?.Dependencies?.Nodes; if (dependencies == null) { continue; } PackageStatus highestStatus = PackageStatus.Unknown; // Go through each dependency in the dependency manifest foreach (var dependency in dependencies) { var currentVersion = dependency.requirements; if (string.IsNullOrEmpty(currentVersion)) { continue; } //getting latest versions from the respective packagemanagers,azure sdks and the default values from github string latestVersion; string azureSdkVersion = String.Empty; switch (dependency.packageManager) { case "NUGET": latestVersion = await GetLatestNugetVersion(dependency.packageName, currentVersion); azureSdkVersion = await _azureSdkService.GetAzureSdkVersions(dependency.packageName); break; case "NPM": latestVersion = await _npmService.GetLatestVersion(dependency.packageName); break; default: latestVersion = dependency.repository?.releases?.nodes?.FirstOrDefault()?.tagName; break; } dependency.latestVersion = latestVersion; dependency.azureSdkVersion = azureSdkVersion; //calculate status normally for repos without security alerts if (vulnerabilityCount == 0) { dependency.status = CalculateStatus(currentVersion.Substring(2), latestVersion); } //check if a repo has security alerts else if (vulnerabilityCount > 0) { var librariesWithAlerts = repository?.VulnerabilityAlerts.Edges.Select(p => p.Node?.SecurityVulnerability.Package.Name); //if the name of the dependency is in the list of libraries with alerts, set status to urgent update if (librariesWithAlerts.Contains(dependency.packageName)) { dependency.status = PackageStatus.UrgentUpdate; } else { dependency.status = CalculateStatus(currentVersion.Substring(2), latestVersion); } } } //getting the highest status from a dependency node highestStatus = HighestStatus(dependencies); //comparing the highest statuses from different nodes if (highestStatus > repository.highestStatus) { repository.highestStatus = highestStatus; } } return(repository); }
/// <summary> /// Gets the repository's details and updates the status field in the dependencies /// </summary> /// <param name="repository"> A Repository object</param> /// <returns>An updated repository object with the status field.</returns> internal async Task <Repository> UpdateRepositoryStatus(Repository repository) { var headerDetails = await GetYamlHeader(repository.Name, repository.DefaultBranch == null? "master" : repository.DefaultBranch.Name); repository.IdentityStatus = PackageStatus.Unknown; repository.GraphStatus = PackageStatus.Unknown; repository.highestStatus = PackageStatus.Unknown; var vulnerabilityCount = repository?.VulnerabilityAlerts?.TotalCount; var dependencyGraphManifests = repository?.DependencyGraphManifests?.Nodes; if (dependencyGraphManifests == null || dependencyGraphManifests.Count() == 0 && headerDetails != null) { var dependencyFile = headerDetails.DependencyFile ?? string.Empty; if (dependencyFile == "noDependencies") { // Repository doesn't use dependencies, mark as // up to date repository.highestStatus = PackageStatus.UpToDate; return(repository); } if (string.IsNullOrEmpty(dependencyFile)) { return(repository); } // Build dependency graph from file dependencyGraphManifests = await BuildDependencyGraphFromFile(repository.Name, repository.DefaultBranch?.Name ?? "master", dependencyFile); repository.DependencyGraphManifests.Nodes = dependencyGraphManifests; if (dependencyGraphManifests == null) { return(repository); } } // Go through the various dependency manifests in the repo foreach (var dependencyManifest in dependencyGraphManifests) { var dependencies = dependencyManifest?.Dependencies?.Nodes; if (dependencies == null) { continue; } PackageStatus highestStatus = PackageStatus.Unknown; // Go through each dependency in the dependency manifest foreach (var dependency in dependencies) { var currentVersion = dependency.requirements; if (string.IsNullOrEmpty(currentVersion)) { continue; } //getting latest versions from the respective packagemanagers,azure sdks and the default values from github string latestVersion; string azureSdkVersion = String.Empty; switch (dependency.packageManager) { case "NUGET": latestVersion = await GetLatestNugetVersion(dependency.packageName, currentVersion); azureSdkVersion = await _azureSdkService.GetAzureSdkVersions(dependency.packageName); break; case "NPM": latestVersion = await _npmService.GetLatestVersion(dependency.packageName); break; case "GRADLE": case "MAVEN": // Check the Maven repositories for version information first latestVersion = await _mavenService.GetLatestVersion(dependency.packageName, currentVersion); if (string.IsNullOrEmpty(latestVersion)) { // Fall back to GitHub's supplied value latestVersion = dependency.repository?.releases?.nodes?.FirstOrDefault()?.tagName; } break; case "COCOAPODS": latestVersion = await _cocoaPodsService.GetLatestVersion(dependency.packageName); break; default: latestVersion = dependency.repository?.releases?.nodes?.FirstOrDefault()?.tagName; break; } dependency.latestVersion = latestVersion; dependency.azureSdkVersion = azureSdkVersion; //calculate status normally for repos without security alerts if (vulnerabilityCount == 0) { dependency.status = CalculateStatus(currentVersion.Substring(2), latestVersion); } //check if a repo has security alerts else if (vulnerabilityCount > 0) { var librariesWithAlerts = repository?.VulnerabilityAlerts.Edges.Select(p => p.Node?.SecurityVulnerability.Package.Name); //if the name of the dependency is in the list of libraries with alerts, set status to urgent update if (librariesWithAlerts.Contains(dependency.packageName)) { dependency.status = PackageStatus.UrgentUpdate; } else { dependency.status = CalculateStatus(currentVersion.Substring(2), latestVersion); } } // Check if dependency is Identity library if (IsIdentityLibrary(dependency) && dependency.status > repository.IdentityStatus) { repository.IdentityStatus = dependency.status; } // Check if dependency is Graph SDK else if (IsGraphSdk(dependency) && dependency.status > repository.GraphStatus) { repository.GraphStatus = dependency.status; } } //getting the highest status from a dependency node highestStatus = HighestStatus(dependencies); //comparing the highest statuses from different nodes if (highestStatus > repository.highestStatus) { repository.highestStatus = highestStatus; } } return(repository); }