From 01405abdf2a57f1a2bc5cf5c9a33610b50f81a6f Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sun, 28 Apr 2024 15:44:12 +0100 Subject: [PATCH] Package deletion and types --- .../Packages/PackagesController.Search.cs | 2 +- .../Packages/PackagesController.WebViews.cs | 24 ++++----- src/isnd/Data/Catalog/CatalogPage.cs | 12 ++--- src/isnd/Data/Catalog/PackageDetails.cs | 4 +- src/isnd/Data/Catalog/PackageRegistration.cs | 8 +-- src/isnd/Data/Catalog/RegistratioinLeave.cs | 4 +- src/isnd/Data/Packages/Package.cs | 2 +- src/isnd/Data/Packages/PackageVersion.cs | 4 +- src/isnd/Interfaces/IPackageManager.cs | 4 +- src/isnd/Services/PackageManager.cs | 51 ++++++++----------- src/isnd/ViewModels/PackageSearchResult.cs | 7 ++- src/isnd/ViewModels/SearchVersionInfo.cs | 4 +- src/isnd/Views/Packages/Delete.cshtml | 9 ++-- test/isnd.tests/UnitTestWebHost.cs | 2 +- 14 files changed, 67 insertions(+), 70 deletions(-) diff --git a/src/isnd/Controllers/Packages/PackagesController.Search.cs b/src/isnd/Controllers/Packages/PackagesController.Search.cs index cc069db..9406689 100644 --- a/src/isnd/Controllers/Packages/PackagesController.Search.cs +++ b/src/isnd/Controllers/Packages/PackagesController.Search.cs @@ -20,7 +20,7 @@ namespace isnd.Controllers int take=25, bool prerelease=false, string semVerLevel = "2.0.0", - string packageType = null) + string packageType = "Dependency") { PackageRegistrationQuery query = new PackageRegistrationQuery { diff --git a/src/isnd/Controllers/Packages/PackagesController.WebViews.cs b/src/isnd/Controllers/Packages/PackagesController.WebViews.cs index bd14136..d392066 100644 --- a/src/isnd/Controllers/Packages/PackagesController.WebViews.cs +++ b/src/isnd/Controllers/Packages/PackagesController.WebViews.cs @@ -77,8 +77,8 @@ namespace isnd.Controllers } var packageVersion = await dbContext.PackageVersions.Include(p => p.Package) - .FirstOrDefaultAsync(m => m.PackageId == pkgid - && m.FullString == version && m.Type == pkgtype); + .FirstOrDefaultAsync(m => m.PackageId == pkgid && m.FullString == version + && (pkgtype!=null && m.Type == pkgtype || m.Type != "Delete" )); if (packageVersion == null) return NotFound(); if (!User.IsOwner(packageVersion)) return Unauthorized(); var pkg = await packageManager.GetPackageAsync(pkgid, version, pkgtype); @@ -87,18 +87,18 @@ namespace isnd.Controllers // POST: PackageVersion/Delete/5 [HttpPost] - [ValidateAntiForgeryToken] - public async Task DeleteConfirmed(string PackageId, string FullString, - string Type) + [ValidateAntiForgeryToken][Authorize] + public async Task DeleteConfirmed(string pkgid, string version, + string type) { - PackageVersion packageVersion = await dbContext.PackageVersions + var packageVersion = await dbContext.PackageVersions .Include(pv => pv.Package) - .FirstOrDefaultAsync(m => m.PackageId == PackageId - && m.FullString == FullString && m.Type == Type); - if (packageVersion == null) return NotFound(); - if (!User.IsOwner(packageVersion)) return Unauthorized(); - - await packageManager.DeletePackageAsync(PackageId, FullString, Type); + .Where(m => m.PackageId == pkgid + && m.FullString == version && (type==null || m.Type == type)) + .ToArrayAsync(); + if (packageVersion.Length==0) return NotFound(); + if (!User.IsOwner(packageVersion.First())) return Unauthorized(); + await packageManager.DeletePackageAsync(pkgid, version, type); return RedirectToAction(nameof(Index)); } } diff --git a/src/isnd/Data/Catalog/CatalogPage.cs b/src/isnd/Data/Catalog/CatalogPage.cs index dfd5ece..97d2029 100644 --- a/src/isnd/Data/Catalog/CatalogPage.cs +++ b/src/isnd/Data/Catalog/CatalogPage.cs @@ -7,23 +7,23 @@ using NuGet.Versioning; namespace isnd.Data.Catalog { - public class CatalogPage : Permalink + public class RegistrationPage : Permalink { private readonly string pkgid; - private readonly List items; + private readonly List items; private readonly string apiBase; - public CatalogPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json") + public RegistrationPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json") { Parent = apiBase + $"/registration/{pkgid}/index.json"; - this.items = new List(); + this.items = new List(); this.pkgid = pkgid; this.apiBase = apiBase; } - public CatalogPage(string pkgid, string apiBase, IEnumerable versions) : this(pkgid, apiBase) + public RegistrationPage(string pkgid, string apiBase, IEnumerable versions) : this(pkgid, apiBase) { AddVersionRange(versions); } @@ -39,7 +39,7 @@ namespace isnd.Data.Catalog /// [JsonProperty("items")] - public RegistrationLeave[] Items { get => items.ToArray(); } + public RegistrationLeaf[] Items { get => items.ToArray(); } public void AddVersionRange(IEnumerable vitems) { diff --git a/src/isnd/Data/Catalog/PackageDetails.cs b/src/isnd/Data/Catalog/PackageDetails.cs index 58d5177..0bb57fd 100644 --- a/src/isnd/Data/Catalog/PackageDetails.cs +++ b/src/isnd/Data/Catalog/PackageDetails.cs @@ -26,12 +26,12 @@ namespace isnd.Data.Catalog /// public PackageDetails(PackageVersion pkg, string apiBase): base( apiBase + ApiConfig.Registration + "/" + pkg.PackageId + "/" + pkg.FullString + ".json") { - PackageId = pkg.Package.Id; + Title = PackageId = pkg.Package.Id; Version = pkg.FullString; Authors = $"{pkg.Package.Owner.FullName} <${pkg.Package.Owner.Email}>"; packageContent = apiBase + pkg.NugetLink; CommitId = pkg.CommitId; - CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp; + Published = CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp; IsListed = !pkg.IsDeleted && pkg.Package.Public; if (pkg.DependencyGroups!=null) { diff --git a/src/isnd/Data/Catalog/PackageRegistration.cs b/src/isnd/Data/Catalog/PackageRegistration.cs index 68b45e4..9bca29c 100644 --- a/src/isnd/Data/Catalog/PackageRegistration.cs +++ b/src/isnd/Data/Catalog/PackageRegistration.cs @@ -12,14 +12,14 @@ namespace isnd.Data.Catalog public PackageRegistration(string url) : base(url) { - Items = new List(); + Items = new List(); } public PackageRegistration(string apiBase, string pkgId, IEnumerable versions) : base($"{apiBase}{ApiConfig.Registration}/{pkgId}/index.json") { - Items = new List + Items = new List { - new CatalogPage(pkgId, apiBase, versions) + new RegistrationPage(pkgId, apiBase, versions) }; } @@ -27,7 +27,7 @@ namespace isnd.Data.Catalog public int Count { get => Items.Count; } [JsonProperty("items")] - public List Items { get; set; } + public List Items { get; set; } } } \ No newline at end of file diff --git a/src/isnd/Data/Catalog/RegistratioinLeave.cs b/src/isnd/Data/Catalog/RegistratioinLeave.cs index 6a3c7b3..4fc9793 100644 --- a/src/isnd/Data/Catalog/RegistratioinLeave.cs +++ b/src/isnd/Data/Catalog/RegistratioinLeave.cs @@ -9,9 +9,9 @@ namespace isnd.Data.Catalog /// Hosts a catalog entry, /// the atomic content reference /// - public class RegistrationLeave + public class RegistrationLeaf { - public RegistrationLeave(string apiBase, string pkgId, string fullVersionString, PackageDetails entry) + public RegistrationLeaf(string apiBase, string pkgId, string fullVersionString, PackageDetails entry) { this.registration = apiBase + ApiConfig.Registration + "/" + pkgId + "/" + fullVersionString + ".json"; diff --git a/src/isnd/Data/Packages/Package.cs b/src/isnd/Data/Packages/Package.cs index 2c41a3b..ece5613 100644 --- a/src/isnd/Data/Packages/Package.cs +++ b/src/isnd/Data/Packages/Package.cs @@ -50,7 +50,7 @@ namespace isnd.Data.Packages internal string GetLatestVersion() { - return Versions.Max(v => v.NugetVersion).ToFullString(); + return Versions.Max(v => v.NugetVersion)?.ToFullString(); } } } \ No newline at end of file diff --git a/src/isnd/Data/Packages/PackageVersion.cs b/src/isnd/Data/Packages/PackageVersion.cs index fb5d941..c73d7af 100644 --- a/src/isnd/Data/Packages/PackageVersion.cs +++ b/src/isnd/Data/Packages/PackageVersion.cs @@ -74,9 +74,9 @@ namespace isnd.Data public string SementicVersionString { get => $"{Major}.{Minor}.{Patch}"; } public NuGetVersion NugetVersion { get => new NuGetVersion(FullString); } - public Catalog.RegistrationLeave ToPackage(string apiBase) + public Catalog.RegistrationLeaf ToPackage(string apiBase) { - return new Catalog.RegistrationLeave(apiBase, this.PackageId , FullString, new Catalog.PackageDetails(this, apiBase)); + return new Catalog.RegistrationLeaf(apiBase, this.PackageId , FullString, new Catalog.PackageDetails(this, apiBase)); } public bool IsDeleted => LatestCommit?.Action == PackageAction.DeletePackage; diff --git a/src/isnd/Interfaces/IPackageManager.cs b/src/isnd/Interfaces/IPackageManager.cs index e8ce502..bff3d9f 100644 --- a/src/isnd/Interfaces/IPackageManager.cs +++ b/src/isnd/Interfaces/IPackageManager.cs @@ -22,8 +22,8 @@ namespace isnd.Interfaces Task DeletePackageAsync(string pkgid, string version, string type); Task UserAskForPackageDeletionAsync(string userid, string pkgId, string lower, string type); Task GetPackageAsync(string pkgid, string version, string type); - Task GetCatalogEntryAsync(string pkgId, string version, string pkgType); - IEnumerable SearchCatalogEntriesById(string pkgId, string semver, string pkgType, bool preRelease); + Task GetCatalogEntryAsync(string pkgId, string version, string pkgType); + IEnumerable SearchCatalogEntriesById(string pkgId, string semver, string pkgType, bool preRelease); Task GetCatalogIndexAsync(); Task GetPackageRegistrationIndexAsync(PackageRegistrationQuery query); diff --git a/src/isnd/Services/PackageManager.cs b/src/isnd/Services/PackageManager.cs index c9009b3..70799f6 100644 --- a/src/isnd/Services/PackageManager.cs +++ b/src/isnd/Services/PackageManager.cs @@ -164,22 +164,20 @@ namespace isnd.Services i = isndSettings.CatalogPageLen; foreach (var commit in scope) { - var validPkgs = (await dbContext.Packages .Include(po => po.Owner) .Include(pkg => pkg.Versions) .Include(pkg => pkg.LatestCommit) .ToArrayAsync()) .GroupBy((q) => q.Id); - foreach (var pkgIdGroup in validPkgs) { - CatalogPage page = index.Items.FirstOrDefault + RegistrationPage page = index.Items.FirstOrDefault (p => p.GetPackageId() == pkgIdGroup.Key); if (page == null) { - page = new CatalogPage(pkgIdGroup.Key, apiBase); + page = new RegistrationPage(pkgIdGroup.Key, apiBase); index.Items.Add(page); } @@ -225,12 +223,12 @@ namespace isnd.Services return await dbContext.PackageVersions.SingleOrDefaultAsync( v => v.PackageId == pkgId && v.FullString == version && - v.Type == type + (type==null || v.Type == type) ); } - public async Task GetCatalogEntryAsync - (string pkgId, string semver, string pkgType = null) + public async Task GetCatalogEntryAsync + (string pkgId, string semver, string pkgType = "Dependency") { var version = await dbContext.PackageVersions .Include(v => v.Package) @@ -241,13 +239,12 @@ namespace isnd.Services .Where(v => v.PackageId == pkgId && v.FullString == semver && v.LatestCommit != null + && (pkgType == null || pkgType == v.Type) ).SingleOrDefaultAsync(); - foreach (var g in version.DependencyGroups) { g.Dependencies = dbContext.Dependencies.Where(d => d.DependencyGroupId == g.Id).ToList(); } - return version.ToPackage(apiBase); } @@ -257,14 +254,14 @@ namespace isnd.Services PackageVersion packageVersion = await dbContext.PackageVersions .Include(pv => pv.Package) .FirstOrDefaultAsync(m => m.PackageId == id - && m.FullString == lower && m.Type == type); + && m.FullString == lower && (type==null || m.Type == type)); if (packageVersion == null) return null; if (packageVersion.Package.OwnerId != uid) return null; return new PackageDeletionReport { Deleted = true, DeletedVersion = packageVersion }; } - public IEnumerable SearchCatalogEntriesById + public IEnumerable SearchCatalogEntriesById (string pkgId, string semver, string pkgType, bool preRelease) { // PackageDependency @@ -294,7 +291,6 @@ namespace isnd.Services public async Task GetPackageRegistrationIndexAsync (PackageRegistrationQuery query) { - // RegistrationPageIndexAndQuery if (string.IsNullOrWhiteSpace(query.Query)) return null; query.Query = query.Query.ToLower(); var scope = await dbContext.PackageVersions @@ -305,7 +301,6 @@ namespace isnd.Services if (scope == null) return null; if (scope.Length == 0) return null; string bid = $"{apiBase}{ApiConfig.Registration}"; - foreach (var version in scope) { version.DependencyGroups = dbContext.PackageDependencyGroups.Include(d => d.Dependencies) @@ -313,9 +308,7 @@ namespace isnd.Services .ToList(); version.LatestCommit = dbContext.Commits.Single(c => c.Id == version.CommitNId); } - - return - new PackageRegistration(apiBase, query.Query, scope); + return new PackageRegistration(apiBase, query.Query, scope); } public async Task SearchPackageAsync(PackageRegistrationQuery query) @@ -325,19 +318,20 @@ namespace isnd.Services query.Query = ""; var packages = await dbContext.Packages - .Include(g => g.Versions) - .Where(d => d.Id.StartsWith(query.Query) - && (query.Prerelease || d.Versions.Any(v => !v.IsPrerelease))) + .Include(g => g.Versions).OrderBy(v=>v.CommitNId) + .Where(d => d.Id.StartsWith(query.Query) + && (query.Prerelease || d.Versions.Any(v => !v.IsPrerelease))) + .Where(p=>p.Versions.Count>=0) .Skip(query.Skip).Take(query.Take).ToArrayAsync(); foreach (var package in packages) foreach (var version in package.Versions) { version.DependencyGroups = dbContext.PackageDependencyGroups.Include(d => d.Dependencies) .Where(d => d.PackageVersionFullString == version.FullString && d.PackageId == version.PackageId) + .ToList(); } return new PackageSearchResult(packages, apiBase, packages.Count()); - } public async Task PutPackageAsync(Stream packageStream, string ownerId) @@ -370,17 +364,14 @@ namespace isnd.Services var frameWorks = (dependencies ?? frameworkReferences) .Descendants().Where(x => x.Name.LocalName == "group") .Select(x => NewFrameworkDependencyGroup(x)).ToArray(); - var types = "Package"; - + // FIXME default package type or null + var types = "Dependency"; pkgId = xMeta.Descendants().FirstOrDefault(x => x.Name.LocalName == "id")?.Value; string pkgVersion = xMeta.Descendants().FirstOrDefault(x => x.Name.LocalName == "version")?.Value; if (!NuGetVersion.TryParse(pkgVersion, out nugetVersion)) throw new InvalidPackageException("metadata/version"); - - - string packageIdPath = Path.Combine(isndSettings.PackagesRootDir, pkgId); pkgPath = Path.Combine(packageIdPath, nugetVersion.ToFullString()); @@ -397,21 +388,20 @@ namespace isnd.Services if (pkg != null) { // Update - pkg.Description = packageDescription; - pkg.LatestCommit = commit; } else { // First version - pkg = new Data.Packages.Package + pkg = new Package { Id = pkgId, - Description = packageDescription, OwnerId = ownerId, - LatestCommit = commit }; dbContext.Packages.Add(pkg); } + pkg.Public = true; + pkg.LatestCommit = commit; + pkg.Description = packageDescription; // here, the package is or new, or owned by the key owner if (!packageIdPathInfo.Exists) packageIdPathInfo.Create(); @@ -437,7 +427,6 @@ namespace isnd.Services } string versionFullString = nugetVersion.ToFullString(); - // FIXME default package type or null dbContext.PackageVersions.Add (version = new PackageVersion { diff --git a/src/isnd/ViewModels/PackageSearchResult.cs b/src/isnd/ViewModels/PackageSearchResult.cs index f3cd486..7bed892 100644 --- a/src/isnd/ViewModels/PackageSearchResult.cs +++ b/src/isnd/ViewModels/PackageSearchResult.cs @@ -6,6 +6,7 @@ using System.Text.Json.Serialization; using isnd.Data; using isnd.Data.Packages; using isnd.Entities; +using NuGet.Packaging.Core; namespace isnd.ViewModels { @@ -37,7 +38,11 @@ namespace isnd.ViewModels { version = package.GetLatestVersion(), description = package.Description, - versions = package.Versions.Select(v => new SearchVersionInfo(regId, v)).ToArray() + versions = package.Versions.Select(v => new SearchVersionInfo(apiBase, v)).ToArray(), + packageTypes = package.Versions.Select(v=>new PackageType(v.Type, new System.Version(v.Major,v.Minor,v.Patch, v.Revision))) + .ToArray(), + + }; } diff --git a/src/isnd/ViewModels/SearchVersionInfo.cs b/src/isnd/ViewModels/SearchVersionInfo.cs index 57aa01d..204be56 100644 --- a/src/isnd/ViewModels/SearchVersionInfo.cs +++ b/src/isnd/ViewModels/SearchVersionInfo.cs @@ -1,11 +1,13 @@ using isnd.Data.Catalog; +using isnd.Entities; using Newtonsoft.Json; namespace isnd.ViewModels { public class SearchVersionInfo: Permalink { - public SearchVersionInfo(string id, Data.PackageVersion v) : base(id, "VersionInfo") + public SearchVersionInfo(string apiBase, Data.PackageVersion v) : base( $"{apiBase}{ApiConfig.Registration}/{v.PackageId}/{v.FullString}.json", "VersionInfo") + { Version = v.FullString; } diff --git a/src/isnd/Views/Packages/Delete.cshtml b/src/isnd/Views/Packages/Delete.cshtml index b5bebf5..bb006ef 100644 --- a/src/isnd/Views/Packages/Delete.cshtml +++ b/src/isnd/Views/Packages/Delete.cshtml @@ -42,12 +42,13 @@ @Html.DisplayFor(model => model.Package.Id) - + @if (Model!=null) {
- - - + + + | Back to List
+ } diff --git a/test/isnd.tests/UnitTestWebHost.cs b/test/isnd.tests/UnitTestWebHost.cs index 72908dd..13e0d9e 100644 --- a/test/isnd.tests/UnitTestWebHost.cs +++ b/test/isnd.tests/UnitTestWebHost.cs @@ -170,7 +170,7 @@ namespace isnd.host.tests { Console.WriteLine($"Found package {result.Identity.Id} {result.Identity.Version}"); } - Assert.True( results.Any(result => result.DependencySets.Any())); + Assert.NotEmpty( results.Where(result => result.DependencySets.Any())); } [Fact]