Exemple #1
0
        internal static bool ShouldCuratePackage(
            CuratedFeed curatedFeed,
            Package galleryPackage,
            PackageReader nugetPackage)
        {
            var nuspec = nugetPackage.GetNuspecReader();

            return
                // Must have min client version of null or <= 2.2
                ((nuspec.GetMinClientVersion() == null || nuspec.GetMinClientVersion() <= new NuGetVersion(2, 2, 0)) &&

                 // Must be latest stable
                 galleryPackage.IsLatestStable &&

                 // Must support net40
                 SupportsNet40(galleryPackage) &&

                 (
                     // Must have AspNetWebPages tag
                     ContainsAspNetWebPagesTag(galleryPackage) ||

                     // OR: Must not contain powershell or T4
                     DoesNotContainUnsupportedFiles(nugetPackage)
                 ) &&

                 // Dependencies on the gallery must be curated
                 DependenciesAreCurated(galleryPackage, curatedFeed));
        }
Exemple #2
0
        public static void RewritingTheNuSpecDoesNotMessUpTheNuspecStream()
        {
            var packageStream = CreateTestPackageStream();
            var manifestStreamLengthOriginal = GetManifestStreamLength(packageStream);

            var longValue  = new String('x', 200);
            var shortValue = "y";

            // Act 1 - Make the stream bigger
            NupkgRewriter.RewriteNupkgManifest(packageStream,
                                               new List <Action <ManifestEdit> >
            {
                metadata => { metadata.Description = longValue; },
                metadata => { metadata.Summary = longValue; }
            });

            // Assert 1
            var manifestStreamLength1 = GetManifestStreamLength(packageStream);

            Assert.True(manifestStreamLength1 > manifestStreamLengthOriginal);

            using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: true))
            {
                var nuspec = nupkg.GetNuspecReader();

                Assert.Equal("TestPackage", nuspec.GetId());
                Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion());
                Assert.Equal(longValue, nuspec.GetMetadata().First(kvp => kvp.Key == "description").Value);
                Assert.Equal(longValue, nuspec.GetMetadata().First(kvp => kvp.Key == "summary").Value);
            }

            // Act 2 - Make the stream smaller
            NupkgRewriter.RewriteNupkgManifest(packageStream,
                                               new List <Action <ManifestEdit> >
            {
                metadata => { metadata.Description = shortValue; },
                metadata => { metadata.Summary = shortValue; }
            });

            // Assert 2
            var manifestStreamLength2 = GetManifestStreamLength(packageStream);

            Assert.True(manifestStreamLength2 < manifestStreamLength1);

            using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: true))
            {
                var nuspec = nupkg.GetNuspecReader();

                Assert.Equal("TestPackage", nuspec.GetId());
                Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion());
                Assert.Equal(shortValue, nuspec.GetMetadata().First(kvp => kvp.Key == "description").Value);
                Assert.Equal(shortValue, nuspec.GetMetadata().First(kvp => kvp.Key == "summary").Value);
            }
        }
Exemple #3
0
        public void EnsureValid(PackageReader packageReader)
        {
            var packageMetadata = PackageMetadata.FromNuspecReader(packageReader.GetNuspecReader());

            ValidateNuGetPackageMetadata(packageMetadata);

            var supportedFrameworks = GetSupportedFrameworks(packageReader).Select(fn => fn.ToShortNameOrNull()).ToArray();

            if (!supportedFrameworks.AnySafe(sf => sf == null))
            {
                ValidateSupportedFrameworks(supportedFrameworks);
            }
        }
Exemple #4
0
        public Package CreatePackage(PackageReader nugetPackage, PackageStreamMetadata packageStreamMetadata, User user, bool commitChanges = true)
        {
            var packageMetadata = PackageMetadata.FromNuspecReader(nugetPackage.GetNuspecReader());

            ValidateNuGetPackageMetadata(packageMetadata);

            var packageRegistration = CreateOrGetPackageRegistration(user, packageMetadata);

            var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage, packageMetadata, packageStreamMetadata, user);

            packageRegistration.Packages.Add(package);
            UpdateIsLatest(packageRegistration, false);

            if (commitChanges)
            {
                _packageRegistrationRepository.CommitChanges();
                NotifyIndexingService();
            }

            return(package);
        }
Exemple #5
0
        public static void CanReadBasicMetadataProperties()
        {
            var packageStream = CreateTestPackageStream();
            var nupkg = new PackageReader(packageStream, leaveStreamOpen: false);
            var nuspec = nupkg.GetNuspecReader();

            // Act
            var packageMetadata = PackageMetadata.FromNuspecReader(nuspec);

            // Assert
            Assert.Equal("TestPackage", packageMetadata.Id);
            Assert.Equal(NuGetVersion.Parse("0.0.0.1"), packageMetadata.Version);
            Assert.Equal("Package A", packageMetadata.Title);
            Assert.Equal(2, packageMetadata.Authors.Count);
            Assert.Equal("ownera, ownerb", packageMetadata.Owners);
            Assert.False(packageMetadata.RequireLicenseAcceptance);
            Assert.Equal("package A description.", packageMetadata.Description);
            Assert.Equal("en-US", packageMetadata.Language);
            Assert.Equal("http://www.nuget.org/", packageMetadata.ProjectUrl.ToString());
            Assert.Equal("http://www.nuget.org/", packageMetadata.IconUrl.ToString());
            Assert.Equal("http://www.nuget.org/", packageMetadata.LicenseUrl.ToString());
        }
Exemple #6
0
        public static void CanRewriteTheNuspecInANupkg()
        {
            var packageStream = CreateTestPackageStream();

            // Act
            NupkgRewriter.RewriteNupkgManifest(packageStream,
                                               new List <Action <ManifestEdit> >
            {
                metadata => { metadata.Authors = "Me and You"; },
                metadata => { metadata.Tags = "Peas In A Pod"; }
            });

            // Assert
            using (var nupkg = new PackageReader(packageStream, leaveStreamOpen: false))
            {
                var nuspec = nupkg.GetNuspecReader();

                Assert.Equal("TestPackage", nuspec.GetId());
                Assert.Equal(NuGetVersion.Parse("0.0.0.1"), nuspec.GetVersion());
                Assert.Equal("Me and You", nuspec.GetMetadata().First(kvp => kvp.Key == "authors").Value);
                Assert.Equal("Peas In A Pod", nuspec.GetMetadata().First(kvp => kvp.Key == "tags").Value);
            }
        }
Exemple #7
0
        /// <summary>
        /// Given the nupkg file as a read-write stream with random access (e.g. MemoryStream),
        /// This will replace the .nuspec file with a new .nuspec generated from
        /// a) the old .nuspec file
        /// b) supplied edits
        ///
        /// This function leaves readWriteStream open.
        /// </summary>
        public static void RewriteNupkgManifest(Stream readWriteStream, IEnumerable <Action <ManifestEdit> > edits)
        {
            if (!readWriteStream.CanRead)
            {
                throw new ArgumentException("Must be a readable stream", "readWriteStream");
            }

            if (!readWriteStream.CanWrite)
            {
                throw new ArgumentException("Must be a writeable stream", "readWriteStream");
            }

            if (!readWriteStream.CanSeek)
            {
                throw new ArgumentException("Must be a seekable stream", "readWriteStream");
            }

            using (var packageReader = new PackageReader(readWriteStream, leaveStreamOpen: true))
            {
                var nuspecReader = packageReader.GetNuspecReader();

                // Read <metadata> node from nuspec
                var metadataNode = nuspecReader.Xml.Root.Elements()
                                   .FirstOrDefault(e => StringComparer.Ordinal.Equals(e.Name.LocalName, "metadata"));
                if (metadataNode == null)
                {
                    throw new PackagingException("The package manifest is missing the 'metadata' node.");
                }

                // Convert metadata into a ManifestEdit so that we can run it through the editing pipeline
                var editableManifestElements = new ManifestEdit
                {
                    Title                    = ReadFromMetadata(metadataNode, "title"),
                    Authors                  = ReadFromMetadata(metadataNode, "authors"),
                    Copyright                = ReadFromMetadata(metadataNode, "copyright"),
                    Description              = ReadFromMetadata(metadataNode, "description"),
                    IconUrl                  = ReadFromMetadata(metadataNode, "iconUrl"),
                    LicenseUrl               = ReadFromMetadata(metadataNode, "licenseUrl"),
                    ProjectUrl               = ReadFromMetadata(metadataNode, "projectUrl"),
                    ReleaseNotes             = ReadFromMetadata(metadataNode, "releasenotes"),
                    RequireLicenseAcceptance = ReadBoolFromMetadata(metadataNode, "requireLicenseAcceptance"),
                    Summary                  = ReadFromMetadata(metadataNode, "summary"),
                    Tags = ReadFromMetadata(metadataNode, "tags")
                };

                // Perform edits
                foreach (var edit in edits)
                {
                    edit.Invoke(editableManifestElements);
                }

                // Update the <metadata> node
                WriteToMetadata(metadataNode, "title", editableManifestElements.Title);
                WriteToMetadata(metadataNode, "authors", editableManifestElements.Authors);
                WriteToMetadata(metadataNode, "copyright", editableManifestElements.Copyright);
                WriteToMetadata(metadataNode, "description", editableManifestElements.Description);
                WriteToMetadata(metadataNode, "iconUrl", editableManifestElements.IconUrl);
                WriteToMetadata(metadataNode, "licenseUrl", editableManifestElements.LicenseUrl);
                WriteToMetadata(metadataNode, "projectUrl", editableManifestElements.ProjectUrl);
                WriteToMetadata(metadataNode, "releasenotes", editableManifestElements.ReleaseNotes);
                WriteToMetadata(metadataNode, "requireLicenseAcceptance", editableManifestElements.RequireLicenseAcceptance.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
                WriteToMetadata(metadataNode, "summary", editableManifestElements.Summary);
                WriteToMetadata(metadataNode, "tags", editableManifestElements.Tags);

                // Update the package stream
                using (var newManifestStream = new MemoryStream())
                {
                    nuspecReader.Xml.Save(newManifestStream);

                    using (var archive = new ZipArchive(readWriteStream, ZipArchiveMode.Update, leaveOpen: true))
                    {
                        var manifestEntries = archive.Entries
                                              .Where(entry => entry.FullName.IndexOf("/", StringComparison.OrdinalIgnoreCase) == -1 &&
                                                     entry.Name.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase)).ToList();

                        if (manifestEntries.Count == 0)
                        {
                            throw new PackagingException("Nuspec file does not exist in package.");
                        }

                        if (manifestEntries.Count > 1)
                        {
                            throw new PackagingException("Package contains multiple nuspec files.");
                        }

                        var manifestEntry = manifestEntries[0];

                        using (var manifestOutputStream = manifestEntry.Open())
                        {
                            manifestOutputStream.SetLength(0);
                            newManifestStream.Position = 0;
                            newManifestStream.CopyTo(manifestOutputStream);
                        }
                    }
                }
            }
        }
Exemple #8
0
        public override void ExecuteCommand()
        {
            Log.Trace("Getting latest packages...");
            var packages = GetLatestStablePackages();

            Log.Trace("Getting previously curated packages...");
            var alreadyCuratedPackageIds = GetAlreadyCuratedPackageIds();

            Log.Trace("Calculating minimum difference set...");
            var packageIdsToCurate = packages.Keys.Except(alreadyCuratedPackageIds).ToList();

            var totalCount     = packageIdsToCurate.Count;
            var processedCount = 0;

            Log.Trace(
                "Curating {0} packages for the WebMatrix curated on '{1}',",
                totalCount,
                ConnectionString);

            Parallel.ForEach(packageIdsToCurate, new ParallelOptions {
                MaxDegreeOfParallelism = 10
            }, packageIdToCurate =>
            {
                var package = packages[packageIdToCurate];

                try
                {
                    var downloadPath = DownloadPackage(package);

                    bool shouldBeIncluded;
                    using (var nugetPackage = new PackageReader(File.OpenRead(downloadPath)))
                    {
                        var nuspecReader = nugetPackage.GetNuspecReader();
                        var metadata     = nuspecReader.GetMetadata()
                                           .ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.OrdinalIgnoreCase);

                        string tags;
                        shouldBeIncluded = metadata.TryGetValue("tags", out tags) && tags.ToLowerInvariant().Contains("aspnetwebpages");

                        if (!shouldBeIncluded)
                        {
                            shouldBeIncluded = true;
                            foreach (var file in nugetPackage.GetFiles())
                            {
                                var fi = new FileInfo(file);
                                if (fi.Extension == ".ps1" || fi.Extension == ".t4")
                                {
                                    shouldBeIncluded = false;
                                    break;
                                }
                            }
                        }

                        if (shouldBeIncluded)
                        {
                            AddPackageToCuratedFeed(package);
                        }
                    }

                    File.Delete(downloadPath);

                    Interlocked.Increment(ref processedCount);
                    Log.Info(
                        "{2} package '{0}.{1}' ({3} of {4}).",
                        package.Id,
                        package.Version,
                        shouldBeIncluded ? "Curated" : "Ignored",
                        processedCount,
                        totalCount);
                }
                catch (Exception ex)
                {
                    Interlocked.Increment(ref processedCount);
                    Log.Error(
                        "Error curating package '{0}.{1}' ({2} of {3}): {4}.",
                        package.Id,
                        package.Version,
                        processedCount,
                        totalCount,
                        ex.Message);
                }
            });
        }
Exemple #9
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
                using (var packageToPush = new PackageReader(packageStream, leaveStreamOpen: false))
                {
                    NuspecReader nuspec = null;
                    try
                    {
                        nuspec = packageToPush.GetNuspecReader();
                    }
                    catch (Exception ex)
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                    CultureInfo.CurrentCulture,
                                                                    Strings.UploadPackage_InvalidNuspec,
                                                                    ex.Message)));
                    }

                    if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion)
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                    CultureInfo.CurrentCulture,
                                                                    Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                    nuspec.GetMinClientVersion())));
                    }

                    // Ensure that the user can push packages for this partialId.
                    var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId());
                    if (packageRegistration != null)
                    {
                        if (!packageRegistration.IsOwner(user))
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
                        }

                        // Check if a particular Id-Version combination already exists. We eventually need to remove this check.
                        string normalizedVersion = nuspec.GetVersion().ToNormalizedString();
                        bool   packageExists     =
                            packageRegistration.Packages.Any(
                                p => String.Equals(
                                    p.NormalizedVersion,
                                    normalizedVersion,
                                    StringComparison.OrdinalIgnoreCase));

                        if (packageExists)
                        {
                            return(new HttpStatusCodeWithBodyResult(
                                       HttpStatusCode.Conflict,
                                       String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                     nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe())));
                        }
                    }

                    var packageStreamMetadata = new PackageStreamMetadata
                    {
                        HashAlgorithm = Constants.Sha512HashAlgorithmId,
                        Hash          = CryptographyService.GenerateHash(packageStream.AsSeekableStream()),
                        Size          = packageStream.Length,
                    };

                    var package = PackageService.CreatePackage(packageToPush, packageStreamMetadata, user, commitChanges: false);
                    AutoCuratePackage.Execute(package, packageToPush, commitChanges: false);
                    EntitiesContext.SaveChanges();

                    using (Stream uploadStream = packageStream)
                    {
                        uploadStream.Position = 0;
                        await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream());

                        IndexingService.UpdatePackage(package);
                    }
                }

            return(new HttpStatusCodeResult(HttpStatusCode.Created));
        }