Package deletion and types

main
Paul Schneider 5 months ago
parent 62a8bf27cb
commit 01405abdf2
14 changed files with 67 additions and 70 deletions

@ -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
{

@ -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<IActionResult> DeleteConfirmed(string PackageId, string FullString,
string Type)
[ValidateAntiForgeryToken][Authorize]
public async Task<IActionResult> 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));
}
}

@ -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<RegistrationLeave> items;
private readonly List<RegistrationLeaf> 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<RegistrationLeave>();
this.items = new List<RegistrationLeaf>();
this.pkgid = pkgid;
this.apiBase = apiBase;
}
public CatalogPage(string pkgid, string apiBase, IEnumerable<PackageVersion> versions) : this(pkgid, apiBase)
public RegistrationPage(string pkgid, string apiBase, IEnumerable<PackageVersion> versions) : this(pkgid, apiBase)
{
AddVersionRange(versions);
}
@ -39,7 +39,7 @@ namespace isnd.Data.Catalog
/// <value></value>
[JsonProperty("items")]
public RegistrationLeave[] Items { get => items.ToArray(); }
public RegistrationLeaf[] Items { get => items.ToArray(); }
public void AddVersionRange(IEnumerable<PackageVersion> vitems)
{

@ -26,12 +26,12 @@ namespace isnd.Data.Catalog
/// <returns></returns>
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)
{

@ -12,14 +12,14 @@ namespace isnd.Data.Catalog
public PackageRegistration(string url) : base(url)
{
Items = new List<CatalogPage>();
Items = new List<RegistrationPage>();
}
public PackageRegistration(string apiBase, string pkgId, IEnumerable<PackageVersion> versions) : base($"{apiBase}{ApiConfig.Registration}/{pkgId}/index.json")
{
Items = new List<CatalogPage>
Items = new List<RegistrationPage>
{
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<CatalogPage> Items { get; set; }
public List<RegistrationPage> Items { get; set; }
}
}

@ -9,9 +9,9 @@ namespace isnd.Data.Catalog
/// Hosts a catalog entry,
/// the atomic content reference
/// </summary>
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";

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

@ -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;

@ -22,8 +22,8 @@ namespace isnd.Interfaces
Task<PackageDeletionReport> DeletePackageAsync(string pkgid, string version, string type);
Task<PackageDeletionReport> UserAskForPackageDeletionAsync(string userid, string pkgId, string lower, string type);
Task<PackageVersion> GetPackageAsync(string pkgid, string version, string type);
Task<Data.Catalog.RegistrationLeave> GetCatalogEntryAsync(string pkgId, string version, string pkgType);
IEnumerable<Data.Catalog.RegistrationLeave> SearchCatalogEntriesById(string pkgId, string semver, string pkgType, bool preRelease);
Task<Data.Catalog.RegistrationLeaf> GetCatalogEntryAsync(string pkgId, string version, string pkgType);
IEnumerable<Data.Catalog.RegistrationLeaf> SearchCatalogEntriesById(string pkgId, string semver, string pkgType, bool preRelease);
Task<PackageRegistration> GetCatalogIndexAsync();
Task<PackageRegistration> GetPackageRegistrationIndexAsync(PackageRegistrationQuery query);

@ -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<Data.Catalog.RegistrationLeave> GetCatalogEntryAsync
(string pkgId, string semver, string pkgType = null)
public async Task<Data.Catalog.RegistrationLeaf> 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<Data.Catalog.RegistrationLeave> SearchCatalogEntriesById
public IEnumerable<Data.Catalog.RegistrationLeaf> SearchCatalogEntriesById
(string pkgId, string semver, string pkgType, bool preRelease)
{
// PackageDependency
@ -294,7 +291,6 @@ namespace isnd.Services
public async Task<PackageRegistration> 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<PackageSearchResult> 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<PackageVersion> 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
{

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

@ -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;
}

@ -42,12 +42,13 @@
@Html.DisplayFor(model => model.Package.Id)
</dd>
</dl>
@if (Model!=null) {
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="PackageId" />
<input type="hidden" asp-for="FullString" />
<input type="hidden" asp-for="Type" />
<input type="hidden" name="pkgid" value="@Model.PackageId" />
<input type="hidden" name="version" value="@Model.FullString" />
<input type="hidden" name="type" value="@Model.Type" />
<input type="submit" value="Delete" class="btn btn-default" /> |
<a asp-action="Index">Back to List</a>
</form>
}
</div>

@ -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]

Loading…