From be7df3d054fd7c685379c8aa8f0d988bc87ac240 Mon Sep 17 00:00:00 2001
From: Paul Schneider
Date: Mon, 16 Mar 2026 23:16:12 +0000
Subject: [PATCH] APi Scopes
---
.../Administration/ApiScopeController.cs | 153 +++++++++++++++++
.../Administration/ApiScopesApiController.cs | 58 +++++++
.../Administration/ClientController.cs | 79 ++++++---
src/Yavsc.Org/Extensions/HostingExtensions.cs | 18 +-
src/Yavsc.Org/Views/ApiScope/Create.cshtml | 69 ++++++++
src/Yavsc.Org/Views/ApiScope/Delete.cshtml | 72 ++++++++
src/Yavsc.Org/Views/ApiScope/Details.cshtml | 69 ++++++++
src/Yavsc.Org/Views/ApiScope/Edit.cshtml | 70 ++++++++
src/Yavsc.Org/Views/ApiScope/Index.cshtml | 79 +++++++++
src/Yavsc.Org/Views/Client/Details.cshtml | 2 +-
src/Yavsc.Org/Views/Client/Index.cshtml | 154 +++++++++---------
src/Yavsc.Org/Views/Shared/_Layout.cshtml | 4 +-
.../wwwroot/lib/bootstrap.quartz.min.css | 12 ++
.../Models/ApplicationDbContext.cs | 23 ++-
src/Yavsc.Server/Models/YavscApiResource.cs | 8 +
.../Models/YavscApiResourceClaim.cs | 8 +
.../Models/YavscApiResourceProperty.cs | 8 +
.../Models/YavscApiResourceScope.cs | 8 +
.../Models/YavscApiResourceSecret.cs | 8 +
src/Yavsc.Server/Models/YavscApiScope.cs | 9 +
src/Yavsc.Server/Models/YavscApiScopeClaim.cs | 8 +
.../Models/YavscApiScopeProperty.cs | 8 +
.../Models/YavscDeviceFlowCodes.cs | 8 +
.../Models/YavscPersistedGrant.cs | 8 +
.../yavscTests/NonRegression/AbstractTests.cs | 2 +-
25 files changed, 826 insertions(+), 119 deletions(-)
create mode 100644 src/Yavsc.Org/Controllers/Administration/ApiScopeController.cs
create mode 100644 src/Yavsc.Org/Controllers/Administration/ApiScopesApiController.cs
create mode 100644 src/Yavsc.Org/Views/ApiScope/Create.cshtml
create mode 100644 src/Yavsc.Org/Views/ApiScope/Delete.cshtml
create mode 100644 src/Yavsc.Org/Views/ApiScope/Details.cshtml
create mode 100644 src/Yavsc.Org/Views/ApiScope/Edit.cshtml
create mode 100644 src/Yavsc.Org/Views/ApiScope/Index.cshtml
create mode 100644 src/Yavsc.Org/wwwroot/lib/bootstrap.quartz.min.css
create mode 100644 src/Yavsc.Server/Models/YavscApiResource.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiResourceClaim.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiResourceProperty.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiResourceScope.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiResourceSecret.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiScope.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiScopeClaim.cs
create mode 100644 src/Yavsc.Server/Models/YavscApiScopeProperty.cs
create mode 100644 src/Yavsc.Server/Models/YavscDeviceFlowCodes.cs
create mode 100644 src/Yavsc.Server/Models/YavscPersistedGrant.cs
diff --git a/src/Yavsc.Org/Controllers/Administration/ApiScopeController.cs b/src/Yavsc.Org/Controllers/Administration/ApiScopeController.cs
new file mode 100644
index 00000000..0a32abaf
--- /dev/null
+++ b/src/Yavsc.Org/Controllers/Administration/ApiScopeController.cs
@@ -0,0 +1,153 @@
+
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Yavsc.Models;
+using IdentityServer8.EntityFramework.Entities;
+namespace Yavsc.Org.Controllers
+{
+ public class ApiScopeController : Controller
+ {
+ private readonly ApplicationDbContext _context;
+
+ public ApiScopeController(ApplicationDbContext context)
+ {
+ _context = context;
+ }
+
+ // GET: ApiScope
+ public async Task Index()
+ {
+ return View(await _context.ApiScopes.ToListAsync());
+ }
+
+ // GET: ApiScope/Details/5
+ public async Task Details(int? id)
+ {
+ if (id == null)
+ {
+ return NotFound();
+ }
+
+ var apiScope = await _context.ApiScopes
+ .FirstOrDefaultAsync(m => m.Id == id);
+ if (apiScope == null)
+ {
+ return NotFound();
+ }
+
+ return View(apiScope);
+ }
+
+ // GET: ApiScope/Create
+ public IActionResult Create()
+ {
+ return View();
+ }
+
+ // POST: ApiScope/Create
+ // To protect from overposting attacks, enable the specific properties you want to bind to.
+ // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task Create(ApiScope apiScope)
+ {
+ if (ModelState.IsValid)
+ {
+ _context.Add(apiScope);
+ await _context.SaveChangesAsync();
+ return RedirectToAction(nameof(Index));
+ }
+ return View(apiScope);
+ }
+
+ // GET: ApiScope/Edit/5
+ public async Task Edit(int? id)
+ {
+ if (id == null)
+ {
+ return NotFound();
+ }
+
+ var apiScope = await _context.ApiScopes.FindAsync(id);
+ if (apiScope == null)
+ {
+ return NotFound();
+ }
+ return View(apiScope);
+ }
+
+ // POST: ApiScope/Edit/5
+ // To protect from overposting attacks, enable the specific properties you want to bind to.
+ // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task Edit(int id,
+ ApiScope apiScope)
+ {
+ if (id != apiScope.Id)
+ {
+ return NotFound();
+ }
+
+ if (ModelState.IsValid)
+ {
+ try
+ {
+ _context.Update(apiScope);
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!ApiScopeExists(apiScope.Id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+ return RedirectToAction(nameof(Index));
+ }
+ return View(apiScope);
+ }
+
+ // GET: ApiScope/Delete/5
+ public async Task Delete(int? id)
+ {
+ if (id == null)
+ {
+ return NotFound();
+ }
+
+ var apiScope = await _context.ApiScopes
+ .FirstOrDefaultAsync(m => m.Id == id);
+ if (apiScope == null)
+ {
+ return NotFound();
+ }
+
+ return View(apiScope);
+ }
+
+ // POST: ApiScope/Delete/5
+ [HttpPost, ActionName("Delete")]
+ [ValidateAntiForgeryToken]
+ public async Task DeleteConfirmed(int id)
+ {
+ var apiScope = await _context.ApiScopes.FindAsync(id);
+ if (apiScope != null)
+ {
+ _context.ApiScopes.Remove(apiScope);
+ }
+
+ await _context.SaveChangesAsync();
+ return RedirectToAction(nameof(Index));
+ }
+
+ private bool ApiScopeExists(int id)
+ {
+ return _context.ApiScopes.Any(e => e.Id == id);
+ }
+ }
+}
diff --git a/src/Yavsc.Org/Controllers/Administration/ApiScopesApiController.cs b/src/Yavsc.Org/Controllers/Administration/ApiScopesApiController.cs
new file mode 100644
index 00000000..983e7233
--- /dev/null
+++ b/src/Yavsc.Org/Controllers/Administration/ApiScopesApiController.cs
@@ -0,0 +1,58 @@
+using IdentityServer8.EntityFramework.Entities;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Yavsc.Models;
+using Yavsc.Server.Helpers;
+
+namespace Yavsc.Org.Controllers.Administration
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class ApiScopesApiController : ControllerBase
+ {
+ private ApplicationDbContext dbContext;
+
+ public ApiScopesApiController(ApplicationDbContext dbContext)
+ {
+ this.dbContext = dbContext;
+ }
+ // GET: api/
+ [HttpGet]
+ public async Task> Get(int skip = 0, int take = 25)
+ {
+ return await dbContext.ApiScopes.Skip(skip).Take(take).ToArrayAsync();
+ }
+
+ // GET api//5
+ [HttpGet("{id}")]
+ public async Task Get(int id)
+ {
+ return await dbContext.ApiScopes.FirstOrDefaultAsync(s => s.Id == id);
+ }
+
+ // POST api/
+ [HttpPost]
+ public async Task Post([FromBody] ApiScope value)
+ {
+ dbContext.ApiScopes.Add(value);
+ await dbContext.SaveChangesAsync(User.GetUserId());
+ }
+
+ // PUT api//5
+ [HttpPut("{id}")]
+ public async Task Put(int id, [FromBody] ApiScope value)
+ {
+ dbContext.Update(value);
+ await dbContext.SaveChangesAsync(User.GetUserId());
+ }
+
+ // DELETE api//5
+ [HttpDelete("{id}")]
+ public async Task Delete(int id)
+ {
+ var scope = await dbContext.ApiScopes.FirstAsync(s => s.Id == id);
+ dbContext.Remove(scope);
+ }
+ }
+}
diff --git a/src/Yavsc.Org/Controllers/Administration/ClientController.cs b/src/Yavsc.Org/Controllers/Administration/ClientController.cs
index 47a6c0aa..658a7639 100644
--- a/src/Yavsc.Org/Controllers/Administration/ClientController.cs
+++ b/src/Yavsc.Org/Controllers/Administration/ClientController.cs
@@ -5,33 +5,36 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Options;
using Yavsc.Models;
using Yavsc.Models.Auth;
+using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{
[Authorize("AdministratorOnly")]
public class ClientController : Controller
{
- private readonly ApplicationDbContext context;
+ private readonly ApplicationDbContext dbContext;
private readonly ClientStore clientStore;
+ private readonly SiteSettings siteSettings;
- public ClientController(ApplicationDbContext context,
- ClientStore clientStore,
-
- IdentityServer8.Stores.ValidatingClientStore validatingClientStore
+ public ClientController(
+ ApplicationDbContext dbContext,
+ ClientStore clientStore, IOptions siteSettingsOptions
)
{
- this.context = context;
+ this.dbContext = dbContext;
this.clientStore = clientStore;
+ this.siteSettings = siteSettingsOptions.Value;
}
// GET: Client
public async Task Index()
{
- return View(await context.Clients.Include(c => c.AllowedGrantTypes)
+ return View(await dbContext.Clients.Include(c => c.AllowedGrantTypes)
.Include(c => c.RedirectUris).ToListAsync());
}
@@ -39,7 +42,7 @@ namespace Yavsc.Controllers
public async Task Details(int id)
{
- Client client = await context.Clients.Include(
+ Client client = await dbContext.Clients.Include(
c => c.ClientSecrets
).Include(c => c.AllowedGrantTypes)
.Include(c => c.RedirectUris)
@@ -59,8 +62,6 @@ namespace Yavsc.Controllers
// GET: Client/Create
public IActionResult Create()
{
- Secret s;
-
SetAppTypesInputValues();
return View();
}
@@ -68,6 +69,7 @@ namespace Yavsc.Controllers
// POST: Client/Create
[HttpPost]
[ValidateAntiForgeryToken]
+
public async Task Create(Client client)
{
if (ModelState.IsValid)
@@ -79,16 +81,39 @@ namespace Yavsc.Controllers
return BadRequest(ModelState);
}
- context.Clients.Add(client);
- if (client.ClientSecrets != null)
- {
- foreach (var secret in client.ClientSecrets)
- {
- context.ClientSecrets.Add(secret);
- }
- }
- await context.SaveChangesAsync();
+ dbContext.Clients.Add(client);
+ await dbContext.SaveChangesAsync(User.GetUserId());
+ dbContext.ClientRedirectUris.Add(new ClientRedirectUri
+ {
+ ClientId = client.Id,
+ RedirectUri = siteSettings.Audience
+
+ });
+ dbContext.ClientCorsOrigins.Add(new ClientCorsOrigin
+ {
+ ClientId = client.Id,
+ Origin = siteSettings.Audience
+
+ });
+ foreach (String credType in new String[] { "code", "client_credentials", "password" })
+ {
+ dbContext.ClientGrantTypes.Add(new ClientGrantType
+ {
+ ClientId = client.Id,
+ GrantType = credType
+ });
+ }
+ foreach (String scope in new String[] { "openid", "profile" })
+ {
+ dbContext.ClientScopes.Add(new ClientScope
+ {
+ ClientId = client.Id,
+ Scope = scope
+ });
+ }
+
+ await dbContext.SaveChangesAsync(User.GetUserId());
return RedirectToAction("Index");
}
@@ -112,7 +137,7 @@ namespace Yavsc.Controllers
// GET: Client/Edit/5
public async Task Edit(int id)
{
- Client client = await context.Clients.SingleOrDefaultAsync(m => m.Id == id);
+ Client client = await dbContext.Clients.SingleOrDefaultAsync(m => m.Id == id);
if (client == null)
{
return NotFound();
@@ -133,11 +158,11 @@ namespace Yavsc.Controllers
{
foreach (var secret in client.ClientSecrets)
{
- context.Update(secret);
+ dbContext.Update(secret);
}
}
- context.Update(client);
- await context.SaveChangesAsync();
+ dbContext.Update(client);
+ await dbContext.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(client);
@@ -148,7 +173,7 @@ namespace Yavsc.Controllers
public async Task Delete(int id)
{
- Client client = await context.Clients.SingleOrDefaultAsync(m => m.Id == id);
+ Client client = await dbContext.Clients.SingleOrDefaultAsync(m => m.Id == id);
if (client == null)
{
return NotFound();
@@ -162,11 +187,11 @@ namespace Yavsc.Controllers
[ValidateAntiForgeryToken]
public async Task DeleteConfirmed(int id)
{
- Client client = await context.Clients
+ Client client = await dbContext.Clients
.Include(client => client.ClientSecrets)
.SingleAsync(m => m.Id == id);
- context.Clients.Remove(client);
- await context.SaveChangesAsync();
+ dbContext.Clients.Remove(client);
+ await dbContext.SaveChangesAsync();
return RedirectToAction("Index");
}
}
diff --git a/src/Yavsc.Org/Extensions/HostingExtensions.cs b/src/Yavsc.Org/Extensions/HostingExtensions.cs
index 73408301..4af832b0 100644
--- a/src/Yavsc.Org/Extensions/HostingExtensions.cs
+++ b/src/Yavsc.Org/Extensions/HostingExtensions.cs
@@ -43,6 +43,7 @@ using IdentityServer8.EntityFramework.Services;
using IdentityServer8.EntityFramework.Interfaces;
using Microsoft.AspNetCore.Authentication.Cookies;
using IdentityServer8.Validation;
+using IdentityServer8.EntityFramework.Entities;
namespace Yavsc.Extensions;
@@ -288,7 +289,20 @@ public static class HostingExtensions
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(connectionString,
- sql => sql.MigrationsAssembly(migrationsAssembly));
+ sql => sql.MigrationsAssembly(migrationsAssembly))
+ .UseSeeding((context, _) =>
+ {
+ foreach (String scope in new string[] { "blog", "admin", "contract", "com"})
+ {
+ var testBlog = context.Set().FirstOrDefault(b => b.Name == scope);
+ if (testBlog == null)
+ {
+ context.Set().Add(new ApiScope { Name = scope });
+ context.SaveChanges();
+ }
+ }
+
+ });
})
.AddOperationalStore(options =>
{
@@ -398,7 +412,7 @@ public static class HostingExtensions
app.UseSession();
return app;
}
-
+
private static void MigrateDatabase(this IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService().CreateScope())
diff --git a/src/Yavsc.Org/Views/ApiScope/Create.cshtml b/src/Yavsc.Org/Views/ApiScope/Create.cshtml
new file mode 100644
index 00000000..5d3b9b8b
--- /dev/null
+++ b/src/Yavsc.Org/Views/ApiScope/Create.cshtml
@@ -0,0 +1,69 @@
+@model IdentityServer8.EntityFramework.Entities.ApiScope
+
+@{
+ Layout = null;
+}
+
+
+
+
+
+
+ Create
+
+
+
+ApiScope
+
+
+
+
+
+
+
diff --git a/src/Yavsc.Org/Views/ApiScope/Delete.cshtml b/src/Yavsc.Org/Views/ApiScope/Delete.cshtml
new file mode 100644
index 00000000..166e6110
--- /dev/null
+++ b/src/Yavsc.Org/Views/ApiScope/Delete.cshtml
@@ -0,0 +1,72 @@
+@model Yavsc.Models.YavscApiScope
+
+@{
+ Layout = null;
+}
+
+
+
+
+
+
+ Delete
+
+
+
+Are you sure you want to delete this?
+
+
YavscApiScope
+
+
+ -
+ @Html.DisplayNameFor(model => model.Enabled)
+
+ -
+ @Html.DisplayFor(model => model.Enabled)
+
+ -
+ @Html.DisplayNameFor(model => model.Name)
+
+ -
+ @Html.DisplayFor(model => model.Name)
+
+ -
+ @Html.DisplayNameFor(model => model.DisplayName)
+
+ -
+ @Html.DisplayFor(model => model.DisplayName)
+
+ -
+ @Html.DisplayNameFor(model => model.Description)
+
+ -
+ @Html.DisplayFor(model => model.Description)
+
+ -
+ @Html.DisplayNameFor(model => model.Required)
+
+ -
+ @Html.DisplayFor(model => model.Required)
+
+ -
+ @Html.DisplayNameFor(model => model.Emphasize)
+
+ -
+ @Html.DisplayFor(model => model.Emphasize)
+
+ -
+ @Html.DisplayNameFor(model => model.ShowInDiscoveryDocument)
+
+ -
+ @Html.DisplayFor(model => model.ShowInDiscoveryDocument)
+
+
+
+
+
+
+
diff --git a/src/Yavsc.Org/Views/ApiScope/Details.cshtml b/src/Yavsc.Org/Views/ApiScope/Details.cshtml
new file mode 100644
index 00000000..6c904ce3
--- /dev/null
+++ b/src/Yavsc.Org/Views/ApiScope/Details.cshtml
@@ -0,0 +1,69 @@
+@model Yavsc.Models.YavscApiScope
+
+@{
+ Layout = null;
+}
+
+
+
+
+
+
+ Details
+
+
+
+
+
YavscApiScope
+
+
+ -
+ @Html.DisplayNameFor(model => model.Enabled)
+
+ -
+ @Html.DisplayFor(model => model.Enabled)
+
+ -
+ @Html.DisplayNameFor(model => model.Name)
+
+ -
+ @Html.DisplayFor(model => model.Name)
+
+ -
+ @Html.DisplayNameFor(model => model.DisplayName)
+
+ -
+ @Html.DisplayFor(model => model.DisplayName)
+
+ -
+ @Html.DisplayNameFor(model => model.Description)
+
+ -
+ @Html.DisplayFor(model => model.Description)
+
+ -
+ @Html.DisplayNameFor(model => model.Required)
+
+ -
+ @Html.DisplayFor(model => model.Required)
+
+ -
+ @Html.DisplayNameFor(model => model.Emphasize)
+
+ -
+ @Html.DisplayFor(model => model.Emphasize)
+
+ -
+ @Html.DisplayNameFor(model => model.ShowInDiscoveryDocument)
+
+ -
+ @Html.DisplayFor(model => model.ShowInDiscoveryDocument)
+
+
+
+
+
+
diff --git a/src/Yavsc.Org/Views/ApiScope/Edit.cshtml b/src/Yavsc.Org/Views/ApiScope/Edit.cshtml
new file mode 100644
index 00000000..34b111d4
--- /dev/null
+++ b/src/Yavsc.Org/Views/ApiScope/Edit.cshtml
@@ -0,0 +1,70 @@
+@model Yavsc.Models.YavscApiScope
+
+@{
+ Layout = null;
+}
+
+
+
+
+
+
+ Edit
+
+
+
+YavscApiScope
+
+
+
+
+
+
+
diff --git a/src/Yavsc.Org/Views/ApiScope/Index.cshtml b/src/Yavsc.Org/Views/ApiScope/Index.cshtml
new file mode 100644
index 00000000..2d3bd6c7
--- /dev/null
+++ b/src/Yavsc.Org/Views/ApiScope/Index.cshtml
@@ -0,0 +1,79 @@
+@model IEnumerable
+
+@{
+ Layout = null;
+}
+
+
+
+
+
+
+ Index
+
+
+
+ Create New
+
+
+
+
+ |
+ @Html.DisplayNameFor(model => model.Enabled)
+ |
+
+ @Html.DisplayNameFor(model => model.Name)
+ |
+
+ @Html.DisplayNameFor(model => model.DisplayName)
+ |
+
+ @Html.DisplayNameFor(model => model.Description)
+ |
+
+ @Html.DisplayNameFor(model => model.Required)
+ |
+
+ @Html.DisplayNameFor(model => model.Emphasize)
+ |
+
+ @Html.DisplayNameFor(model => model.ShowInDiscoveryDocument)
+ |
+ |
+
+
+
+@foreach (var item in Model) {
+
+ |
+ @Html.DisplayFor(modelItem => item.Enabled)
+ |
+
+ @Html.DisplayFor(modelItem => item.Name)
+ |
+
+ @Html.DisplayFor(modelItem => item.DisplayName)
+ |
+
+ @Html.DisplayFor(modelItem => item.Description)
+ |
+
+ @Html.DisplayFor(modelItem => item.Required)
+ |
+
+ @Html.DisplayFor(modelItem => item.Emphasize)
+ |
+
+ @Html.DisplayFor(modelItem => item.ShowInDiscoveryDocument)
+ |
+
+ Edit |
+ Details |
+ Delete
+ |
+
+}
+
+
+
+
diff --git a/src/Yavsc.Org/Views/Client/Details.cshtml b/src/Yavsc.Org/Views/Client/Details.cshtml
index 6b36252b..b86615a4 100644
--- a/src/Yavsc.Org/Views/Client/Details.cshtml
+++ b/src/Yavsc.Org/Views/Client/Details.cshtml
@@ -60,7 +60,7 @@
@Html.DisplayNameFor(model => model.AccessTokenType)
- @Html.DisplayFor(model => model.AccessTokenType)
+ @Html.DisplayFor(model => model.AccessTokenType)
diff --git a/src/Yavsc.Org/Views/Client/Index.cshtml b/src/Yavsc.Org/Views/Client/Index.cshtml
index 557631f9..f91f71dc 100644
--- a/src/Yavsc.Org/Views/Client/Index.cshtml
+++ b/src/Yavsc.Org/Views/Client/Index.cshtml
@@ -1,4 +1,4 @@
-@using IdentityServer8.Models
+@using IdentityServer8.Models;
@model IEnumerable
@Localizer["Index"]
@@ -7,77 +7,85 @@
@Localizer["Create New"]
-
-
- |
- @Html.DisplayNameFor(model => model.ClientId)
- |
-
- @Html.DisplayNameFor(model => model.Enabled)
- |
-
- @Html.DisplayNameFor(model => model.ClientName)
- |
-
- @Html.DisplayNameFor(model => model.FrontChannelLogoutUri)
- |
-
- @Html.DisplayNameFor(model => model.RedirectUris)
- |
-
- @Html.DisplayNameFor(model => model.AbsoluteRefreshTokenLifetime)
- |
-
- @Html.DisplayNameFor(model => model.AllowedGrantTypes)
- |
-
- @Html.DisplayNameFor(model => model.AccessTokenType)
- |
- |
-
-
- @foreach (var item in Model)
- {
-
- |
- @Html.DisplayFor(modelItem => item.ClientId)
- |
-
- @Html.DisplayFor(modelItem => item.Enabled)
- |
-
+@foreach (var item in Model)
+{
+
+
+
+ Identifier
+ and activation
+
+
+ -
+ @Html.DisplayNameFor(modelItem => item.ClientName)
+
+ -
@Html.DisplayFor(modelItem => item.ClientName)
-
|
-
- @Html.DisplayFor(modelItem => item.FrontChannelLogoutUri)
- |
-
-
- @foreach (var uri in item.RedirectUris)
- {
- - @uri.RedirectUri
- }
-
- |
-
- @Html.DisplayFor(modelItem => item.AbsoluteRefreshTokenLifetime)
- |
-
-
- @foreach (var t in item.AllowedGrantTypes)
- {
- - @t.GrantType
- }
-
- |
-
+
+
+ @Html.DisplayNameFor(modelItem => item.ClientId)
+
+
+ @Html.DisplayFor(modelItem => item.ClientId)
+
+
+ @Html.DisplayNameFor(modelItem => item.Enabled)
+
+
+ @Html.DisplayFor(modelItem => item.Enabled)
+
+
+
+
+
+
+ Urls
+ login and logout, refresh token
+
+ -
+ @Html.DisplayNameFor(model => model.FrontChannelLogoutUri)
+
+ - @Html.DisplayFor(model => item.FrontChannelLogoutUri)
+
+ - @Html.DisplayNameFor(model => model.RedirectUris)
+ -
+ @foreach (var uri in item.RedirectUris)
+ {
+
- @uri.RedirectUri
+ }
+
+ - @Html.DisplayNameFor(model => model.AbsoluteRefreshTokenLifetime)
+ - @Html.DisplayFor(model => item.AbsoluteRefreshTokenLifetime)
+
+
+
+
+
+
+ Grants
+ and access type
+
+
+ - @Html.DisplayNameFor(model => model.AllowedGrantTypes)
+ - @foreach (var t in item.AllowedGrantTypes)
+ {
+
- @t.GrantType
+ }
+
+
+ -
+ @Html.DisplayNameFor(model => model.AccessTokenType)
+
+ -
@Enum.GetName(typeof(AccessTokenType), item.AccessTokenType)
-
|
-
- Edit |
- Details |
- Delete
- |
-
- }
-
+
+
+
+
+
+ Edit
+ Details
+ Delete
+
+
+}
diff --git a/src/Yavsc.Org/Views/Shared/_Layout.cshtml b/src/Yavsc.Org/Views/Shared/_Layout.cshtml
index aaf974a7..45f6e976 100644
--- a/src/Yavsc.Org/Views/Shared/_Layout.cshtml
+++ b/src/Yavsc.Org/Views/Shared/_Layout.cshtml
@@ -8,7 +8,7 @@
-
+
@@ -36,7 +36,7 @@ background-attachment: fixed;
}
}
@await RenderSectionAsync("subbanner", false)
-