Пример #1
0
        public static PackageAnalysisContext Create(
            ITestOutputHelper output,
            ManifestMetadata metadata,
            string[] emptyFiles = null,
            string signRequest  = null)
        {
            var disposableDirectory = new DisposableDirectory();
            var basePath            = disposableDirectory.Path;
            var nupkgFileName       = $"{PackageId}.{metadata.Version}.nupkg";
            var nupkgPath           = Path.Combine(basePath, nupkgFileName);

            // set required metadata
            metadata.Id          = metadata.Id ?? "Test";
            metadata.Version     = metadata.Version ?? new NuGetVersion("1.0.0");
            metadata.Authors     = metadata.Authors.Any() ? metadata.Authors : new[] { "test" };
            metadata.Description = metadata.Description ?? "Description";

            // prevent PackageException for packages with no dependencies or content
            emptyFiles = emptyFiles ?? new[] { "_._" };

            var builder = new PackageBuilder();

            builder.Populate(metadata);

            using (var nupkg = File.Create(nupkgPath))
            {
                foreach (var dest in emptyFiles)
                {
                    var fileName = Path.GetFileName(dest);
                    File.WriteAllText(Path.Combine(basePath, fileName), "");
                    builder.AddFiles(basePath, fileName, dest);
                }

                builder.Save(nupkg);
            }

            SignRequestItem packageSignRequest = null;

            if (signRequest != null)
            {
                var reader       = new StringReader(signRequest);
                var signManifest = SignRequestManifestXmlReader.Load(reader, basePath);
                packageSignRequest = signManifest.First(f => f.Path == nupkgFileName);
            }

            var context = new TestPackageAnalysisContext(disposableDirectory)
            {
                Logger          = new TestLogger(output),
                PackageFileInfo = new FileInfo(nupkgPath),
                SignRequest     = packageSignRequest,
                Metadata        = builder,
            };

            return(context);
        }
Пример #2
0
        public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context)
        {
            if (context.SignRequest == null)
            {
                context.Logger.Log(LogLevel.Info, "Skipping signing rule request verification for " + context.PackageFileInfo.FullName);
                yield break;
            }

            foreach (var file in context.PackageReader.GetFiles())
            {
                if (!SignRequestItem.IsFileTypeSignable(file))
                {
                    continue;
                }

                if (!context.SignRequest.Children.Any(f => string.Equals(f.Path, file)))
                {
                    yield return(PackageIssueFactory.SignRequestMissingPackageFile(context.Metadata.Id, file));
                }
            }
        }
Пример #3
0
        internal bool Execute(Func <TextWriter> writerFactory)
        {
            var signRequestCollection = new SignRequestCollection();

            var containers  = new Dictionary <string, SignRequestItem>(StringComparer.OrdinalIgnoreCase);
            var isContainer = new bool[Requests.Length];

            for (var i = 0; i < Requests.Length; i++)
            {
                var item = Requests[i];
                if (bool.TryParse(item.GetMetadata("IsContainer"), out var isc) && isc)
                {
                    isContainer[i] = true;
                    var itemType = string.IsNullOrEmpty(item.GetMetadata("Type"))
                        ? Path.GetExtension(item.ItemSpec)
                        : item.GetMetadata("Type");

                    var             type           = SignRequestItem.GetTypeFromFileExtension(itemType);
                    var             normalizedPath = GetRelativePath(BasePath, item.ItemSpec);
                    SignRequestItem container;

                    switch (type)
                    {
                    case SignRequestItemType.Zip:
                        container = SignRequestItem.CreateZip(normalizedPath);
                        break;

                    case SignRequestItemType.Nupkg:
                        container = SignRequestItem.CreateNugetPackage(normalizedPath, item.GetMetadata("Certificate"));
                        break;

                    case SignRequestItemType.Vsix:
                        container = SignRequestItem.CreateVsix(normalizedPath, item.GetMetadata("Certificate"));
                        break;

                    default:
                        Log.LogError(
                            $"Unknown container type for signed file request:'{item.ItemSpec}'. Signing request container must specify the metadata 'Type'.");
                        continue;
                    }

                    containers[item.ItemSpec] = container;
                    if (signRequestCollection.ContainsItemForPath(container.Path))
                    {
                        Log.LogError(
                            $"Duplicate sign request for {container.ItemType} '{container.Path}'");
                        continue;
                    }
                    signRequestCollection.Add(container);
                }
            }

            for (var i = 0; i < Requests.Length; i++)
            {
                if (isContainer[i])
                {
                    continue;
                }

                var item           = Requests[i];
                var normalizedPath = GetRelativePath(BasePath, item.ItemSpec);
                var containerPath  = item.GetMetadata("Container");
                if (!string.IsNullOrEmpty(containerPath))
                {
                    if (!containers.TryGetValue(containerPath, out var container))
                    {
                        Log.LogError(
                            $"Signing request item '{item.ItemSpec}' specifies an unknown container '{containerPath}'.");
                        continue;
                    }

                    var itemPath = GetPathWithinContainer(item);

                    if (string.IsNullOrEmpty(itemPath))
                    {
                        Log.LogError(null, null, null, item.GetMetadata(ProjectFileMetadataName), 0, 0, 0, 0,
                                     message: $"Could not identify the path for the signable file {item.ItemSpec}");
                        continue;
                    }

                    normalizedPath = NormalizePath(itemPath);
                    var file = SignRequestItem.CreateFile(normalizedPath,
                                                          item.GetMetadata("Certificate"),
                                                          item.GetMetadata("StrongName"));

                    if (container.ContainsChildPath(file.Path))
                    {
                        Log.LogError($"Duplicate sign request for file '{file.Path}' inside '{container.Path}'");
                        continue;
                    }
                    container.AddChild(file);
                }
                else
                {
                    var file = SignRequestItem.CreateFile(normalizedPath,
                                                          item.GetMetadata("Certificate"),
                                                          item.GetMetadata("StrongName"));

                    if (signRequestCollection.ContainsItemForPath(file.Path))
                    {
                        Log.LogError(
                            $"Duplicate sign request for file '{file.Path}'");
                        continue;
                    }

                    signRequestCollection.Add(file);
                }
            }

            if (Exclusions != null)
            {
                foreach (var item in Exclusions)
                {
                    var normalizedPath = GetRelativePath(BasePath, item.ItemSpec);

                    var containerPath = item.GetMetadata("Container");
                    if (!string.IsNullOrEmpty(containerPath))
                    {
                        if (!containers.TryGetValue(containerPath, out var container))
                        {
                            Log.LogError(
                                $"Exclusion item '{item.ItemSpec}' specifies an unknown container '{containerPath}'.");
                            continue;
                        }

                        var itemPath = GetPathWithinContainer(item);
                        if (string.IsNullOrEmpty(itemPath))
                        {
                            Log.LogError(null, null, null, item.GetMetadata(ProjectFileMetadataName), 0, 0, 0, 0,
                                         message: $"Could not identify the path for signing exclusion {item.ItemSpec}");
                            continue;
                        }

                        normalizedPath = NormalizePath(itemPath);
                        var file = SignRequestItem.CreateExclusion(normalizedPath);

                        if (container.ContainsChildPath(file.Path))
                        {
                            // ignore duplicate exclusions
                            continue;
                        }
                        container.AddChild(file);
                    }
                    else
                    {
                        var file = SignRequestItem.CreateExclusion(normalizedPath);
                        if (signRequestCollection.ContainsItemForPath(file.Path))
                        {
                            // ignore duplicate exclusions
                            continue;
                        }
                        signRequestCollection.Add(file);
                    }
                }
            }

            if (Log.HasLoggedErrors)
            {
                return(false);
            }

            using (var stream = writerFactory())
                using (var writer = new SignRequestManifestXmlWriter(stream))
                {
                    writer.Write(signRequestCollection);
                }

            Log.LogMessage($"Generated bill of materials in {OutputPath}");

            return(!Log.HasLoggedErrors);
        }