Пример #1
0
        public void LicenseDefaultNotAllowed_InternalProject_NoViolation()
        {
            var config = new Config {
                DiskCache = new DiskCacheConfig {
                    ResolvedLicenses = new DiskCacheItem {
                        DoCache = false
                    }
                }
            };
            var packagePolicies = new PackagePolicies(new PackagePolicy[] { });
            var licensePolicies = new[] { new LicensePolicy {
                                              License = "no-distribution-allowed", Allow = false, AllowInternal = true
                                          } };

            var pd = new PackageDetails
            {
                Id      = "test-id",
                Version = "1.0.4",
                License = "no-distribution-allowed",
            };

            var package      = new AnalyzedPackage(pd.Id, pd.Version, "path-to-origin-project");
            var dependencies = DependencyChain <AnalyzedPackage> .EmptyList;
            var packages     = new[] { new DependencyChain <AnalyzedPackage>(package, dependencies) };

            var scanner = new LicenseScanner(_ => Task.FromResult(new PackageDetailsResult(pd)), packagePolicies, config);
            var licensedDependencies = scanner.FindLicenses(packages);

            LicensePolicies licensing = new LicensePolicies(licensePolicies, packagePolicies, new Projects(new[] { "path-to-origin-project" }));
            var             result    = licensing.Apply(licensedDependencies);

            Assert.Equal(1, result.Count);
            Assert.Equal(Evaluation.Ok, result.First().Package.Result);
        }
Пример #2
0
        internal async Task <IList <DependencyChain <AnalyzedPackage> > > FindPackageDependencies(IEnumerable <PackageRange> packages, ICollection <string> searchedRoots)
        {
            var packagesToResolved = packages
                                     .Select(p => (Package: p, Resolved: this.versionResolver.GetSingleVersion(p)))
                                     .ToList();

            List <DependencyChain <AnalyzedPackage> > result = packagesToResolved
                                                               .Where(tuple => tuple.Resolved == null)
                                                               .Select(tuple => new InvalidDependencyChain(tuple.Package, $"Could not find a package with version {tuple.Package.VersionRange}."))
                                                               .Cast <DependencyChain <AnalyzedPackage> >()
                                                               .ToList();

            var validPackages = packagesToResolved.Select(t => t.Resolved).ToArray();

            Task.WaitAll(validPackages);

            var valid = validPackages.Where(x => x.Result != null).Select(x => x.Result !);

            // Separate the packages into those who have a location and those
            // who do not. The former we will look up on disk, the others in
            // nuget.
            var packagesAndLocations     = valid.Select(package => (package, location: packagePolicies.GetLocation(package.Id)));
            var packagesWithLocations    = packagesAndLocations.Where(p => p.location != null);
            var packagesWithoutLocations = packagesAndLocations.Except(packagesWithLocations).Select(p => p.package);

            {
                var dependencies = await this.registry.FindPackageDependencies(packagesWithoutLocations);

                result.AddRange(dependencies);
            }
            {
                foreach (var(package, location) in packagesWithLocations)
                {
                    if (searchedRoots.Contains(location))
                    {
                        continue;
                    }

                    var analyzedPackage = new AnalyzedPackage(package);
                    IList <DependencyChain <AnalyzedPackage> > dependencies;
                    if (this.followLocations)
                    {
                        searchedRoots.Add(location);
                        dependencies = await this.FindPackageDependenciesAux(location !, searchedRoots);
                    }
                    else
                    {
                        dependencies = DependencyChain <AnalyzedPackage> .EmptyList;
                    }

                    var chain = new DependencyChain <AnalyzedPackage>(analyzedPackage, dependencies);
                    result.Add(chain);
                }
            }

            return(result);
        }
        internal async Task <DependencyChain <AnalyzedPackage> > FindPackageDependencies(Package package, HashSet <string> upstreamDependencies)
        {
            string resolvedDependenciesPath = string.Format(this.resolvedPathFormatStr, package.Id, package.Version);

            if (DiskCache.TryGetValue(resolvedDependenciesPath, this.config.ResolvedDependencies, out DependencyChain <AnalyzedPackage>?cached))
            {
                return(cached);
            }

            string     path = string.Format(this.detailsPathFormatStr, package.Id, package.Version);
            NpmPackage?npmPackage;

            if (!DiskCache.TryGetValue(path, this.config.PackageDetails, out npmPackage))
            {
                npmPackage = await this.npm.GetPackage(package).ContinueWith(CachePackage);
            }

            if (npmPackage == null)
            {
                Log.Warning($"Could not find information about {package.Id} {package.Version} from npm");
                return(new InvalidDependencyChain(package, "Could not find information from npm"));
            }

            var analyzedPackage = new AnalyzedPackage(package);

            var packageDependencies = npmPackage.Dependencies ?? new Dictionary <string, string>();
            var ds           = packageDependencies.Select(x => new PackageRange(x.Key, x.Value, package.OriginProject));
            var dependencies = await FindPackageDependencies(ds, upstreamDependencies);

            var result = new DependencyChain <AnalyzedPackage>(analyzedPackage, dependencies);

            CacheDependencies(package, result);

            return(result);

            NpmPackage?CachePackage(Task <(PackageDetailsResultEnum, NpmPackage?)> package)
            {
                if (!this.config.PackageDetails.DoCache)
                {
                    return(package.Result.Item2);
                }

                if (package.Result.Item1 != PackageDetailsResultEnum.Success)
                {
                    return(null);
                }

                NpmPackage p         = package.Result.Item2 !;
                string     cachePath = string.Format(this.detailsPathFormatStr, p.Id, p.Version);

                DiskCache.Cache(cachePath, p);
                return(p);
            }
        }
Пример #4
0
        private async Task <DependencyChain <AnalyzedPackage> > FindPackageDependencies(Package package)
        {
            string resolvedDependenciesPath = string.Format(this.resolvedPathFormatStr, package.Id, package.Version);

            if (DiskCache.TryGetValue(resolvedDependenciesPath, this.config.ResolvedDependencies, out DependencyChain <AnalyzedPackage>?cached))
            {
                return(cached);
            }

            var(status, packageDetails) = await GetPackageDetails(package);

            if (status == PackageDetailsResultEnum.InternalPackage)
            {
                var analyzedPackage = new AnalyzedPackage(package.Id, package.Version, package.OriginProject, AnalysisState.Ok, string.Empty);
                return(new DependencyChain <AnalyzedPackage>(analyzedPackage, DependencyChain <AnalyzedPackage> .EmptyList));
            }
            else if (status != PackageDetailsResultEnum.Success)
            {
                return(new InvalidDependencyChain(package, "Could not find any package information."));
            }
            else if (packageDetails == null)
            {
                throw new InvalidOperationException($"Got a null result even though status indicated success: {package}");
            }

            List <DependencyChain <AnalyzedPackage> > result = new List <DependencyChain <AnalyzedPackage> >();

            foreach (var group in packageDetails.DependencyGroups ?? EmptyDependencyGroups)
            {
                var dependencies = await FindPackageDependenciesAux(group.Dependencies ?? EmptyDependencies, false);

                result.AddRange(dependencies);
            }

            var uniqueDependencies = result.Distinct(DependencyComparer).ToList();

            if (uniqueDependencies.Any())
            {
                Log.Debug($"{package}: dependencies - {string.Join(", ", uniqueDependencies.Select(y => y.Package.ToString()))}");
            }
            else
            {
                Log.Debug($"{package}: no dependencies");
            }

            return(new DependencyChain <AnalyzedPackage>(new AnalyzedPackage(package), uniqueDependencies));
        }
Пример #5
0
        public void NoPackageFound_HasValidPackagePolicy_GivesCorrectLicense()
        {
            var config          = new Config();
            var packagePolicies = new PackagePolicies(new[] { new PackagePolicy {
                                                                  Package = "test-id", License = "test-license"
                                                              } });
            var scanner = new LicenseScanner(_ => Task.FromResult(new PackageDetailsResult(PackageDetailsResultEnum.NoPackageFound)), packagePolicies, config);

            var package      = new AnalyzedPackage("test-id", "1.0.4", string.Empty, AnalysisState.Error, "test error");
            var dependencies = DependencyChain <AnalyzedPackage> .EmptyList;
            var packages     = new[] { new DependencyChain <AnalyzedPackage>(package, dependencies) };

            var result = scanner.FindLicenses(packages);

            Assert.Equal(1, result.Count);
            Assert.Equal("test-license", result.First().Package.License);
        }