Beispiel #1
0
 public static V2FeedPackageInfo ToV2FeedPackageInfo(
     this NuspecReader reader, PackageDerivedData packageDerivedData, string downloadUrl, long downloadCount)
 {
     return(new V2FeedPackageInfo(
                identity: new PackageIdentity(reader.GetId(), reader.GetVersion()),
                title: reader.GetTitle(),
                summary: reader.GetSummary(),
                description: reader.GetDescription(),
                authors: reader.GetAuthors().Split(','),
                owners: reader.GetOwners().Split(','),
                iconUrl: reader.GetIconUrl(),
                licenseUrl: reader.GetLicenseUrl(),
                projectUrl: reader.GetProjectUrl(),
                reportAbuseUrl: reader.GetProjectUrl(),
                tags: reader.GetTags(),
                created: packageDerivedData.Created,
                lastEdited: packageDerivedData.LastUpdated,
                published: packageDerivedData.LastUpdated,
                dependencies: DependencySetsAsString(reader.GetDependencyGroups()),
                requireLicenseAccept: reader.GetRequireLicenseAcceptance(),
                downloadUrl: downloadUrl,
                downloadCount: downloadCount.ToString(),
                packageHash: packageDerivedData.PackageHash,
                packageHashAlgorithm: packageDerivedData.PackageHashAlgorithm,
                minClientVersion: reader.GetMinClientVersion()
                ));
 }
 public static PackageMetadata FromNuspecReader(NuspecReader nuspecReader)
 {
     return(new PackageMetadata(
                nuspecReader.GetMetadata().ToDictionary(kvp => kvp.Key, kvp => kvp.Value),
                nuspecReader.GetDependencyGroups(),
                nuspecReader.GetFrameworkReferenceGroups(),
                nuspecReader.GetMinClientVersion()
                ));
 }
Beispiel #3
0
        /// <summary>
        /// Gets package metadata from a the provided <see cref="NuspecReader"/> instance.
        /// </summary>
        /// <param name="nuspecReader">The <see cref="NuspecReader"/> instance used to read the <see cref="PackageMetadata"/></param>
        /// <param name="strict">
        /// Whether or not to be strict when reading the <see cref="NuspecReader"/>. This should be <code>true</code>
        /// on initial ingestion but false when a package that has already been accepted is being processed.</param>
        /// <exception cref="PackagingException">
        /// We default to use a strict version-check on dependency groups.
        /// When an invalid dependency version range is detected, a <see cref="PackagingException"/> will be thrown.
        /// </exception>
        public static PackageMetadata FromNuspecReader(NuspecReader nuspecReader, bool strict)
        {
            var strictNuspecReader = new StrictNuspecReader(nuspecReader.Xml);
            var metadataLookup     = strictNuspecReader.GetMetadataLookup();

            if (strict)
            {
                var duplicates = metadataLookup
                                 .Where(g => g.Count() > 1)
                                 .Select(g => g.Key)
                                 .ToList();

                if (duplicates.Any())
                {
                    throw new PackagingException(string.Format(
                                                     CoreStrings.Manifest_DuplicateMetadataElements,
                                                     string.Join("', '", duplicates)));
                }
            }

            // Reject invalid metadata element names. Today this only rejects element names that collide with
            // properties generated downstream.
            var metadataKeys = new HashSet <string>(metadataLookup.Select(g => g.Key));

            metadataKeys.IntersectWith(RestrictedMetadataElements);
            if (metadataKeys.Any())
            {
                throw new PackagingException(string.Format(
                                                 CoreStrings.Manifest_InvalidMetadataElements,
                                                 string.Join("', '", metadataKeys.OrderBy(x => x))));
            }

            // Reject non-boolean values for boolean metadata.
            foreach (var booleanName in BooleanMetadataElements)
            {
                foreach (var unparsedBoolean in metadataLookup[booleanName])
                {
                    if (!bool.TryParse(unparsedBoolean, out var parsedBoolean))
                    {
                        throw new PackagingException(string.Format(
                                                         CoreStrings.Manifest_InvalidBooleanMetadata,
                                                         booleanName));
                    }
                }
            }

            return(new PackageMetadata(
                       nuspecReader.GetMetadata().ToDictionary(kvp => kvp.Key, kvp => kvp.Value),
                       nuspecReader.GetDependencyGroups(useStrictVersionCheck: strict),
                       nuspecReader.GetFrameworkReferenceGroups(),
                       nuspecReader.GetPackageTypes(),
                       nuspecReader.GetMinClientVersion(),
                       nuspecReader.GetRepositoryMetadata(),
                       nuspecReader.GetLicenseMetadata()));
        }
        public static void CheckMinClientVersion(Stream packageStream, PackageIdentity packageIdentity)
        {
            var packageZipArchive       = new ZipArchive(packageStream);
            var packageReader           = new PackageReader(packageZipArchive);
            var nuspecReader            = new NuspecReader(packageReader.GetNuspec());
            var packageMinClientVersion = nuspecReader.GetMinClientVersion();

            // validate that the current version of NuGet satisfies the minVersion attribute specified in the .nuspec
            if (Constants.NuGetSemanticVersion < packageMinClientVersion)
            {
                throw new NuGetVersionNotSatisfiedException(
                          String.Format(CultureInfo.CurrentCulture, Strings.PackageMinVersionNotSatisfied, packageIdentity,
                                        packageMinClientVersion.ToNormalizedString(), Constants.NuGetSemanticVersion.ToNormalizedString()));
            }
        }
Beispiel #5
0
        public ServerPackage(NuspecReader package, PackageDerivedData packageDerivedData)
        {
            Id         = package.GetId();
            Version    = package.GetVersion();
            Title      = package.GetTitle();
            Authors    = package.GetAuthors();
            Owners     = package.GetOwners();
            IconUrl    = package.GetIconUrl();
            LicenseUrl = package.GetLicenseUrl();
            ProjectUrl = package.GetProjectUrl();
            RequireLicenseAcceptance = package.GetRequireLicenseAcceptance();
            DevelopmentDependency    = package.GetDevelopmentDependency();
            Description             = package.GetDescription();
            Summary                 = package.GetSummary();
            ReleaseNotes            = package.GetReleaseNotes();
            Language                = package.GetLanguage();
            Tags                    = package.GetTags();
            Copyright               = package.GetCopyright();
            MinClientVersion        = package.GetMinClientVersion();
            ReportAbuseUrl          = null;
            DownloadCount           = 0;
            SemVer1IsAbsoluteLatest = false;
            SemVer1IsLatest         = false;
            SemVer2IsAbsoluteLatest = false;
            SemVer2IsLatest         = false;
            //FIXME is this OK?
            Listed = true;

            IsSemVer2 = IsPackageSemVer2(package);

            _dependencySets = package.GetDependencyGroups().ToList();
            Dependencies    = _dependencySets.DependencySetsAsString();

            _supportedFrameworks = package.GetFrameworkReferenceGroups().Select(f => f.TargetFramework).ToList();
            SupportedFrameworks  = string.Join("|", _supportedFrameworks.Select(f => f.GetFrameworkString()));

            PackageSize          = packageDerivedData.PackageSize;
            PackageHash          = packageDerivedData.PackageHash;
            PackageHashAlgorithm = packageDerivedData.PackageHashAlgorithm;
            LastUpdated          = packageDerivedData.LastUpdated;
            Created  = packageDerivedData.Created;
            Path     = packageDerivedData.Path;
            FullPath = packageDerivedData.FullPath;
        }
Beispiel #6
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
            {
                try
                {
                    using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true))
                    {
                        var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew

                        var entryInTheFuture = archive.Entries.FirstOrDefault(
                            e => e.LastWriteTime.UtcDateTime > reference);

                        if (entryInTheFuture != null)
                        {
                            return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                        CultureInfo.CurrentCulture,
                                                                        Strings.PackageEntryFromTheFuture,
                                                                        entryInTheFuture.Name)));
                        }
                    }

                    using (var packageToPush = new PackageArchiveReader(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 = await PackageService.CreatePackageAsync(
                            packageToPush,
                            packageStreamMetadata,
                            user,
                            commitChanges : false);

                        await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                        await EntitiesContext.SaveChangesAsync();

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

                            IndexingService.UpdatePackage(package);
                        }

                        MessageService.SendPackageAddedNotice(package,
                                                              Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme),
                                                              Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme));

                        return(new HttpStatusCodeResult(HttpStatusCode.Created));
                    }
                }
                catch (InvalidPackageException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (InvalidDataException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (EntityException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
                catch (FrameworkException ex)
                {
                    return(BadRequestForExceptionMessage(ex));
                }
            }
        }
Beispiel #7
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            // Get the user
            var user = GetCurrentUser();

            using (var packageStream = ReadPackageFromRequest())
            {
                try
                {
                    using (var packageToPush = new PackageArchiveReader(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 = await PackageService.CreatePackageAsync(packageToPush, packageStreamMetadata, user, commitChanges : false);

                        await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                        await EntitiesContext.SaveChangesAsync();

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

                            IndexingService.UpdatePackage(package);
                        }

                        return(new HttpStatusCodeResult(HttpStatusCode.Created));
                    }
                }
                catch (InvalidDataException ex)
                {
                    return(new HttpStatusCodeWithBodyResult(
                               HttpStatusCode.BadRequest,
                               string.Format(CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidPackage, ex.Message)));
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Create a PackageDetails page that contains all the package information.
        /// </summary>
        public JObject CreatePackageDetails(PackageInput packageInput)
        {
            var now          = DateTimeOffset.UtcNow;
            var package      = packageInput.Package;
            var nuspec       = XDocument.Load(package.GetNuspec());
            var nuspecReader = new NuspecReader(nuspec);

            var pageId = Guid.NewGuid().ToString().ToLowerInvariant();

            var rootUri = UriUtility.CreateUri($"{_context.Source.BaseURI}catalog/data/{pageId}.json");

            packageInput.PackageDetailsUri = rootUri;

            var json = JsonUtility.Create(rootUri, new List <string>()
            {
                "PackageDetails", "catalog:Permalink"
            });

            json.Add("commitId", _context.CommitId.ToString().ToLowerInvariant());
            json.Add("commitTimeStamp", DateTimeOffset.UtcNow.GetDateString());
            json.Add("sleet:operation", "add");

            var context = JsonUtility.GetContext("Catalog");

            json.Add("@context", context);

            json.Add("id", packageInput.Identity.Id);
            json.Add("version", packageInput.Identity.Version.ToFullVersionString());

            json.Add("created", now.GetDateString());
            json.Add("lastEdited", "0001-01-01T00:00:00Z");

            var copyProperties = new List <string>()
            {
                "authors",
                "copyright",
                "description",
                "iconUrl",
                "projectUrl",
                "licenseUrl",
                "language",
                "summary",
                "owners",
                "releaseNotes"
            };

            foreach (var propertyName in copyProperties)
            {
                json.Add(CreateProperty(propertyName, propertyName, nuspecReader));
            }

            json.Add("isPrerelease", packageInput.Identity.Version.IsPrerelease);

            // Unused?
            json.Add("licenseNames", string.Empty);
            json.Add("licenseReportUrl", string.Empty);

            // All packages are listed
            json.Add("listed", true);

            var titleValue = GetEntry(nuspecReader, "title");

            if (!string.IsNullOrEmpty(titleValue))
            {
                json.Add("title", titleValue);
            }

            using (var stream = File.OpenRead(packageInput.PackagePath))
            {
                using (var sha512 = SHA512.Create())
                {
                    var packageHash = Convert.ToBase64String(sha512.ComputeHash(stream));

                    json.Add("packageHash", packageHash);
                    json.Add("packageHashAlgorithm", "SHA512");
                }

                json.Add("packageSize", stream.Length);
            }

            json.Add("published", now.GetDateString());
            json.Add("requireLicenseAcceptance", GetEntry(nuspecReader, "requireLicenseAcceptance").Equals("true", StringComparison.OrdinalIgnoreCase));

            var minVersion = nuspecReader.GetMinClientVersion();

            if (minVersion != null)
            {
                json.Add("minClientVersion", minVersion.ToIdentityString());
            }

            // Tags
            var tagSet = new HashSet <string>(GetEntry(nuspecReader, "tags").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase);

            tagSet.Remove(string.Empty);
            var tagArray = new JArray(tagSet);

            json.Add("tags", tagArray);

            // Framework assemblies
            var fwrGroups = nuspecReader.GetFrameworkReferenceGroups();
            var fwrArray  = new JArray();

            json.Add("frameworkAssemblyGroup", fwrArray);

            foreach (var group in fwrGroups.OrderBy(e => e.TargetFramework.GetShortFolderName(), StringComparer.OrdinalIgnoreCase))
            {
                var groupTFM  = group.TargetFramework.GetShortFolderName().ToLowerInvariant();
                var groupNode = JsonUtility.Create(rootUri, $"frameworkassemblygroup/{groupTFM}".ToLowerInvariant(), "FrameworkAssemblyGroup");

                // Leave the framework property out for the 'any' group
                if (!group.TargetFramework.IsAny)
                {
                    groupNode.Add("targetFramework", groupTFM);
                }

                fwrArray.Add(groupNode);

                if (group.Items.Any())
                {
                    var assemblyArray = new JArray();
                    groupNode.Add("assembly", assemblyArray);

                    foreach (var fwAssembly in group.Items.Distinct().OrderBy(e => e, StringComparer.OrdinalIgnoreCase))
                    {
                        assemblyArray.Add(fwAssembly);
                    }
                }
            }

            // Dependencies
            var dependencyGroups = nuspecReader.GetDependencyGroups();

            var depArray = new JArray();

            json.Add("dependencyGroups", depArray);

            foreach (var group in dependencyGroups.OrderBy(e => e.TargetFramework.GetShortFolderName(), StringComparer.OrdinalIgnoreCase))
            {
                var groupTFM  = group.TargetFramework.GetShortFolderName().ToLowerInvariant();
                var groupNode = JsonUtility.Create(rootUri, $"dependencygroup/{groupTFM}".ToLowerInvariant(), "PackageDependencyGroup");

                // Leave the framework property out for the 'any' group
                if (!group.TargetFramework.IsAny)
                {
                    groupNode.Add("targetFramework", groupTFM);
                }

                depArray.Add(groupNode);

                if (group.Packages.Any())
                {
                    var packageArray = new JArray();
                    groupNode.Add("dependencies", packageArray);

                    foreach (var depPackage in group.Packages.Distinct().OrderBy(e => e.Id, StringComparer.OrdinalIgnoreCase))
                    {
                        var packageNode = JsonUtility.Create(rootUri, $"dependencygroup/{groupTFM}/{depPackage.Id}".ToLowerInvariant(), "PackageDependency");
                        packageNode.Add("id", depPackage.Id);
                        packageNode.Add("range", depPackage.VersionRange.ToNormalizedString());

                        packageArray.Add(packageNode);
                    }
                }
            }

            json.Add("packageContent", packageInput.NupkgUri.AbsoluteUri);

            // add flatcontainer files
            var packageEntriesArray = new JArray();

            json.Add("packageEntries", packageEntriesArray);
            var packageEntryIndex = 0;

            foreach (var entry in packageInput.Zip.Entries.OrderBy(e => e.FullName, StringComparer.OrdinalIgnoreCase))
            {
                var fileEntry = JsonUtility.Create(rootUri, $"packageEntry/{packageEntryIndex}", "packageEntry");
                fileEntry.Add("fullName", entry.FullName);
                fileEntry.Add("length", entry.Length);
                fileEntry.Add("lastWriteTime", entry.LastWriteTime.GetDateString());

                packageEntriesArray.Add(fileEntry);
                packageEntryIndex++;
            }

            json.Add("sleet:toolVersion", Constants.SleetVersion.ToFullVersionString());

            return(JsonLDTokenComparer.Format(json));
        }