ApiKey
This commit is contained in:
@ -13,12 +13,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace nuget_host.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.
|
||||
/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!
|
||||
/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval
|
||||
/// </summary>
|
||||
[SecurityHeaders]
|
||||
[AllowAnonymous]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
|
146
Controllers/ApiKeysController.cs
Normal file
146
Controllers/ApiKeysController.cs
Normal file
@ -0,0 +1,146 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using nuget_host.Data;
|
||||
using nuget_host.Entities;
|
||||
using nuget_host.Models;
|
||||
using nuget_host.Models.ApiKeys;
|
||||
|
||||
|
||||
namespace nuget_host.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class ApiKeysController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext dbContext;
|
||||
private readonly NugetSettings nugetSettings;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
private readonly IDataProtector protector;
|
||||
public ApiKeysController(ApplicationDbContext dbContext,
|
||||
IOptions<NugetSettings> nugetSettingsOptions,
|
||||
IDataProtectionProvider provider,
|
||||
UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
this.dbContext = dbContext;
|
||||
this.nugetSettings = nugetSettingsOptions.Value;
|
||||
protector = provider.CreateProtector(nugetSettings.ProtectionTitle);
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Index()
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
System.Collections.Generic.List<ApiKey> index = GetUserKeys().ToList();
|
||||
IndexModel model = new IndexModel { ApiKey = index };
|
||||
ViewData["Title"] = "Index";
|
||||
return View("Index", model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Create()
|
||||
{
|
||||
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var username = User.Identity.Name;
|
||||
var user = await _userManager.FindByIdAsync(userId);
|
||||
ViewBag.UserId = new SelectList(new List<ApplicationUser> { user });
|
||||
return View(new CreateModel{ });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Create(CreateModel model)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
IQueryable<ApiKey> userKeys = GetUserKeys();
|
||||
if (userKeys.Count() >= nugetSettings.MaxUserKeyCount)
|
||||
{
|
||||
ModelState.AddModelError(null, "Maximum key count reached");
|
||||
return View();
|
||||
}
|
||||
ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name };
|
||||
_ = dbContext.ApiKeys.Add(newKey);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
return View("Details", new DetailModel { Name = newKey.Name,
|
||||
ProtectedValue = protector.Protect(newKey.Id),
|
||||
ApiKey = newKey });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Delete(string id)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = dbContext.ApiKeys.FirstOrDefault(k => k.Id == id && k.UserId == userid);
|
||||
return View(new DeleteModel { ApiKey = key });
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Delete(DeleteModel model)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = dbContext.ApiKeys.FirstOrDefault(k => k.Id == model.ApiKey.Id && k.UserId == userid);
|
||||
if (key == null)
|
||||
{
|
||||
ModelState.AddModelError(null, "Key not found");
|
||||
return View();
|
||||
}
|
||||
_ = dbContext.ApiKeys.Remove(key);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
return View("Index", new IndexModel { ApiKey = GetUserKeys().ToList() } );
|
||||
}
|
||||
|
||||
public async Task<ActionResult> Details(string id)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
|
||||
if (key == null)
|
||||
{
|
||||
ModelState.AddModelError(null, "Key not found");
|
||||
return View();
|
||||
}
|
||||
return View("Details", new DetailModel { ApiKey = key, Name = key.Name, ProtectedValue = protector.Protect(key.Id)});
|
||||
|
||||
}
|
||||
|
||||
public async Task<ActionResult> Edit(string id)
|
||||
{
|
||||
|
||||
EditModel edit = new EditModel();
|
||||
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
var user = await _userManager.FindByIdAsync(userId);
|
||||
|
||||
edit.ApiKey = await GetUserKeys().SingleOrDefaultAsync(k =>
|
||||
k.UserId == userId && k.Id == id);
|
||||
ViewBag.UserId = new SelectList(new List<ApplicationUser> { user });
|
||||
|
||||
return View(edit);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Edit(EditModel model)
|
||||
{
|
||||
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
var apiKey = await dbContext.ApiKeys.SingleOrDefaultAsync(k => k.UserId == userId && k.Id == model.ApiKey.Id);
|
||||
apiKey.Name = model.ApiKey.Name;
|
||||
apiKey.ValidityPeriodInDays = model.ApiKey.ValidityPeriodInDays;
|
||||
await dbContext.SaveChangesAsync();
|
||||
return View("Details", new DetailModel { ApiKey = apiKey });
|
||||
}
|
||||
|
||||
public IQueryable<ApiKey> GetUserKeys()
|
||||
{
|
||||
return dbContext.ApiKeys.Include(k => k.User).Where(k => k.User.UserName == User.Identity.Name);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using nuget_host.Models;
|
||||
using nuget_host.Models.ApiKeys;
|
||||
|
||||
namespace nuget_host.Data
|
||||
{
|
||||
@ -13,5 +14,7 @@ namespace nuget_host.Data
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<ApiKey> ApiKeys { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace nuget_host.Entities
|
||||
{
|
||||
public string ProtectionTitle {get; set;}
|
||||
public string PackagesRootDir {get; set;}
|
||||
public int MaxUserKeyCount {get; set;}
|
||||
|
||||
}
|
||||
}
|
253
Migrations/20210502153508_api-keys.Designer.cs
generated
Normal file
253
Migrations/20210502153508_api-keys.Designer.cs
generated
Normal file
@ -0,0 +1,253 @@
|
||||
// <auto-generated />
|
||||
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("20210502153508_api-keys")]
|
||||
partial class apikeys
|
||||
{
|
||||
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<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("ProviderKey");
|
||||
|
||||
b.Property<string>("ProviderDisplayName");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("RoleId");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKey", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ApiKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AccessFailedCount");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed");
|
||||
|
||||
b.Property<string>("FullName");
|
||||
|
||||
b.Property<bool>("LockoutEnabled");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("PhoneNumber");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed");
|
||||
|
||||
b.Property<string>("SecurityStamp");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKey", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
39
Migrations/20210502153508_api-keys.cs
Normal file
39
Migrations/20210502153508_api-keys.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace nugethost.Migrations
|
||||
{
|
||||
public partial class apikeys : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ApiKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(nullable: false),
|
||||
UserId = table.Column<string>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ApiKeys", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ApiKeys_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ApiKeys_UserId",
|
||||
table: "ApiKeys",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ApiKeys");
|
||||
}
|
||||
}
|
||||
}
|
259
Migrations/20210508012908_ApkiKey.CreationDate.Designer.cs
generated
Normal file
259
Migrations/20210508012908_ApkiKey.CreationDate.Designer.cs
generated
Normal file
@ -0,0 +1,259 @@
|
||||
// <auto-generated />
|
||||
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("20210508012908_ApkiKey.CreationDate")]
|
||||
partial class ApkiKeyCreationDate
|
||||
{
|
||||
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<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("ProviderKey");
|
||||
|
||||
b.Property<string>("ProviderDisplayName");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("RoleId");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKeys.ApiKey", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("CreationDate");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("ValidityPeriodInDays");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ApiKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AccessFailedCount");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed");
|
||||
|
||||
b.Property<string>("FullName");
|
||||
|
||||
b.Property<bool>("LockoutEnabled");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("PhoneNumber");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed");
|
||||
|
||||
b.Property<string>("SecurityStamp");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKeys.ApiKey", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
43
Migrations/20210508012908_ApkiKey.CreationDate.cs
Normal file
43
Migrations/20210508012908_ApkiKey.CreationDate.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace nugethost.Migrations
|
||||
{
|
||||
public partial class ApkiKeyCreationDate : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "CreationDate",
|
||||
table: "ApiKeys",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "ApiKeys",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "ValidityPeriodInDays",
|
||||
table: "ApiKeys",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CreationDate",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "ApiKeys");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ValidityPeriodInDays",
|
||||
table: "ApiKeys");
|
||||
}
|
||||
}
|
||||
}
|
@ -126,6 +126,27 @@ namespace nugethost.Migrations
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKeys.ApiKey", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("CreationDate");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("ValidityPeriodInDays");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ApiKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
@ -222,6 +243,14 @@ namespace nugethost.Migrations
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("nuget_host.Models.ApiKeys.ApiKey", b =>
|
||||
{
|
||||
b.HasOne("nuget_host.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
23
Models/ApiKeys/ApiKey.cs
Normal file
23
Models/ApiKeys/ApiKey.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class ApiKey
|
||||
{
|
||||
[Required][Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[Required][ForeignKey("User")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int ValidityPeriodInDays{ get; set; }
|
||||
|
||||
public DateTime CreationDate { get; set; }
|
||||
}
|
||||
}
|
14
Models/ApiKeys/ApiKeyViewModel.cs
Normal file
14
Models/ApiKeys/ApiKeyViewModel.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class ApiKeyViewModel
|
||||
{
|
||||
[Display(Name = "Key Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
[Display(Name = "Key Value")]
|
||||
public string ProtectedValue { get; set; }
|
||||
}
|
||||
}
|
14
Models/ApiKeys/CreateModel.cs
Normal file
14
Models/ApiKeys/CreateModel.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class CreateModel
|
||||
{
|
||||
|
||||
[Required][StringLength(255)]
|
||||
[Display(Name = "Key Name")]
|
||||
public string Name { get; set; }
|
||||
public string UserId { get; set; }
|
||||
|
||||
}
|
||||
}
|
7
Models/ApiKeys/DeleteModel.cs
Normal file
7
Models/ApiKeys/DeleteModel.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class DeleteModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
}
|
||||
}
|
8
Models/ApiKeys/DetailModel.cs
Normal file
8
Models/ApiKeys/DetailModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class DetailModel : ApiKeyViewModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
|
||||
}
|
||||
}
|
12
Models/ApiKeys/EditModel.cs
Normal file
12
Models/ApiKeys/EditModel.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class EditModel
|
||||
{
|
||||
public EditModel()
|
||||
{
|
||||
if (ApiKey==null) ApiKey = new ApiKey();
|
||||
}
|
||||
|
||||
public ApiKey ApiKey { get; set; }
|
||||
}
|
||||
}
|
9
Models/ApiKeys/IndexModel.cs
Normal file
9
Models/ApiKeys/IndexModel.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class IndexModel
|
||||
{
|
||||
public List<ApiKey> ApiKey { get; set; }
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace nuget_host.Models
|
||||
{
|
||||
public class GrantsViewModel
|
||||
{
|
||||
public IEnumerable<GrantViewModel> Grants { get; set; }
|
||||
}
|
||||
|
||||
public class GrantViewModel
|
||||
{
|
||||
public string ClientId { get; set; }
|
||||
public string ClientName { get; set; }
|
||||
public string ClientUrl { get; set; }
|
||||
public string ClientLogoUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime? Expires { get; set; }
|
||||
public IEnumerable<string> IdentityGrantNames { get; set; }
|
||||
public IEnumerable<string> ApiGrantNames { get; set; }
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace nuget_host.Models
|
||||
{
|
||||
public class SecurityHeadersAttribute : ActionFilterAttribute
|
||||
{
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
{
|
||||
var result = context.Result;
|
||||
if (result is ViewResult)
|
||||
{
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||
if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Type-Options"))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("X-Content-Type-Options", "nosniff");
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
||||
if (!context.HttpContext.Response.Headers.ContainsKey("X-Frame-Options"))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||
var csp = "default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';";
|
||||
// also consider adding upgrade-insecure-requests once you have HTTPS in place for production
|
||||
//csp += "upgrade-insecure-requests;";
|
||||
// also an example if you need client images to be displayed from twitter
|
||||
// csp += "img-src 'self' https://pbs.twimg.com;";
|
||||
|
||||
// once for standards compliant browsers
|
||||
if (!context.HttpContext.Response.Headers.ContainsKey("Content-Security-Policy"))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("Content-Security-Policy", csp);
|
||||
}
|
||||
// and once again for IE
|
||||
if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Security-Policy"))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("X-Content-Security-Policy", csp);
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
||||
var referrer_policy = "no-referrer";
|
||||
if (!context.HttpContext.Response.Headers.ContainsKey("Referrer-Policy"))
|
||||
{
|
||||
context.HttpContext.Response.Headers.Add("Referrer-Policy", referrer_policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -51,9 +51,9 @@ namespace nuget_host
|
||||
services.AddTransient<IMailer, EmailSender>();
|
||||
services.AddTransient<IEmailSender, EmailSender>();
|
||||
|
||||
var smtpSettingsconf = Configuration.GetSection("SmtpSettings");
|
||||
var smtpSettingsconf = Configuration.GetSection("Smtp");
|
||||
services.Configure<SmtpSettings>(smtpSettingsconf);
|
||||
var nugetSettingsconf = Configuration.GetSection("NugetSettings");
|
||||
var nugetSettingsconf = Configuration.GetSection("Nuget");
|
||||
services.Configure<NugetSettings>(nugetSettingsconf);
|
||||
|
||||
}
|
||||
|
35
Views/ApiKeys/Create.cshtml
Normal file
35
Views/ApiKeys/Create.cshtml
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
@model nuget_host.Models.ApiKeys.CreateModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Create";
|
||||
}
|
||||
|
||||
<h2>Create</h2>
|
||||
|
||||
<h4>ApiKey</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post" asp-controller="ApiKeys">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="UserId" class="control-label"></label>
|
||||
<select asp-for="UserId" class ="form-control" asp-items="ViewBag.UserId"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Name" class="control-label"></label>
|
||||
<input asp-for="Name" class="form-control" />
|
||||
<span asp-validation-for="Name" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Create" class="btn btn-default" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
||||
|
46
Views/ApiKeys/Delete.cshtml
Normal file
46
Views/ApiKeys/Delete.cshtml
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
@model nuget_host.Models.ApiKeys.DeleteModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Delete";
|
||||
}
|
||||
|
||||
<h2>Delete</h2>
|
||||
|
||||
<h3>Are you sure you want to delete this?</h3>
|
||||
<div>
|
||||
<h4>ApiKey</h4>
|
||||
<hr />
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.User)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.User.Id)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.Name)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.Name)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.CreationDate)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.CreationDate)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.ValidityPeriodInDays)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.ValidityPeriodInDays)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<form method="post">
|
||||
<input type="hidden" asp-for="ApiKey.Id" />
|
||||
<input type="submit" value="Delete" class="btn btn-default" /> |
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</form>
|
||||
</div>
|
49
Views/ApiKeys/Details.cshtml
Normal file
49
Views/ApiKeys/Details.cshtml
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
@model nuget_host.Models.ApiKeys.DetailModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Details";
|
||||
}
|
||||
|
||||
<h2>Details</h2>
|
||||
|
||||
<div>
|
||||
<h4>ApiKey</h4>
|
||||
<hr />
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.User)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.User.Id)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.Name)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.Name)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.CreationDate)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.CreationDate)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ApiKey.ValidityPeriodInDays)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ApiKey.ValidityPeriodInDays)
|
||||
</dd>
|
||||
<dt>
|
||||
@Html.DisplayNameFor(model => model.ProtectedValue)
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.DisplayFor(model => model.ProtectedValue)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-controller="ApiKeys" asp-action="Edit" asp-route-id="@Model.ApiKey.Id">Edit</a> |
|
||||
<a asp-controller="ApiKeys" asp-action="Index">Back to List</a>
|
||||
</div>
|
42
Views/ApiKeys/Edit.cshtml
Normal file
42
Views/ApiKeys/Edit.cshtml
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
@model nuget_host.Models.ApiKeys.EditModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Edit";
|
||||
}
|
||||
|
||||
<h2>Edit</h2>
|
||||
|
||||
<h4>ApiKey</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<input type="hidden" asp-for="ApiKey.Id" />
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey.UserId" class="control-label"></label>
|
||||
<select asp-for="ApiKey.UserId" class="form-control" asp-items="ViewBag.UserId"></select>
|
||||
<span asp-validation-for="ApiKey.UserId" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey.Name" class="control-label"></label>
|
||||
<input asp-for="ApiKey.Name" class="form-control" />
|
||||
<span asp-validation-for="ApiKey.Name" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="ApiKey.ValidityPeriodInDays" class="control-label"></label>
|
||||
<input asp-for="ApiKey.ValidityPeriodInDays" class="form-control" />
|
||||
<span asp-validation-for="ApiKey.ValidityPeriodInDays" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="Save" class="btn btn-default" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a asp-action="Index">Back to List</a>
|
||||
</div>
|
||||
|
54
Views/ApiKeys/Index.cshtml
Normal file
54
Views/ApiKeys/Index.cshtml
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
@model nuget_host.Models.ApiKeys.IndexModel
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Index";
|
||||
}
|
||||
|
||||
<h2>Index</h2>
|
||||
|
||||
<p>
|
||||
<a asp-controller="ApiKeys" asp-action="Create">Create New</a>
|
||||
</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.ApiKey[0].User)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.ApiKey[0].Name)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.ApiKey[0].CreationDate)
|
||||
</th>
|
||||
<th>
|
||||
@Html.DisplayNameFor(model => model.ApiKey[0].ValidityPeriodInDays)
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.ApiKey) {
|
||||
<tr>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.User.Id)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.Name)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.CreationDate)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayFor(modelItem => item.ValidityPeriodInDays)
|
||||
</td>
|
||||
<td>
|
||||
<a asp-controller="ApiKeys" asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
|
||||
<a asp-controller="ApiKeys" asp-action="Details" asp-route-id="@item.Id">Details</a> |
|
||||
<a asp-controller="ApiKeys" asp-action="Delete" asp-route-id="@item.Id">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
@ -1,87 +0,0 @@
|
||||
@model GrantsViewModel
|
||||
|
||||
<div class="grants-page">
|
||||
<div class="lead">
|
||||
<h1>Client Application Permissions</h1>
|
||||
<p>Below is the list of applications you have given permission to and the resources they have access to.</p>
|
||||
</div>
|
||||
|
||||
@if (Model.Grants.Any() == false)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div class="alert alert-info">
|
||||
You have not given access to any applications
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var grant in Model.Grants)
|
||||
{
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-sm-8 card-title">
|
||||
@if (grant.ClientLogoUrl != null)
|
||||
{
|
||||
<img src="@grant.ClientLogoUrl">
|
||||
}
|
||||
<strong>@grant.ClientName</strong>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<form asp-action="Revoke">
|
||||
<input type="hidden" name="clientId" value="@grant.ClientId">
|
||||
<button class="btn btn-danger">Revoke Access</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="list-group list-group-flush">
|
||||
@if (grant.Description != null)
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<label>Description:</label> @grant.Description
|
||||
</li>
|
||||
}
|
||||
<li class="list-group-item">
|
||||
<label>Created:</label> @grant.Created.ToString("yyyy-MM-dd")
|
||||
</li>
|
||||
@if (grant.Expires.HasValue)
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<label>Expires:</label> @grant.Expires.Value.ToString("yyyy-MM-dd")
|
||||
</li>
|
||||
}
|
||||
@if (grant.IdentityGrantNames.Any())
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<label>Identity Grants</label>
|
||||
<ul>
|
||||
@foreach (var name in grant.IdentityGrantNames)
|
||||
{
|
||||
<li>@name</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
@if (grant.ApiGrantNames.Any())
|
||||
{
|
||||
<li class="list-group-item">
|
||||
<label>API Grants</label>
|
||||
<ul>
|
||||
@foreach (var name in grant.ApiGrantNames)
|
||||
{
|
||||
<li>@name</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
@ -1,5 +1,6 @@
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";}
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="display-4">Welcome</h1>
|
||||
@ -8,4 +9,4 @@
|
||||
<img src="~/icon.jpg">
|
||||
Welcome to Nuget host
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"NuGet": {
|
||||
"Nuget": {
|
||||
"ExternalUrl" : "<http://localhost:5000/packages",
|
||||
"PackagesRootDir" : "packages"
|
||||
"PackagesRootDir" : "packages",
|
||||
"MaxUserKeyCount": 5
|
||||
},
|
||||
"Smtp": {
|
||||
"Server": "localhost",
|
||||
|
@ -1,9 +1,10 @@
|
||||
{
|
||||
"RootApiKeySecret": "<your-root-api-clear-key>",
|
||||
"NuGet": {
|
||||
"Nuget": {
|
||||
"ExternalUrl" : "<http://your-external.url",
|
||||
"PackagesRootDir" : "<your-Source-dir>",
|
||||
"ProtectionTitle": "protected-data-v1"
|
||||
"ProtectionTitle": "protected-data-v1",
|
||||
"MaxUserKeyCount": 1
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=<pqserver>;Port=<pqport>;Database=<dbname>;Username=<dbusername>;Password=<dbpass>;"
|
||||
|
Reference in New Issue
Block a user