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)); }
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)); }
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))); }
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)); }
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; } }
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()); } }
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)); }
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); }
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)); }
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; } }
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)); }
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)); }
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)); }
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)); }
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); }