Пример #1
0
        /// <summary>
        /// Retrieves the specified component from NuGet.
        /// </summary>
        /// <param name="name">NuGet package name</param>
        /// <param name="version">Package version</param>
        /// <returns></returns>
        public async Task <Component> GetComponentAsync(string name, string version)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            Console.WriteLine("Retrieving " + name + " " + version);

            var component = new Component
            {
                Name    = name,
                Version = version,
                Purl    = Utils.GeneratePackageUrl(name, version)
            };

            var url = _baseUrl + name + "/" + version + "/" + name + ".nuspec";
            var doc = await _httpClient.GetXmlAsync(url);

            if (doc == null)
            {
                return(component);
            }

            var root     = doc.DocumentElement;
            var metadata = root.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']");

            component.Publisher = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'authors']");
            component.Copyright = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'copyright']");
            var title       = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'title']");
            var summary     = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'summary']");
            var description = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'description']");

            if (summary != null)
            {
                component.Description = summary;
            }
            else if (description != null)
            {
                component.Description = description;
            }
            else if (title != null)
            {
                component.Description = title;
            }

            // Utilize the new license expression field present in more recent packages
            // TODO: Need to have more robust parsing to support composite expressions seen in (https://github.com/NuGet/Home/wiki/Packaging-License-within-the-nupkg#project-properties)
            var licenseNode    = metadata.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'license']");
            var licenseUrlNode = metadata.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'licenseUrl']");

            if (licenseNode?.Attributes["type"].Value == "expression")
            {
                var licenses = licenseNode.FirstChild.Value
                               .Replace("AND", ";")
                               .Replace("OR", ";")
                               .Replace("WITH", ";")
                               .Replace("+", "")
                               .Split(';').ToList();
                foreach (var license in licenses)
                {
                    component.Licenses.Add(new Models.License
                    {
                        Id   = license.Trim(),
                        Name = license.Trim()
                    });
                }
            }
            else if (licenseUrlNode != null)
            {
                var licenseUrl = licenseUrlNode.FirstChild.Value;
                var license    = await _githubService.GetLicenseAsync(licenseUrl.Trim());

                component.Licenses.Add(license ?? new Models.License
                {
                    Url = licenseUrl.Trim()
                });
            }

            var projectUrl = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'projectUrl']");

            if (projectUrl != null)
            {
                var externalReference = new Models.ExternalReference();
                externalReference.Type = Models.ExternalReference.WEBSITE;
                externalReference.Url  = projectUrl;
                component.ExternalReferences.Add(externalReference);
            }

            var dependencies = metadata.SelectNodes("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'dependencies']/*[local-name() = 'dependency']");

            foreach (XmlNode dependency in dependencies)
            {
                var dependencyName    = dependency.Attributes["id"];
                var dependencyVersion = dependency.Attributes["version"];
                if (dependencyName != null && dependencyVersion != null)
                {
                    var nugetDependency = new NugetPackage {
                        Name    = dependencyName.Value,
                        Version = dependencyVersion.Value,
                    };
                    component.Dependencies.Add(nugetDependency);
                }
            }

            return(component);
        }
Пример #2
0
        /// <summary>
        /// Retrieves the specified component from NuGet.
        /// </summary>
        /// <param name="name">NuGet package name</param>
        /// <param name="version">Package version</param>
        /// <returns></returns>
        public async Task <Component> GetComponentAsync(string name, string version, string scope)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            Console.WriteLine("Retrieving " + name + " " + version);

            var component = new Component
            {
                Name    = name,
                Version = version,
                Scope   = scope,
                Purl    = Core.Utils.GeneratePackageUrl(name, version),
                Type    = Component.ComponentType.Library
            };

            var nuspecFilename = GetCachedNuspecFilename(name, version);

            NuspecReader nuspecReader = null;

            if (nuspecFilename == null)
            {
                var url = _baseUrl + name + "/" + version + "/" + name + ".nuspec";
                using (var xmlStream = await _httpClient.GetXmlStreamAsync(url).ConfigureAwait(false))
                {
                    if (xmlStream != null)
                    {
                        nuspecReader = new NuspecReader(xmlStream);
                    }
                }
            }
            else
            {
                using (var xmlStream = _fileSystem.File.Open(nuspecFilename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    nuspecReader = new NuspecReader(xmlStream);
                }
            }

            if (nuspecReader == null)
            {
                return(component);
            }

            component.Publisher = nuspecReader.GetAuthors();
            component.Copyright = nuspecReader.GetCopyright();
            // this prevents empty copyright values in the JSON BOM
            if (string.IsNullOrEmpty(component.Copyright))
            {
                component.Copyright = null;
            }
            var title       = nuspecReader.GetTitle();
            var summary     = nuspecReader.GetSummary();
            var description = nuspecReader.GetDescription();

            if (!string.IsNullOrEmpty(summary))
            {
                component.Description = summary;
            }
            else if (!string.IsNullOrEmpty(description))
            {
                component.Description = description;
            }
            else if (!string.IsNullOrEmpty(title))
            {
                component.Description = title;
            }

            var licenseMetadata = nuspecReader.GetLicenseMetadata();

            if (licenseMetadata != null && licenseMetadata.Type == NuGet.Packaging.LicenseType.Expression)
            {
                Action <NuGetLicense> licenseProcessor = delegate(NuGetLicense nugetLicense)
                {
                    var license = new Models.v1_2.License
                    {
                        Id   = nugetLicense.Identifier,
                        Name = nugetLicense.Identifier
                    };
                    component.Licenses = new List <ComponentLicense>
                    {
                        new ComponentLicense
                        {
                            License = license
                        }
                    };
                };
                licenseMetadata.LicenseExpression.OnEachLeafNode(licenseProcessor, null);
            }
            else
            {
                var licenseUrl = nuspecReader.GetLicenseUrl();
                if (!string.IsNullOrEmpty(licenseUrl))
                {
                    Models.v1_2.License license = null;

                    if (_githubService != null)
                    {
                        license = await _githubService.GetLicenseAsync(licenseUrl).ConfigureAwait(false);
                    }

                    if (license == null)
                    {
                        license = new Models.v1_2.License
                        {
                            Url = licenseUrl
                        };
                    }

                    component.Licenses = new List <ComponentLicense>
                    {
                        new ComponentLicense
                        {
                            License = license
                        }
                    };
                }
            }

            var projectUrl = nuspecReader.GetProjectUrl();

            if (!string.IsNullOrEmpty(projectUrl))
            {
                var externalReference = new Models.v1_2.ExternalReference();
                externalReference.Type       = Models.v1_2.ExternalReference.ExternalReferenceType.Website;
                externalReference.Url        = projectUrl;
                component.ExternalReferences = new List <ExternalReference>
                {
                    externalReference
                };
            }

            // Source: https://docs.microsoft.com/de-de/nuget/reference/nuspec#repository
            var repoMeta = nuspecReader.GetRepositoryMetadata();
            var vcsUrl   = repoMeta?.Url;

            if (!string.IsNullOrEmpty(vcsUrl))
            {
                var externalReference = new Models.v1_2.ExternalReference();
                externalReference.Type = Models.v1_2.ExternalReference.ExternalReferenceType.Vcs;
                externalReference.Url  = vcsUrl;
                if (null == component.ExternalReferences)
                {
                    component.ExternalReferences = new List <ExternalReference>
                    {
                        externalReference
                    };
                }
                else
                {
                    component.ExternalReferences.Add(externalReference);
                }
            }

            return(component);
        }
Пример #3
0
        /// <summary>
        /// Retrieves the specified component from NuGet.
        /// </summary>
        /// <param name="name">NuGet package name</param>
        /// <param name="version">Package version</param>
        /// <returns></returns>
        public async Task <Component> GetComponentAsync(string name, string version, string scope)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            Console.WriteLine("Retrieving " + name + " " + version);

            var component = new Component
            {
                Name    = name,
                Version = version,
                Scope   = scope,
                Purl    = Core.Utils.GeneratePackageUrl(name, version),
                Type    = Component.ComponentType.Library
            };

            var nuspecFilename = GetCachedNuspecFilename(name, version);

            NuspecReader nuspecReader = null;

            byte[] hashBytes = null;

            if (nuspecFilename == null)
            {
                var nugetUrlPrefix = _baseUrl + name + "/" + version + "/" + name;
                var nuspecUrl      = nugetUrlPrefix + _nuspecExtension;
                var nupkgUrl       = nugetUrlPrefix + "." + version + _nupkgExtension;
                using (var xmlStream = await _httpClient.GetStreamWithStatusCheckAsync(nuspecUrl).ConfigureAwait(false))
                {
                    if (xmlStream != null)
                    {
                        nuspecReader = new NuspecReader(xmlStream);
                    }
                }

                using (var stream = await _httpClient.GetStreamWithStatusCheckAsync(nupkgUrl).ConfigureAwait(false))
                {
                    if (stream != null)
                    {
                        hashBytes = ComputeSha215Hash(stream);
                    }
                }
            }
            else
            {
                using (var xmlStream = _fileSystem.File.OpenRead(nuspecFilename))
                {
                    nuspecReader = new NuspecReader(xmlStream);
                }

                // reference: https://docs.microsoft.com/en-us/nuget/reference/cli-reference/cli-ref-add
                // and: https://github.com/NuGet/Home/wiki/Nupkg-Metadata-File
                //  └─<packageID>
                //   └─<version>
                //    ├─<packageID>.<version>.nupkg
                //    ├─<packageID>.<version>.nupkg.sha512
                //    └─<packageID>.nuspec

                string shaFilename   = Path.ChangeExtension(nuspecFilename, version + _sha512Extension);
                string nupkgFilename = Path.ChangeExtension(nuspecFilename, version + _nupkgExtension);

                if (_fileSystem.File.Exists(shaFilename))
                {
                    string base64Hash = _fileSystem.File.ReadAllText(shaFilename);
                    hashBytes = Convert.FromBase64String(base64Hash);
                }
                else if (_fileSystem.File.Exists(nupkgFilename))
                {
                    using (var nupkgStream = _fileSystem.File.OpenRead(nupkgFilename))
                    {
                        hashBytes = ComputeSha215Hash(nupkgStream);
                    }
                }
            }

            if (hashBytes != null)
            {
                var  hex = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
                Hash h   = new Hash()
                {
                    Alg     = Hash.HashAlgorithm.SHA_512,
                    Content = hex
                };
                component.Hashes = new List <Hash>()
                {
                    h
                };
            }

            if (nuspecReader == null)
            {
                return(component);
            }

            component.Publisher = nuspecReader.GetAuthors();
            component.Copyright = nuspecReader.GetCopyright();
            // this prevents empty copyright values in the JSON BOM
            if (string.IsNullOrEmpty(component.Copyright))
            {
                component.Copyright = null;
            }
            var title       = nuspecReader.GetTitle();
            var summary     = nuspecReader.GetSummary();
            var description = nuspecReader.GetDescription();

            if (!string.IsNullOrEmpty(summary))
            {
                component.Description = summary;
            }
            else if (!string.IsNullOrEmpty(description))
            {
                component.Description = description;
            }
            else if (!string.IsNullOrEmpty(title))
            {
                component.Description = title;
            }

            var licenseMetadata = nuspecReader.GetLicenseMetadata();

            if (licenseMetadata != null && licenseMetadata.Type == NuGet.Packaging.LicenseType.Expression)
            {
                Action <NuGetLicense> licenseProcessor = delegate(NuGetLicense nugetLicense)
                {
                    var license = new Models.v1_2.License
                    {
                        Id   = nugetLicense.Identifier,
                        Name = nugetLicense.Identifier
                    };
                    component.Licenses = new List <ComponentLicense>
                    {
                        new ComponentLicense
                        {
                            License = license
                        }
                    };
                };
                licenseMetadata.LicenseExpression.OnEachLeafNode(licenseProcessor, null);
            }
            else
            {
                var licenseUrl = nuspecReader.GetLicenseUrl();
                if (!string.IsNullOrEmpty(licenseUrl))
                {
                    Models.v1_2.License license = null;

                    if (_githubService != null)
                    {
                        license = await _githubService.GetLicenseAsync(licenseUrl).ConfigureAwait(false);
                    }

                    if (license == null)
                    {
                        license = new Models.v1_2.License
                        {
                            Url = licenseUrl
                        };
                    }

                    component.Licenses = new List <ComponentLicense>
                    {
                        new ComponentLicense
                        {
                            License = license
                        }
                    };
                }
            }

            var projectUrl = nuspecReader.GetProjectUrl();

            if (!string.IsNullOrEmpty(projectUrl))
            {
                var externalReference = new Models.v1_2.ExternalReference();
                externalReference.Type       = Models.v1_2.ExternalReference.ExternalReferenceType.Website;
                externalReference.Url        = projectUrl;
                component.ExternalReferences = new List <ExternalReference>
                {
                    externalReference
                };
            }

            // Source: https://docs.microsoft.com/de-de/nuget/reference/nuspec#repository
            var repoMeta = nuspecReader.GetRepositoryMetadata();
            var vcsUrl   = repoMeta?.Url;

            if (!string.IsNullOrEmpty(vcsUrl))
            {
                var externalReference = new Models.v1_2.ExternalReference();
                externalReference.Type = Models.v1_2.ExternalReference.ExternalReferenceType.Vcs;
                externalReference.Url  = vcsUrl;
                if (null == component.ExternalReferences)
                {
                    component.ExternalReferences = new List <ExternalReference>
                    {
                        externalReference
                    };
                }
                else
                {
                    component.ExternalReferences.Add(externalReference);
                }
            }

            return(component);
        }
Пример #4
0
        public async Task <Component> GetComponentAsync(string name, string version, Component.ComponentScope?scope)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            // https://docs.microsoft.com/en-us/nuget/reference/nuget-client-sdk - Download a package
            var resource = await _sourceRepository.GetResourceAsync <FindPackageByIdResource>();

            var component      = SetupComponent(name, version, scope);
            var nuspecFilename = GetCachedNuspecFilename(name, version);

            var nuspecModel = await GetNuspec(name, version, nuspecFilename, resource).ConfigureAwait(false);

            if (nuspecModel.hashBytes != null)
            {
                var  hex = BitConverter.ToString(nuspecModel.hashBytes).Replace("-", string.Empty);
                Hash h   = new Hash {
                    Alg = Hash.HashAlgorithm.SHA_512, Content = hex
                };
                component.Hashes = new List <Hash> {
                    h
                };
            }

            if (nuspecModel.nuspecReader == null)
            {
                return(component);
            }

            component = SetupComponentProperties(component, nuspecModel);

            var licenseMetadata = nuspecModel.nuspecReader.GetLicenseMetadata();

            if (licenseMetadata != null && licenseMetadata.Type == LicenseType.Expression)
            {
                Action <NuGetLicense> licenseProcessor = delegate(NuGetLicense nugetLicense)
                {
                    var license = new License {
                        Id = nugetLicense.Identifier, Name = nugetLicense.Identifier
                    };
                    component.Licenses = new List <LicenseChoice> {
                        new LicenseChoice {
                            License = license
                        }
                    };
                };
                licenseMetadata.LicenseExpression.OnEachLeafNode(licenseProcessor, null);
            }
            else
            {
                var licenseUrl = nuspecModel.nuspecReader.GetLicenseUrl();
                if (!string.IsNullOrEmpty(licenseUrl))
                {
                    License license = null;

                    if (_githubService != null)
                    {
                        license = await _githubService.GetLicenseAsync(licenseUrl).ConfigureAwait(false);
                    }

                    if (license == null)
                    {
                        license = new License {
                            Url = licenseUrl
                        };
                    }

                    component.Licenses = new List <LicenseChoice> {
                        new LicenseChoice {
                            License = license
                        }
                    };
                }
            }

            var projectUrl = nuspecModel.nuspecReader.GetProjectUrl();

            if (!string.IsNullOrEmpty(projectUrl))
            {
                var externalReference = new ExternalReference
                {
                    Type = ExternalReference.ExternalReferenceType.Website, Url = projectUrl
                };
                component.ExternalReferences = new List <ExternalReference> {
                    externalReference
                };
            }

            // Source: https://docs.microsoft.com/de-de/nuget/reference/nuspec#repository
            var repoMeta = nuspecModel.nuspecReader.GetRepositoryMetadata();
            var vcsUrl   = repoMeta?.Url;

            if (!string.IsNullOrEmpty(vcsUrl))
            {
                var externalReference = new ExternalReference
                {
                    Type = ExternalReference.ExternalReferenceType.Vcs, Url = vcsUrl
                };
                if (null == component.ExternalReferences)
                {
                    component.ExternalReferences = new List <ExternalReference> {
                        externalReference
                    };
                }
                else
                {
                    component.ExternalReferences.Add(externalReference);
                }
            }

            return(component);
        }