diff --git a/src/nuget-host/Controllers/PackageVersionController.cs b/src/nuget-host/Controllers/PackageVersionController.cs new file mode 100644 index 0000000..153e494 --- /dev/null +++ b/src/nuget-host/Controllers/PackageVersionController.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.EntityFrameworkCore; +using nuget_host.Data; +using nuget_host.ViewModels; + +namespace nuget_host +{ + [AllowAnonymous] + public class PackageVersionController : Controller + { + private readonly ApplicationDbContext _context; + + public PackageVersionController(ApplicationDbContext context) + { + _context = context; + } + + // GET: PackageVersion + public async Task Index(PackageVersionIndexViewModel model) + { + var applicationDbContext = _context.PackageVersions.Include(p => p.Package).Where(p => p.PackageId == model.PackageId); + + model.Versions = await applicationDbContext.ToListAsync(); + + return View(model); + } + + // GET: PackageVersion/Details/5 + public async Task Details(string pkgid, string version) + { + if (pkgid == null || version == null) + { + return NotFound(); + } + + var packageVersion = await _context.PackageVersions + .Include(p => p.Package) + .FirstOrDefaultAsync(m => m.PackageId == pkgid && m.FullString == version); + if (packageVersion == null) + { + return NotFound(); + } + + return View(packageVersion); + } + + [Authorize] + public async Task Delete(string pkgid, string version) + { + if (pkgid == null || version == null) + { + return NotFound(); + } + + var packageVersion = await _context.PackageVersions + .Include(p => p.Package) + .FirstOrDefaultAsync(m => m.PackageId == pkgid && m.FullString == version); + if (packageVersion == null) + { + return NotFound(); + } + + if (!IsOwner(packageVersion)) return Unauthorized(); + + return View(packageVersion); + } + + bool IsOwner(PackageVersion v) + { + var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); + return v.Package.OwnerId == userId; + } + + // POST: PackageVersion/Delete/5 + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public async Task DeleteConfirmed(string PackageId, string FullString) + { + var packageVersion = await _context.PackageVersions.Include(p => p.Package) + .FirstOrDefaultAsync(m => m.PackageId == PackageId && m.FullString == FullString); + if (packageVersion == null) return NotFound(); + if (!IsOwner(packageVersion)) return Unauthorized(); + + _context.PackageVersions.Remove(packageVersion); + await _context.SaveChangesAsync(); + return RedirectToAction(nameof(Index)); + } + } +} diff --git a/src/nuget-host/Controllers/PackagesController.cs b/src/nuget-host/Controllers/PackagesController.cs index d7937d8..6ba520c 100644 --- a/src/nuget-host/Controllers/PackagesController.cs +++ b/src/nuget-host/Controllers/PackagesController.cs @@ -84,7 +84,7 @@ namespace nuget_host.Controllers var version = reader.GetVersion(); string pkgidpath = Path.Combine(nugetSettings.PackagesRootDir, pkgid); - string pkgpath = Path.Combine(pkgidpath, version.Version.ToString()); + string pkgpath = Path.Combine(pkgidpath, version.ToFullString()); string name = $"{pkgid}-{version}.nupkg"; string fullpath = Path.Combine(pkgpath, name); Package package; diff --git a/src/nuget-host/Data/ApplicationDbContext.cs b/src/nuget-host/Data/ApplicationDbContext.cs index 757479f..01671c0 100644 --- a/src/nuget-host/Data/ApplicationDbContext.cs +++ b/src/nuget-host/Data/ApplicationDbContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using nuget_host.Data; @@ -14,7 +15,15 @@ namespace nuget_host.Data : base(options) { } - + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity().HasKey(v => new + { + v.PackageId, + v.FullString + }); + } public DbSet ApiKeys { get; set; } public DbSet Packages { get; set; } public DbSet PackageVersions { get; set; } diff --git a/src/nuget-host/Data/PackageVersion.cs b/src/nuget-host/Data/PackageVersion.cs index 018d34c..8b1b6ff 100644 --- a/src/nuget-host/Data/PackageVersion.cs +++ b/src/nuget-host/Data/PackageVersion.cs @@ -18,8 +18,8 @@ namespace nuget_host.Data [Required] public int Patch { get; set; } - [StringLength(32)] - [Required][Key] + [StringLength(256)] + [Required] public string FullString { get; set; } public bool IsPrerelease { get; set; } diff --git a/src/nuget-host/Migrations/20210522194803_packageVersionKey.Designer.cs b/src/nuget-host/Migrations/20210522194803_packageVersionKey.Designer.cs new file mode 100644 index 0000000..2c37c3a --- /dev/null +++ b/src/nuget-host/Migrations/20210522194803_packageVersionKey.Designer.cs @@ -0,0 +1,312 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using nuget_host.Data; + +namespace nugethost.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20210522194803_packageVersionKey")] + partial class packageVersionKey + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "2.2.6-servicing-10079") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("nuget_host.Data.ApiKeys.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("CreationDate"); + + b.Property("Name"); + + b.Property("UserId") + .IsRequired(); + + b.Property("ValidityPeriodInDays"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKeys"); + }); + + modelBuilder.Entity("nuget_host.Data.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("FullName"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("nuget_host.Data.Package", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.Property("OwnerId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("Packages"); + }); + + modelBuilder.Entity("nuget_host.Data.PackageVersion", b => + { + b.Property("PackageId"); + + b.Property("FullString") + .HasMaxLength(256); + + b.Property("IsPrerelease"); + + b.Property("Major"); + + b.Property("Minor"); + + b.Property("Patch"); + + b.HasKey("PackageId", "FullString"); + + b.ToTable("PackageVersions"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("nuget_host.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("nuget_host.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("nuget_host.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("nuget_host.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("nuget_host.Data.ApiKeys.ApiKey", b => + { + b.HasOne("nuget_host.Data.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("nuget_host.Data.Package", b => + { + b.HasOne("nuget_host.Data.ApplicationUser", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("nuget_host.Data.PackageVersion", b => + { + b.HasOne("nuget_host.Data.Package", "Package") + .WithMany() + .HasForeignKey("PackageId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/nuget-host/Migrations/20210522194803_packageVersionKey.cs b/src/nuget-host/Migrations/20210522194803_packageVersionKey.cs new file mode 100644 index 0000000..bed68db --- /dev/null +++ b/src/nuget-host/Migrations/20210522194803_packageVersionKey.cs @@ -0,0 +1,56 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace nugethost.Migrations +{ + public partial class packageVersionKey : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_PackageVersions", + table: "PackageVersions"); + + migrationBuilder.DropIndex( + name: "IX_PackageVersions_PackageId", + table: "PackageVersions"); + + migrationBuilder.AlterColumn( + name: "FullString", + table: "PackageVersions", + maxLength: 256, + nullable: false, + oldClrType: typeof(string), + oldMaxLength: 32); + + migrationBuilder.AddPrimaryKey( + name: "PK_PackageVersions", + table: "PackageVersions", + columns: new[] { "PackageId", "FullString" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_PackageVersions", + table: "PackageVersions"); + + migrationBuilder.AlterColumn( + name: "FullString", + table: "PackageVersions", + maxLength: 32, + nullable: false, + oldClrType: typeof(string), + oldMaxLength: 256); + + migrationBuilder.AddPrimaryKey( + name: "PK_PackageVersions", + table: "PackageVersions", + column: "FullString"); + + migrationBuilder.CreateIndex( + name: "IX_PackageVersions_PackageId", + table: "PackageVersions", + column: "PackageId"); + } + } +} diff --git a/src/nuget-host/Migrations/ApplicationDbContextModelSnapshot.cs b/src/nuget-host/Migrations/ApplicationDbContextModelSnapshot.cs index 0815c76..eba417d 100644 --- a/src/nuget-host/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/nuget-host/Migrations/ApplicationDbContextModelSnapshot.cs @@ -218,9 +218,10 @@ namespace nugethost.Migrations modelBuilder.Entity("nuget_host.Data.PackageVersion", b => { + b.Property("PackageId"); + b.Property("FullString") - .ValueGeneratedOnAdd() - .HasMaxLength(32); + .HasMaxLength(256); b.Property("IsPrerelease"); @@ -228,14 +229,9 @@ namespace nugethost.Migrations b.Property("Minor"); - b.Property("PackageId") - .IsRequired(); - b.Property("Patch"); - b.HasKey("FullString"); - - b.HasIndex("PackageId"); + b.HasKey("PackageId", "FullString"); b.ToTable("PackageVersions"); }); diff --git a/src/nuget-host/Startup.cs b/src/nuget-host/Startup.cs index c9dfbb7..cf585f9 100644 --- a/src/nuget-host/Startup.cs +++ b/src/nuget-host/Startup.cs @@ -30,7 +30,6 @@ namespace nuget_host } public IConfiguration Configuration { get; } - public static string RootApiKeySecret { get; private set; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) diff --git a/src/nuget-host/ViewModels/PackageVersionIndexViewModel.cs b/src/nuget-host/ViewModels/PackageVersionIndexViewModel.cs new file mode 100644 index 0000000..e3e66b9 --- /dev/null +++ b/src/nuget-host/ViewModels/PackageVersionIndexViewModel.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using nuget_host.Data; + +namespace nuget_host.ViewModels +{ + public class PackageVersionIndexViewModel + { + public List Versions {get; set;} + public string PackageId { get; set; } + } +} \ No newline at end of file diff --git a/src/nuget-host/Views/PackageVersion/Delete.cshtml b/src/nuget-host/Views/PackageVersion/Delete.cshtml new file mode 100644 index 0000000..7f72598 --- /dev/null +++ b/src/nuget-host/Views/PackageVersion/Delete.cshtml @@ -0,0 +1,52 @@ +@model nuget_host.Data.PackageVersion + +@{ + ViewData["Title"] = "Delete"; +} + +

Delete

+ +

Are you sure you want to delete this?

+
+

PackageVersion

+
+
+
+ @Html.DisplayNameFor(model => model.Major) +
+
+ @Html.DisplayFor(model => model.Major) +
+
+ @Html.DisplayNameFor(model => model.Minor) +
+
+ @Html.DisplayFor(model => model.Minor) +
+
+ @Html.DisplayNameFor(model => model.Patch) +
+
+ @Html.DisplayFor(model => model.Patch) +
+
+ @Html.DisplayNameFor(model => model.IsPrerelease) +
+
+ @Html.DisplayFor(model => model.IsPrerelease) +
+
+ @Html.DisplayNameFor(model => model.Package) +
+
+ @Html.DisplayFor(model => model.Package.Id) +
+
+ +
+ + + | + Back to List +
+
diff --git a/src/nuget-host/Views/PackageVersion/Details.cshtml b/src/nuget-host/Views/PackageVersion/Details.cshtml new file mode 100644 index 0000000..7005d46 --- /dev/null +++ b/src/nuget-host/Views/PackageVersion/Details.cshtml @@ -0,0 +1,48 @@ +@model nuget_host.Data.PackageVersion + +@{ + ViewData["Title"] = "Details"; +} + +

Details

+ +
+

PackageVersion

+
+
+
+ @Html.DisplayNameFor(model => model.Major) +
+
+ @Html.DisplayFor(model => model.Major) +
+
+ @Html.DisplayNameFor(model => model.Minor) +
+
+ @Html.DisplayFor(model => model.Minor) +
+
+ @Html.DisplayNameFor(model => model.Patch) +
+
+ @Html.DisplayFor(model => model.Patch) +
+
+ @Html.DisplayNameFor(model => model.IsPrerelease) +
+
+ @Html.DisplayFor(model => model.IsPrerelease) +
+
+ @Html.DisplayNameFor(model => model.Package) +
+
+ @Html.DisplayFor(model => model.Package.Id) +
+
+
+
+ @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) | + Back to List +
diff --git a/src/nuget-host/Views/PackageVersion/Index.cshtml b/src/nuget-host/Views/PackageVersion/Index.cshtml new file mode 100644 index 0000000..1b112b6 --- /dev/null +++ b/src/nuget-host/Views/PackageVersion/Index.cshtml @@ -0,0 +1,66 @@ +@model PackageVersionIndexViewModel + +@{ + ViewData["Title"] = "Index"; +} + +

Index

+ +

+

+
+ +
+ + +
+
+ +
+
+

+ + + + + + + + + + + + + +@foreach (var item in Model.Versions) { + + + + + + + +} + +
+ @Html.DisplayNameFor(model => model.Versions[0].Major) + + @Html.DisplayNameFor(model => model.Versions[0].Minor) + + @Html.DisplayNameFor(model => model.Versions[0].Patch) + + @Html.DisplayNameFor(model => model.Versions[0].IsPrerelease) + + @Html.DisplayNameFor(model => model.Versions[0].Package) +
+ @Html.DisplayFor(modelItem => item.Major) + + @Html.DisplayFor(modelItem => item.Minor) + + @Html.DisplayFor(modelItem => item.Patch) + + @Html.DisplayFor(modelItem => item.IsPrerelease) + + @Html.ActionLink("Details", "Details", new { pkgid = Model.PackageId, version = item.FullString }) | + @Html.ActionLink("Delete", "Delete", new { pkgid = Model.PackageId, version = item.FullString }) +
diff --git a/src/nuget-host/Views/_ViewImports.cshtml b/src/nuget-host/Views/_ViewImports.cshtml index 1056335..3fedf00 100644 --- a/src/nuget-host/Views/_ViewImports.cshtml +++ b/src/nuget-host/Views/_ViewImports.cshtml @@ -1,2 +1,3 @@ @using nuget_host.Data +@using nuget_host.ViewModels @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/nuget-host/packages/nuget-cli/1.0.0/nuget-cli-1.0.0.nupkg b/src/nuget-host/packages/nuget-cli/1.0.0/nuget-cli-1.0.0.nupkg new file mode 100644 index 0000000..2b57d2c Binary files /dev/null and b/src/nuget-host/packages/nuget-cli/1.0.0/nuget-cli-1.0.0.nupkg differ