Example #1
0
        public PackageViewModel(Package package)
        {
            _package = package ?? throw new ArgumentNullException(nameof(package));

            FullVersion = NuGetVersionFormatter.ToFullString(package.Version);
            IsSemVer2   = package.SemVerLevelKey == SemVerLevelKey.SemVer2;

            Version = String.IsNullOrEmpty(package.NormalizedVersion) ?
                      NuGetVersionFormatter.Normalize(package.Version) :
                      package.NormalizedVersion;

            NuGetVersion = NuGetVersion.Parse(FullVersion);

            Description                = package.Description;
            ReleaseNotes               = package.ReleaseNotes;
            IconUrl                    = package.IconUrl;
            LatestVersion              = package.IsLatest;
            LatestVersionSemVer2       = package.IsLatestSemVer2;
            LatestStableVersion        = package.IsLatestStable;
            LatestStableVersionSemVer2 = package.IsLatestStableSemVer2;
            DevelopmentDependency      = package.DevelopmentDependency;
            LastUpdated                = package.Published;
            Listed         = package.Listed;
            _packageStatus = package.PackageStatusKey;
            DownloadCount  = package.DownloadCount;
            Prerelease     = package.IsPrerelease;
        }
        public PackageViewModel(Package package)
        {
            _package = package;

            _fullVersion = NuGetVersionFormatter.ToFullStringOrFallback(package.Version, fallback: package.Version);
            _isSemVer2   = package.SemVerLevelKey == SemVerLevelKey.SemVer2;

            Version = String.IsNullOrEmpty(package.NormalizedVersion) ?
                      NuGetVersionFormatter.Normalize(package.Version) :
                      package.NormalizedVersion;

            Description                = package.Description;
            ReleaseNotes               = package.ReleaseNotes;
            IconUrl                    = package.IconUrl;
            ProjectUrl                 = package.ProjectUrl;
            LicenseUrl                 = package.LicenseUrl;
            HideLicenseReport          = package.HideLicenseReport;
            LatestVersion              = package.IsLatest;
            LatestVersionSemVer2       = package.IsLatestSemVer2;
            LatestStableVersion        = package.IsLatestStable;
            LatestStableVersionSemVer2 = package.IsLatestStableSemVer2;
            LastUpdated                = package.Published;
            Listed           = package.Listed;
            Deleted          = package.Deleted;
            DownloadCount    = package.DownloadCount;
            Prerelease       = package.IsPrerelease;
            LicenseReportUrl = package.LicenseReportUrl;

            var licenseNames = package.LicenseNames;

            if (!String.IsNullOrEmpty(licenseNames))
            {
                LicenseNames = licenseNames.Split(',').Select(l => l.Trim());
            }
        }
        public Task DeleteLicenseFileAsync(string id, string version)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentException($"{nameof(id)} cannot be empty", nameof(id));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (string.IsNullOrWhiteSpace(version))
            {
                throw new ArgumentException($"{nameof(version)} cannot be empty", nameof(version));
            }

            var normalizedVersion = NuGetVersionFormatter.Normalize(version);
            var fileName          = BuildLicenseFileName(id, normalizedVersion);

            return(_fileStorageService.DeleteFileAsync(_metadata.PackageContentFolderName, fileName));
        }
Example #4
0
 static string BuildFileName(
     string id,
     string version, string extension, string path)
 {
     return(string.Format(
                path,
                id.ToLowerInvariant(),
                NuGetVersionFormatter.Normalize(version).ToLowerInvariant(), // No matter what ends up getting passed in, the version should be normalized
                extension));
 }
Example #5
0
 static string BuildFileName(
     string id,
     string version)
 {
     return(string.Format(
                Constants.PackageFileSavePathTemplate,
                id.ToLowerInvariant(),
                NuGetVersionFormatter.Normalize(version).ToLowerInvariant(), // No matter what ends up getting passed in, the version should be normalized
                Constants.NuGetPackageFileExtension));
 }
        public virtual Package FilterExactPackage(
            IReadOnlyCollection <Package> packages,
            string version)
        {
            var normalizedVersion = NuGetVersionFormatter.Normalize(version);

            return(packages.SingleOrDefault(p => string.Equals(
                                                p.NormalizedVersion,
                                                normalizedVersion,
                                                StringComparison.OrdinalIgnoreCase)));
        }
Example #7
0
        private DisplayPackageViewModel SetupCommon(
            DisplayPackageViewModel viewModel,
            Package package,
            string pushedBy,
            IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation)
        {
            viewModel.NuGetVersion = NuGetVersion.Parse(NuGetVersionFormatter.ToFullString(package.Version));
            viewModel.Copyright    = package.Copyright;

            viewModel.DownloadCount = package.DownloadCount;
            viewModel.LastEdited    = package.LastEdited;

            viewModel.TotalDaysSinceCreated = 0;
            viewModel.DownloadsPerDay       = 0;

            viewModel.PushedBy = pushedBy;

            viewModel.InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);

            if (PackageHelper.TryPrepareUrlForRendering(package.ProjectUrl, out string projectUrl))
            {
                viewModel.ProjectUrl = projectUrl;
            }

            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;

            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }

            if (packageKeyToDeprecation != null && packageKeyToDeprecation.TryGetValue(package.Key, out var deprecation))
            {
                viewModel.DeprecationStatus = deprecation.Status;
            }
            else
            {
                viewModel.DeprecationStatus = PackageDeprecationStatus.NotDeprecated;
            }

            return(viewModel);
        }
        public Task DeleteValidationPackageFileAsync(string id, string version)
        {
            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            var normalizedVersion = NuGetVersionFormatter.Normalize(version);
            var fileName          = BuildFileName(
                id,
                normalizedVersion,
                _metadata.FileSavePathTemplate,
                _metadata.FileExtension);

            return(_fileStorageService.DeleteFileAsync(_metadata.ValidationFolderName, fileName));
        }
Example #9
0
        protected void InterceptPackageMaterialized(Package package)
        {
            if (package == null || package.PackageRegistration == null)
            {
                return;
            }

            var packageNormalizedVersion = String.IsNullOrEmpty(package.NormalizedVersion)
                ? NuGetVersionFormatter.Normalize(package.Version)
                : package.NormalizedVersion;

            int downloadCount;

            if (_downloadCountService.TryGetDownloadCountForPackage(package.PackageRegistration.Id, packageNormalizedVersion, out downloadCount))
            {
                package.DownloadCount = downloadCount;
            }
        }
Example #10
0
        public Task DeletePackageFileAsync(string id, string version)
        {
            if (String.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (String.IsNullOrWhiteSpace(version))
            {
                throw new ArgumentNullException(nameof(version));
            }

            var normalizedVersion = NuGetVersionFormatter.Normalize(version);

            var fileName = BuildFileName(id, normalizedVersion, CoreConstants.PackageFileSavePathTemplate, CoreConstants.NuGetPackageFileExtension);

            return(_fileStorageService.DeleteFileAsync(CoreConstants.PackagesFolderName, fileName));
        }
        public PackageViewModel(Package package)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            _package = package;

            FullVersion = NuGetVersionFormatter.ToFullStringOrFallback(package.Version, fallback: package.Version);
            IsSemVer2   = package.SemVerLevelKey == SemVerLevelKey.SemVer2;

            Version = String.IsNullOrEmpty(package.NormalizedVersion) ?
                      NuGetVersionFormatter.Normalize(package.Version) :
                      package.NormalizedVersion;

            NuGetVersion = NuGetVersion.Parse(FullVersion);

            Description                = package.Description;
            ReleaseNotes               = package.ReleaseNotes;
            IconUrl                    = package.IconUrl;
            ProjectUrl                 = package.ProjectUrl;
            RepositoryUrl              = package.RepositoryUrl;
            RepositoryType             = GetRepositoryKind(package.RepositoryUrl, package.RepositoryType);
            LicenseUrl                 = package.LicenseUrl;
            HideLicenseReport          = package.HideLicenseReport;
            LatestVersion              = package.IsLatest;
            LatestVersionSemVer2       = package.IsLatestSemVer2;
            LatestStableVersion        = package.IsLatestStable;
            LatestStableVersionSemVer2 = package.IsLatestStableSemVer2;
            LastUpdated                = package.Published;
            Listed           = package.Listed;
            _packageStatus   = package.PackageStatusKey;
            DownloadCount    = package.DownloadCount;
            Prerelease       = package.IsPrerelease;
            LicenseReportUrl = package.LicenseReportUrl;

            var licenseNames = package.LicenseNames;

            if (!string.IsNullOrEmpty(licenseNames))
            {
                LicenseNames = licenseNames.Split(',').Select(l => l.Trim());
            }
        }
Example #12
0
        public PackageViewModel(Package package)
        {
            _package = package;

            _fullVersion = NuGetVersionFormatter.ToFullStringOrFallback(package.Version, fallback: package.Version);
            _isSemVer2   = package.SemVerLevelKey == SemVerLevelKey.SemVer2;

            Version = String.IsNullOrEmpty(package.NormalizedVersion) ?
                      NuGetVersionFormatter.Normalize(package.Version) :
                      package.NormalizedVersion;

            NuGetVersion = NuGetVersion.Parse(_fullVersion);

            HasSemVer2Version    = NuGetVersion.IsSemVer2;
            HasSemVer2Dependency = package.Dependencies.ToList()
                                   .Where(pd => !string.IsNullOrEmpty(pd.VersionSpec))
                                   .Select(pd => VersionRange.Parse(pd.VersionSpec))
                                   .Any(p => (p.HasUpperBound && p.MaxVersion.IsSemVer2) || (p.HasLowerBound && p.MinVersion.IsSemVer2));

            Description                = package.Description;
            ReleaseNotes               = package.ReleaseNotes;
            IconUrl                    = package.IconUrl;
            ProjectUrl                 = package.ProjectUrl;
            LicenseUrl                 = package.LicenseUrl;
            HideLicenseReport          = package.HideLicenseReport;
            LatestVersion              = package.IsLatest;
            LatestVersionSemVer2       = package.IsLatestSemVer2;
            LatestStableVersion        = package.IsLatestStable;
            LatestStableVersionSemVer2 = package.IsLatestStableSemVer2;
            LastUpdated                = package.Published;
            Listed           = package.Listed;
            Deleted          = package.PackageStatusKey == PackageStatus.Deleted;
            DownloadCount    = package.DownloadCount;
            Prerelease       = package.IsPrerelease;
            LicenseReportUrl = package.LicenseReportUrl;

            var licenseNames = package.LicenseNames;

            if (!String.IsNullOrEmpty(licenseNames))
            {
                LicenseNames = licenseNames.Split(',').Select(l => l.Trim());
            }
        }
        protected static string BuildFileName(Package package, string format, string extension)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            if (package.PackageRegistration == null ||
                String.IsNullOrWhiteSpace(package.PackageRegistration.Id) ||
                (String.IsNullOrWhiteSpace(package.NormalizedVersion) && String.IsNullOrWhiteSpace(package.Version)))
            {
                throw new ArgumentException(CoreStrings.PackageIsMissingRequiredData, nameof(package));
            }

            return(BuildFileName(
                       package.PackageRegistration.Id,
                       string.IsNullOrEmpty(package.NormalizedVersion) ?
                       NuGetVersionFormatter.Normalize(package.Version) :
                       package.NormalizedVersion, format, extension));
        }
Example #14
0
        public PackageViewModel Setup(PackageViewModel viewModel, Package package)
        {
            if (viewModel == null)
            {
                throw new ArgumentNullException(nameof(viewModel));
            }

            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            viewModel.FullVersion = NuGetVersionFormatter.ToFullString(package.Version);
            viewModel.IsSemVer2   = package.SemVerLevelKey == SemVerLevelKey.SemVer2;

            viewModel.Id      = package.PackageRegistration.Id;
            viewModel.Version = String.IsNullOrEmpty(package.NormalizedVersion) ?
                                NuGetVersionFormatter.Normalize(package.Version) :
                                package.NormalizedVersion;

            viewModel.Description                = package.Description;
            viewModel.ReleaseNotes               = package.ReleaseNotes;
            viewModel.IconUrl                    = _iconUrlProvider.GetIconUrlString(package);
            viewModel.LatestVersion              = package.IsLatest;
            viewModel.LatestVersionSemVer2       = package.IsLatestSemVer2;
            viewModel.LatestStableVersion        = package.IsLatestStable;
            viewModel.LatestStableVersionSemVer2 = package.IsLatestStableSemVer2;
            viewModel.DevelopmentDependency      = package.DevelopmentDependency;
            viewModel.LastUpdated                = package.Published;
            viewModel.Listed               = package.Listed;
            viewModel.DownloadCount        = package.DownloadCount;
            viewModel.Prerelease           = package.IsPrerelease;
            viewModel.FailedValidation     = package.PackageStatusKey == PackageStatus.FailedValidation;
            viewModel.Available            = package.PackageStatusKey == PackageStatus.Available;
            viewModel.Validating           = package.PackageStatusKey == PackageStatus.Validating;
            viewModel.Deleted              = package.PackageStatusKey == PackageStatus.Deleted;
            viewModel.PackageStatusSummary = GetPackageStatusSummary(package.PackageStatusKey, package.Listed);
            viewModel.TotalDownloadCount   = package.PackageRegistration.DownloadCount;

            return(viewModel);
        }
        public virtual Package FindPackageByIdAndVersionStrict(string id, string version)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (string.IsNullOrEmpty(version))
            {
                throw new ArgumentException(nameof(version));
            }

            var normalizedVersion = NuGetVersionFormatter.Normalize(version);

            // These string comparisons are case-(in)sensitive depending on SQLServer collation.
            // Case-insensitive collation is recommended, e.g. SQL_Latin1_General_CP1_CI_AS.
            var package = GetPackagesByIdQueryable(id)
                          .SingleOrDefault(p => p.NormalizedVersion == normalizedVersion);

            return(package);
        }
Example #16
0
        public static string GetSelectListText(Package package)
        {
            var tags = new List <string>();

            if (package.IsLatestSemVer2)
            {
                tags.Add("Latest");
            }

            var deprecation = package.Deprecations.SingleOrDefault();

            if (deprecation != null)
            {
                var deprecationReasons = new List <string>();

                if (deprecation.Status.HasFlag(PackageDeprecationStatus.Legacy))
                {
                    deprecationReasons.Add("Legacy");
                }

                if (deprecation.Status.HasFlag(PackageDeprecationStatus.CriticalBugs))
                {
                    deprecationReasons.Add("Critical Bugs");
                }

                if (deprecation.Status.HasFlag(PackageDeprecationStatus.Other))
                {
                    deprecationReasons.Add("Other");
                }

                if (deprecationReasons.Any())
                {
                    tags.Add("Deprecated - " + string.Join(", ", deprecationReasons));
                }
            }

            return(NuGetVersionFormatter.ToFullString(package.Version) + (tags.Any() ? $" ({string.Join(", ", tags)})" : string.Empty));
        }
Example #17
0
        protected void InterceptPackageMaterialized(Package package)
        {
            if (package == null || package.PackageRegistration == null)
            {
                return;
            }

            var packageNormalizedVersion = String.IsNullOrEmpty(package.NormalizedVersion)
                ? NuGetVersionFormatter.Normalize(package.Version)
                : package.NormalizedVersion;

            int downloadCount;

            if (_downloadCountService.TryGetDownloadCountForPackage(package.PackageRegistration.Id, packageNormalizedVersion, out downloadCount))
            {
                if (downloadCount < package.DownloadCount)
                {
                    _telemetryService.TrackPackageDownloadCountDecreasedFromGallery(package.PackageRegistration.Id, packageNormalizedVersion, package.DownloadCount, downloadCount);
                }

                package.DownloadCount = downloadCount;
            }
        }
Example #18
0
        public virtual async Task <ActionResult> GetPackage(string id, string version)
        {
            // some security paranoia about URL hacking somehow creating e.g. open redirects
            // validate user input: explicit calls to the same validators used during Package Registrations
            // Ideally shouldn't be necessary?
            if (!PackageIdValidator.IsValidPackageId(id ?? string.Empty))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid"));
            }

            // if version is non-null, check if it's semantically correct and normalize it.
            if (!String.IsNullOrEmpty(version))
            {
                NuGetVersion dummy;
                if (!NuGetVersion.TryParse(version, out dummy))
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version"));
                }

                // Normalize the version
                version = NuGetVersionFormatter.Normalize(version);
            }
            else
            {
                // If version is null, get the latest version from the database.
                // This ensures that on package restore scenario where version will be non null, we don't hit the database.
                try
                {
                    var package = PackageService.FindPackageByIdAndVersion(
                        id,
                        version,
                        SemVerLevelKey.SemVer2,
                        allowPrerelease: false);

                    if (package == null)
                    {
                        return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
                    }
                    version = package.NormalizedVersion;
                }
                catch (SqlException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
                catch (DataException e)
                {
                    QuietLog.LogHandledException(e);

                    // Database was unavailable and we don't have a version, return a 503
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion));
                }
            }

            if (ConfigurationService.Features.TrackPackageDownloadCountInLocalDatabase)
            {
                await PackageService.IncrementDownloadCountAsync(id, version);
            }

            return(await PackageFileService.CreateDownloadPackageActionResultAsync(
                       HttpContext.Request.Url,
                       id, version));
        }
Example #19
0
        public Document ToDocument()
        {
            var document = new Document();

            // Note: Used to identify index records for updates
            document.Add(new Field("PackageRegistrationKey",
                                   Package.PackageRegistrationKey.ToString(CultureInfo.InvariantCulture),
                                   Field.Store.YES,
                                   Field.Index.NOT_ANALYZED));

            document.Add(new Field("Key", Package.Key.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED));

            if (CuratedFeedKeys != null)
            {
                foreach (var feedKey in CuratedFeedKeys)
                {
                    document.Add(new Field("CuratedFeedKey", feedKey.ToString(CultureInfo.InvariantCulture), Field.Store.NO, Field.Index.NOT_ANALYZED));
                }
            }

            var field = new Field("Id-Exact", Package.PackageRegistration.Id.ToLowerInvariant(), Field.Store.NO, Field.Index.NOT_ANALYZED);

            field.Boost = 2.5f;
            document.Add(field);

            // Store description so we can show them in search results
            field       = new Field("Description", Package.Description, Field.Store.YES, Field.Index.ANALYZED);
            field.Boost = 0.1f;
            document.Add(field);

            // We store the Id/Title field in multiple ways, so that it's possible to match using multiple
            // styles of search
            // Note: no matter which way we store it, it will also be processed by the Analyzer later.

            // Style 1: As-Is Id, no tokenizing (so you can search using dot or dash-joined terms)
            // Boost this one
            field = new Field("Id", Package.PackageRegistration.Id, Field.Store.NO, Field.Index.ANALYZED);
            document.Add(field);

            // Style 2: dot+dash tokenized (so you can search using undotted terms)
            field       = new Field("Id", SplitId(Package.PackageRegistration.Id), Field.Store.NO, Field.Index.ANALYZED);
            field.Boost = 0.8f;
            document.Add(field);

            // Style 3: camel-case tokenized (so you can search using parts of the camelCasedWord).
            // De-boosted since matches are less likely to be meaningful
            field       = new Field("Id", CamelSplitId(Package.PackageRegistration.Id), Field.Store.NO, Field.Index.ANALYZED);
            field.Boost = 0.25f;
            document.Add(field);

            // If an element does not have a Title, fall back to Id, same as the website.
            var workingTitle = String.IsNullOrEmpty(Package.Title)
                                   ? Package.PackageRegistration.Id
                                   : Package.Title;

            // As-Is (stored for search results)
            field       = new Field("Title", workingTitle, Field.Store.YES, Field.Index.ANALYZED);
            field.Boost = 0.9f;
            document.Add(field);

            // no need to store dot+dash tokenized - we'll handle this in the analyzer
            field       = new Field("Title", SplitId(workingTitle), Field.Store.NO, Field.Index.ANALYZED);
            field.Boost = 0.8f;
            document.Add(field);

            // camel-case tokenized
            field       = new Field("Title", CamelSplitId(workingTitle), Field.Store.NO, Field.Index.ANALYZED);
            field.Boost = 0.5f;
            document.Add(field);

            if (!String.IsNullOrEmpty(Package.Tags))
            {
                // Store tags so we can show them in search results
                field       = new Field("Tags", Package.Tags, Field.Store.YES, Field.Index.ANALYZED);
                field.Boost = 0.8f;
                document.Add(field);
            }

            document.Add(new Field("Authors", Package.FlattenedAuthors.ToStringSafe(), Field.Store.YES, Field.Index.ANALYZED));

            // Fields for storing data to avoid hitting SQL while doing searches
            if (!String.IsNullOrEmpty(Package.IconUrl))
            {
                document.Add(new Field("IconUrl", Package.IconUrl, Field.Store.YES, Field.Index.NO));
            }

            if (Package.PackageRegistration.Owners.AnySafe())
            {
                string flattenedOwners = String.Join(";", Package.PackageRegistration.Owners.Select(o => o.Username));
                document.Add(new Field("Owners", flattenedOwners, Field.Store.NO, Field.Index.ANALYZED));
                document.Add(new Field("FlattenedOwners", flattenedOwners, Field.Store.YES, Field.Index.NO));
            }

            document.Add(new Field("Copyright", Package.Copyright.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Created", Package.Created.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("FlattenedDependencies", Package.FlattenedDependencies.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("FlattenedPackageTypes", Package.FlattenedPackageTypes.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Hash", Package.Hash.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("HashAlgorithm", Package.HashAlgorithm.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Id-Original", Package.PackageRegistration.Id, Field.Store.YES, Field.Index.NO));
            document.Add(new Field("IsVerified-Original", Package.PackageRegistration.IsVerified.ToString(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("LastUpdated", Package.LastUpdated.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            if (Package.LastEdited != null)
            {
                document.Add(new Field("LastEdited", Package.LastEdited.Value.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            }

            document.Add(new Field("Language", Package.Language.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("LicenseUrl", Package.LicenseUrl.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("MinClientVersion", Package.MinClientVersion.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Version", Package.Version.ToStringSafe(), Field.Store.YES, Field.Index.NO));

            string normalizedVersion = String.IsNullOrEmpty(Package.NormalizedVersion) ?
                                       NuGetVersionFormatter.Normalize(Package.Version) :
                                       Package.NormalizedVersion;

            document.Add(new Field("NormalizedVersion", normalizedVersion.ToStringSafe(), Field.Store.YES, Field.Index.NO));

            document.Add(new Field("VersionDownloadCount", Package.DownloadCount.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("PackageFileSize", Package.PackageFileSize.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("ProjectUrl", Package.ProjectUrl.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Published", Package.Published.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("ReleaseNotes", Package.ReleaseNotes.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("RequiresLicenseAcceptance", Package.RequiresLicenseAcceptance.ToString(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("Summary", Package.Summary.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("LicenseNames", Package.LicenseNames.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("LicenseReportUrl", Package.LicenseReportUrl.ToStringSafe(), Field.Store.YES, Field.Index.NO));
            document.Add(new Field("HideLicenseReport", Package.HideLicenseReport.ToStringSafe(), Field.Store.YES, Field.Index.NO));

            if (Package.SupportedFrameworks.AnySafe())
            {
                string joinedFrameworks = string.Join(";", Package.SupportedFrameworks.Select(f => f.FrameworkName));
                document.Add(new Field("JoinedSupportedFrameworks", joinedFrameworks, Field.Store.YES,
                                       Field.Index.NO));
            }

            // Fields meant for filtering, also storing data to avoid hitting SQL while doing searches
            document.Add(new Field("IsLatest", Package.IsLatest.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
            document.Add(new Field("IsLatestStable", Package.IsLatestStable.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
            document.Add(new Field("IsLatestSemVer2", Package.IsLatestSemVer2.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
            document.Add(new Field("IsLatestStableSemVer2", Package.IsLatestStableSemVer2.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));

            // Fields meant for filtering, sorting
            document.Add(new Field("PublishedDate", Package.Published.Ticks.ToString(CultureInfo.InvariantCulture), Field.Store.NO, Field.Index.NOT_ANALYZED));
            document.Add(new Field("EditedDate", (Package.LastEdited ?? Package.Published).Ticks.ToString(CultureInfo.InvariantCulture), Field.Store.NO, Field.Index.NOT_ANALYZED));
            document.Add(
                new Field("DownloadCount", Package.PackageRegistration.DownloadCount.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED));

            string displayName = String.IsNullOrEmpty(Package.Title) ? Package.PackageRegistration.Id : Package.Title;

            document.Add(new Field("DisplayName", displayName.ToLower(CultureInfo.CurrentCulture), Field.Store.NO, Field.Index.NOT_ANALYZED));

            return(document);
        }
        private DisplayPackageViewModel SetupCommon(
            DisplayPackageViewModel viewModel,
            Package package,
            string pushedBy,
            IReadOnlyDictionary <int, PackageDeprecation> packageKeyToDeprecation,
            IReadOnlyDictionary <int, IReadOnlyList <PackageVulnerability> > packageKeyToVulnerabilities)
        {
            viewModel.NuGetVersion = NuGetVersion.Parse(NuGetVersionFormatter.ToFullString(package.Version));
            viewModel.Copyright    = package.Copyright;

            viewModel.DownloadCount = package.DownloadCount;
            viewModel.LastEdited    = package.LastEdited;

            viewModel.TotalDaysSinceCreated = 0;
            viewModel.DownloadsPerDay       = 0;

            viewModel.PushedBy = pushedBy;

            viewModel.InitializeRepositoryMetadata(package.RepositoryUrl, package.RepositoryType);

            if (PackageHelper.TryPrepareUrlForRendering(package.ProjectUrl, out string projectUrl))
            {
                viewModel.ProjectUrl = projectUrl;
            }

            var fugetUrl = $"https://www.fuget.org/packages/{package.Id}/{package.NormalizedVersion}";

            if (PackageHelper.TryPrepareUrlForRendering(fugetUrl, out string fugetReadyUrl))
            {
                viewModel.FuGetUrl = fugetReadyUrl;
            }

            viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
            viewModel.LicenseExpression   = package.LicenseExpression;

            if (PackageHelper.TryPrepareUrlForRendering(package.LicenseUrl, out string licenseUrl))
            {
                viewModel.LicenseUrl = licenseUrl;

                var licenseNames = package.LicenseNames;
                if (!string.IsNullOrEmpty(licenseNames))
                {
                    viewModel.LicenseNames = licenseNames.Split(',').Select(l => l.Trim()).ToList();
                }
            }

            PackageDeprecation deprecation = null;

            if (packageKeyToDeprecation != null && packageKeyToDeprecation.TryGetValue(package.Key, out deprecation))
            {
                viewModel.DeprecationStatus = deprecation.Status;
            }
            else
            {
                viewModel.DeprecationStatus = PackageDeprecationStatus.NotDeprecated;
            }

            PackageVulnerabilitySeverity?maxVulnerabilitySeverity = null;

            if (packageKeyToVulnerabilities != null &&
                packageKeyToVulnerabilities.TryGetValue(package.Key, out var vulnerabilities) &&
                vulnerabilities != null && vulnerabilities.Any())
            {
                viewModel.Vulnerabilities          = vulnerabilities;
                maxVulnerabilitySeverity           = viewModel.Vulnerabilities.Max(v => v.Severity); // cache for messaging
                viewModel.MaxVulnerabilitySeverity = maxVulnerabilitySeverity.Value;
            }
            else
            {
                viewModel.Vulnerabilities          = null;
                viewModel.MaxVulnerabilitySeverity = default;
            }

            viewModel.PackageWarningIconTitle =
                GetWarningIconTitle(viewModel.Version, deprecation, maxVulnerabilitySeverity);

            return(viewModel);
        }
        public virtual async Task <JsonResult> Deprecate(
            string id,
            IEnumerable <string> versions,
            bool isVulnerable,
            bool isLegacy,
            bool isOther,
            IEnumerable <string> cveIds,
            decimal?cvssRating,
            IEnumerable <string> cweIds,
            string alternatePackageId,
            string alternatePackageVersion,
            string customMessage)
        {
            var currentUser = GetCurrentUser();

            if (!_featureFlagService.IsManageDeprecationEnabled(GetCurrentUser()))
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (versions == null || !versions.Any())
            {
                return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_NoVersions));
            }

            JsonResult vulnerabilityDetailIdsErrorResult;

            cveIds = cveIds ?? Enumerable.Empty <string>();
            if (!TryVerifyVulnerabilityDetailIds(
                    cveIds,
                    IsValidCveId,
                    Strings.DeprecatePackage_InvalidCve,
                    out vulnerabilityDetailIdsErrorResult))
            {
                return(vulnerabilityDetailIdsErrorResult);
            }

            cweIds = cweIds ?? Enumerable.Empty <string>();
            if (!TryVerifyVulnerabilityDetailIds(
                    cweIds,
                    IsValidCweId,
                    Strings.DeprecatePackage_InvalidCwe,
                    out vulnerabilityDetailIdsErrorResult))
            {
                return(vulnerabilityDetailIdsErrorResult);
            }

            if (cvssRating.HasValue && (cvssRating < 0 || cvssRating > 10))
            {
                return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_InvalidCvss));
            }

            var packages     = _packageService.FindPackagesById(id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships);
            var registration = packages.FirstOrDefault()?.PackageRegistration;

            if (registration == null)
            {
                // This should only happen if someone hacks the form or if the package is deleted while the user is filling out the form.
                return(DeprecateErrorResponse(
                           HttpStatusCode.NotFound,
                           string.Format(Strings.DeprecatePackage_MissingRegistration, id)));
            }

            if (ActionsRequiringPermissions.DeprecatePackage.CheckPermissionsOnBehalfOfAnyAccount(currentUser, registration) != PermissionsCheckResult.Allowed)
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (registration.IsLocked)
            {
                return(DeprecateErrorResponse(
                           HttpStatusCode.Forbidden,
                           string.Format(Strings.DeprecatePackage_Locked, id)));
            }

            PackageRegistration alternatePackageRegistration = null;
            Package             alternatePackage             = null;

            if (!string.IsNullOrWhiteSpace(alternatePackageId))
            {
                if (!string.IsNullOrWhiteSpace(alternatePackageVersion))
                {
                    alternatePackage = _packageService.FindPackageByIdAndVersionStrict(alternatePackageId, alternatePackageVersion);
                    if (alternatePackage == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackage, alternatePackageId, alternatePackageVersion)));
                    }
                }
                else
                {
                    alternatePackageRegistration = _packageService.FindPackageRegistrationById(alternatePackageId);
                    if (alternatePackageRegistration == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackageRegistration, alternatePackageId)));
                    }
                }
            }

            var packagesToUpdate = new List <Package>();

            foreach (var version in versions)
            {
                var normalizedVersion = NuGetVersionFormatter.Normalize(version);
                var package           = packages.SingleOrDefault(v => v.NormalizedVersion == normalizedVersion);
                if (package == null)
                {
                    // This should only happen if someone hacks the form or if a version of the package is deleted while the user is filling out the form.
                    return(DeprecateErrorResponse(
                               HttpStatusCode.NotFound,
                               string.Format(Strings.DeprecatePackage_MissingVersion, id)));
                }
                else
                {
                    packagesToUpdate.Add(package);
                }
            }

            var cves = await _deprecationService.GetOrCreateCvesByIdAsync(cveIds, commitChanges : false);

            IReadOnlyCollection <Cwe> cwes;

            try
            {
                cwes = _deprecationService.GetCwesById(cweIds);
            }
            catch (ArgumentException)
            {
                return(DeprecateErrorResponse(HttpStatusCode.NotFound, Strings.DeprecatePackage_CweMissing));
            }

            var status = PackageDeprecationStatus.NotDeprecated;

            if (isVulnerable)
            {
                status |= PackageDeprecationStatus.Vulnerable;
            }

            if (isLegacy)
            {
                status |= PackageDeprecationStatus.Legacy;
            }

            if (isOther)
            {
                status |= PackageDeprecationStatus.Other;
            }

            await _deprecationService.UpdateDeprecation(
                packagesToUpdate,
                status,
                cves,
                cvssRating,
                cwes,
                alternatePackageRegistration,
                alternatePackage,
                customMessage);

            return(Json(HttpStatusCode.OK));
        }
Example #22
0
        public virtual async Task <JsonResult> Deprecate(
            DeprecatePackageRequest request)
        {
            var status = PackageDeprecationStatus.NotDeprecated;

            if (request.IsLegacy)
            {
                status |= PackageDeprecationStatus.Legacy;
            }

            if (request.HasCriticalBugs)
            {
                status |= PackageDeprecationStatus.CriticalBugs;
            }

            var customMessage = request.CustomMessage;

            if (request.IsOther)
            {
                if (string.IsNullOrWhiteSpace(customMessage))
                {
                    return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_CustomMessageRequired));
                }

                status |= PackageDeprecationStatus.Other;
            }

            if (customMessage != null)
            {
                if (customMessage.Length > MaxCustomMessageLength)
                {
                    return(DeprecateErrorResponse(
                               HttpStatusCode.BadRequest,
                               string.Format(Strings.DeprecatePackage_CustomMessageTooLong, MaxCustomMessageLength)));
                }
            }

            if (request.Versions == null || !request.Versions.Any())
            {
                return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_NoVersions));
            }

            var packages     = _packageService.FindPackagesById(request.Id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships);
            var registration = packages.FirstOrDefault()?.PackageRegistration;

            if (registration == null)
            {
                // This should only happen if someone hacks the form or if the package is deleted while the user is filling out the form.
                return(DeprecateErrorResponse(
                           HttpStatusCode.NotFound,
                           string.Format(Strings.DeprecatePackage_MissingRegistration, request.Id)));
            }

            var currentUser = GetCurrentUser();

            if (!_featureFlagService.IsManageDeprecationEnabled(GetCurrentUser(), registration))
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (ActionsRequiringPermissions.DeprecatePackage.CheckPermissionsOnBehalfOfAnyAccount(currentUser, registration) != PermissionsCheckResult.Allowed)
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (registration.IsLocked)
            {
                return(DeprecateErrorResponse(
                           HttpStatusCode.Forbidden,
                           string.Format(Strings.DeprecatePackage_Locked, request.Id)));
            }

            PackageRegistration alternatePackageRegistration = null;
            Package             alternatePackage             = null;

            if (!string.IsNullOrWhiteSpace(request.AlternatePackageId))
            {
                if (!string.IsNullOrWhiteSpace(request.AlternatePackageVersion))
                {
                    alternatePackage = _packageService.FindPackageByIdAndVersionStrict(request.AlternatePackageId, request.AlternatePackageVersion);
                    if (alternatePackage == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackage, request.AlternatePackageId, request.AlternatePackageVersion)));
                    }
                }
                else
                {
                    alternatePackageRegistration = _packageService.FindPackageRegistrationById(request.AlternatePackageId);
                    if (alternatePackageRegistration == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackageRegistration, request.AlternatePackageId)));
                    }
                }
            }

            var packagesToUpdate = new List <Package>();

            foreach (var version in request.Versions)
            {
                var normalizedVersion = NuGetVersionFormatter.Normalize(version);
                var package           = packages.SingleOrDefault(v => v.NormalizedVersion == normalizedVersion);
                if (package == null)
                {
                    // This should only happen if someone hacks the form or if a version of the package is deleted while the user is filling out the form.
                    return(DeprecateErrorResponse(
                               HttpStatusCode.NotFound,
                               string.Format(Strings.DeprecatePackage_MissingVersion, request.Id)));
                }
                else
                {
                    packagesToUpdate.Add(package);
                }
            }

            if (alternatePackage != null && packagesToUpdate.Any(p => p == alternatePackage))
            {
                return(DeprecateErrorResponse(
                           HttpStatusCode.BadRequest,
                           Strings.DeprecatePackage_AlternateOfSelf));
            }

            await _deprecationService.UpdateDeprecation(
                packagesToUpdate,
                status,
                alternatePackageRegistration,
                alternatePackage,
                customMessage,
                currentUser);

            return(Json(HttpStatusCode.OK));
        }
Example #23
0
        public virtual async Task <JsonResult> Deprecate(
            string id,
            IEnumerable <string> versions,
            bool isLegacy,
            bool hasCriticalBugs,
            bool isOther,
            string alternatePackageId,
            string alternatePackageVersion,
            string customMessage)
        {
            var status = PackageDeprecationStatus.NotDeprecated;

            if (isLegacy)
            {
                status |= PackageDeprecationStatus.Legacy;
            }

            if (hasCriticalBugs)
            {
                status |= PackageDeprecationStatus.CriticalBugs;
            }

            if (isOther)
            {
                if (string.IsNullOrWhiteSpace(customMessage))
                {
                    return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_CustomMessageRequired));
                }

                status |= PackageDeprecationStatus.Other;
            }

            var currentUser = GetCurrentUser();

            if (!_featureFlagService.IsManageDeprecationEnabled(GetCurrentUser()))
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (versions == null || !versions.Any())
            {
                return(DeprecateErrorResponse(HttpStatusCode.BadRequest, Strings.DeprecatePackage_NoVersions));
            }

            var packages     = _packageService.FindPackagesById(id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships);
            var registration = packages.FirstOrDefault()?.PackageRegistration;

            if (registration == null)
            {
                // This should only happen if someone hacks the form or if the package is deleted while the user is filling out the form.
                return(DeprecateErrorResponse(
                           HttpStatusCode.NotFound,
                           string.Format(Strings.DeprecatePackage_MissingRegistration, id)));
            }

            if (ActionsRequiringPermissions.DeprecatePackage.CheckPermissionsOnBehalfOfAnyAccount(currentUser, registration) != PermissionsCheckResult.Allowed)
            {
                return(DeprecateErrorResponse(HttpStatusCode.Forbidden, Strings.DeprecatePackage_Forbidden));
            }

            if (registration.IsLocked)
            {
                return(DeprecateErrorResponse(
                           HttpStatusCode.Forbidden,
                           string.Format(Strings.DeprecatePackage_Locked, id)));
            }

            PackageRegistration alternatePackageRegistration = null;
            Package             alternatePackage             = null;

            if (!string.IsNullOrWhiteSpace(alternatePackageId))
            {
                if (!string.IsNullOrWhiteSpace(alternatePackageVersion))
                {
                    alternatePackage = _packageService.FindPackageByIdAndVersionStrict(alternatePackageId, alternatePackageVersion);
                    if (alternatePackage == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackage, alternatePackageId, alternatePackageVersion)));
                    }
                }
                else
                {
                    alternatePackageRegistration = _packageService.FindPackageRegistrationById(alternatePackageId);
                    if (alternatePackageRegistration == null)
                    {
                        return(DeprecateErrorResponse(
                                   HttpStatusCode.NotFound,
                                   string.Format(Strings.DeprecatePackage_NoAlternatePackageRegistration, alternatePackageId)));
                    }
                }
            }

            var packagesToUpdate = new List <Package>();

            foreach (var version in versions)
            {
                var normalizedVersion = NuGetVersionFormatter.Normalize(version);
                var package           = packages.SingleOrDefault(v => v.NormalizedVersion == normalizedVersion);
                if (package == null)
                {
                    // This should only happen if someone hacks the form or if a version of the package is deleted while the user is filling out the form.
                    return(DeprecateErrorResponse(
                               HttpStatusCode.NotFound,
                               string.Format(Strings.DeprecatePackage_MissingVersion, id)));
                }
                else
                {
                    packagesToUpdate.Add(package);
                }
            }

            await _deprecationService.UpdateDeprecation(
                packagesToUpdate,
                status,
                alternatePackageRegistration,
                alternatePackage,
                customMessage,
                currentUser);

            foreach (var packageToUpdate in packagesToUpdate)
            {
                await _auditingService.SaveAuditRecordAsync(
                    new PackageAuditRecord(
                        packageToUpdate,
                        status == PackageDeprecationStatus.NotDeprecated ? AuditedPackageAction.Undeprecate : AuditedPackageAction.Deprecate,
                        status == PackageDeprecationStatus.NotDeprecated ? PackageUndeprecatedVia.Web : PackageDeprecatedVia.Web));
            }

            return(Json(HttpStatusCode.OK));
        }
Example #24
0
        public ManagePackageViewModel(Package package, User currentUser, IReadOnlyList <ReportPackageReason> reasons, UrlHelper url, string readMe, bool isManageDeprecationEnabled)
            : base(package, currentUser)
        {
            IsCurrentUserAnAdmin = currentUser != null && currentUser.IsAdministrator;

            DeletePackagesRequest = new DeletePackagesRequest
            {
                Packages = new List <string>
                {
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0}|{1}",
                        package.PackageRegistration.Id,
                        package.Version)
                },
                ReasonChoices = reasons
            };

            IsLocked = package.PackageRegistration.IsLocked;

            IsManageDeprecationEnabled = isManageDeprecationEnabled;

            var versionSelectPackages = package.PackageRegistration.Packages
                                        .Where(p => p.PackageStatusKey == PackageStatus.Available || p.PackageStatusKey == PackageStatus.Validating)
                                        .OrderByDescending(p => new NuGetVersion(p.Version))
                                        .ToList();

            VersionSelectList                 = new List <SelectListItem>();
            VersionListedStateDictionary      = new Dictionary <string, VersionListedState>();
            VersionReadMeStateDictionary      = new Dictionary <string, VersionReadMeState>();
            VersionDeprecationStateDictionary = new Dictionary <string, VersionDeprecationState>();

            var submitUrlTemplate    = url.PackageVersionActionTemplate("Edit");
            var getReadMeUrlTemplate = url.PackageVersionActionTemplate("GetReadMeMd");

            foreach (var versionSelectPackage in versionSelectPackages)
            {
                var text  = PackageHelper.GetSelectListText(versionSelectPackage);
                var value = NuGetVersionFormatter.Normalize(versionSelectPackage.Version);
                VersionSelectList.Add(new SelectListItem
                {
                    Text     = text,
                    Value    = value,
                    Selected = package == versionSelectPackage
                });

                VersionListedStateDictionary.Add(
                    value,
                    new VersionListedState(versionSelectPackage));

                var model = new TrivialPackageVersionModel(versionSelectPackage);
                VersionReadMeStateDictionary.Add(
                    value,
                    new VersionReadMeState(
                        submitUrlTemplate.Resolve(model),
                        getReadMeUrlTemplate.Resolve(model),
                        null));

                VersionDeprecationStateDictionary.Add(
                    value,
                    new VersionDeprecationState(versionSelectPackage, text));
            }

            // Update edit model with the readme.md data.
            ReadMe = new EditPackageVersionReadMeRequest();
            if (package.HasReadMe)
            {
                ReadMe.ReadMe.SourceType = ReadMeService.TypeWritten;
                ReadMe.ReadMe.SourceText = readMe;
            }
        }
        private ManagePackageViewModel SetupInternal(
            ManagePackageViewModel viewModel,
            Package package,
            User currentUser,
            IReadOnlyList <ReportPackageReason> reasons,
            UrlHelper url,
            string readMe,
            bool isManageDeprecationEnabled)
        {
            viewModel.IsCurrentUserAnAdmin = currentUser != null && currentUser.IsAdministrator;

            viewModel.DeletePackagesRequest = new DeletePackagesRequest
            {
                Packages = new List <string>
                {
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0}|{1}",
                        package.PackageRegistration.Id,
                        package.Version)
                },
                ReasonChoices = reasons
            };

            viewModel.IsLocked = package.PackageRegistration.IsLocked;

            viewModel.IsManageDeprecationEnabled = isManageDeprecationEnabled;

            var versionSelectPackages = package.PackageRegistration.Packages
                                        .Where(p => p.PackageStatusKey == PackageStatus.Available || p.PackageStatusKey == PackageStatus.Validating)
                                        .OrderByDescending(p => new NuGetVersion(p.Version))
                                        .ToList();

            var versionSelectList = new List <SelectListItem>();

            viewModel.VersionSelectList = versionSelectList;
            var versionListedStateDictionary = new Dictionary <string, ManagePackageViewModel.VersionListedState>();

            viewModel.VersionListedStateDictionary = versionListedStateDictionary;
            var versionReadMeStateDictionary = new Dictionary <string, ManagePackageViewModel.VersionReadMeState>();

            viewModel.VersionReadMeStateDictionary = versionReadMeStateDictionary;
            var versionDeprecationStateDictionary = new Dictionary <string, ManagePackageViewModel.VersionDeprecationState>();

            viewModel.VersionDeprecationStateDictionary = versionDeprecationStateDictionary;

            foreach (var versionSelectPackage in versionSelectPackages)
            {
                var text  = PackageHelper.GetSelectListText(versionSelectPackage);
                var value = NuGetVersionFormatter.Normalize(versionSelectPackage.Version);
                versionSelectList.Add(new SelectListItem
                {
                    Text     = text,
                    Value    = value,
                    Selected = package == versionSelectPackage
                });

                versionListedStateDictionary.Add(
                    value,
                    new ManagePackageViewModel.VersionListedState(versionSelectPackage.Listed, versionSelectPackage.DownloadCount));

                var model = new TrivialPackageVersionModel(versionSelectPackage);
                versionReadMeStateDictionary.Add(
                    value,
                    GetVersionReadMeState(model, url));

                versionDeprecationStateDictionary.Add(
                    value,
                    GetVersionDeprecationState(versionSelectPackage.Deprecations.SingleOrDefault(), text));
            }

            // Update edit model with the readme.md data.
            viewModel.ReadMe = new EditPackageVersionReadMeRequest();
            if (package.HasReadMe && package.EmbeddedReadmeType == EmbeddedReadmeFileType.Absent)
            {
                viewModel.ReadMe.ReadMe.SourceType = ReadMeService.TypeWritten;
                viewModel.ReadMe.ReadMe.SourceText = readMe;
            }

            return(viewModel);
        }
        public async Task <string> GetLicenseFileFlatContainerUrlAsync(string packageId, string packageVersion)
        {
            if (packageId == null)
            {
                throw new ArgumentNullException(nameof(packageId));
            }
            if (packageVersion == null)
            {
                throw new ArgumentNullException(nameof(packageVersion));
            }

            var packageBaseAddress = await _serviceDiscoveryClient.GetEndpointsForResourceType(GalleryConstants.PackageBaseAddress);

            var packageBaseUri         = new Uri(packageBaseAddress.First().AbsoluteUri.TrimEnd('/') + "/"); // make sure that there is one "/" at the end of the Uri.
            var licenseFileRelativeUri = string.Join("/", new string[] { packageId.ToLowerInvariant(), NuGetVersionFormatter.Normalize(packageVersion).ToLowerInvariant(), CoreConstants.LicenseFileName });

            return(new Uri(packageBaseUri, licenseFileRelativeUri).AbsoluteUri);
        }