ApiKey
parent
749eb645d5
commit
dd6d83cf06
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class DeleteModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class DetailModel : ApiKeyViewModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace nuget_host.Models.ApiKeys
|
||||
{
|
||||
public class IndexModel
|
||||
{
|
||||
public List<ApiKey> ApiKey { get; set; }
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
||||
|
@ -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>
|
Loading…
Reference in New Issue