IdentityServer8

This commit is contained in:
Paul Schneider
2025-02-08 20:06:24 +00:00
parent aa71ff8761
commit 96a54aa6bf
47 changed files with 4089 additions and 541 deletions

View File

@ -3,7 +3,7 @@
namespace Yavsc namespace Yavsc
{ {
public interface IBlogPost : ITrackedEntity, IIdentified<long>, IRating<long>, ITitle public interface IBlogPost : ITrackedEntity, IIdentified<long>, ITitle
{ {
string AuthorId { get; set; } string AuthorId { get; set; }
string Content { get; set; } string Content { get; set; }

View File

@ -3,7 +3,7 @@ namespace Yavsc.Abstract.Identity.Security
public interface ICircleAuthorized public interface ICircleAuthorized
{ {
long Id { get; set; } long Id { get; set; }
string GetOwnerId (); string OwnerId { get; }
bool AuthorizeCircle(long circleId); bool AuthorizeCircle(long circleId);
ICircleAuthorization [] GetACL(); ICircleAuthorization [] GetACL();

View File

@ -1,37 +0,0 @@
//
// IIdentified.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// Copyright (c) 2015 GNU GPL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace Yavsc
{
/// <summary>
/// I rating.
/// </summary>
public interface IRating<TK>: IIdentified<TK>
{
/// <summary>
/// Gets or sets the rate.
/// </summary>
/// <value>The rate.</value>
int Rate { get; set; }
}
}

View File

@ -20,10 +20,6 @@ namespace Yavsc.Models.Blog
[Display(Name="Identifiant du post")] [Display(Name="Identifiant du post")]
public long Id { get; set; } public long Id { get; set; }
[Display(Name="Indice de qualité")]
public int Rate { get; set; }
[Display(Name="Identifiant de l'auteur")] [Display(Name="Identifiant de l'auteur")]
[ForeignKey("Author")] [ForeignKey("Author")]
public string AuthorId { get; set; } public string AuthorId { get; set; }
@ -61,11 +57,6 @@ namespace Yavsc.Models.Blog
return ACL?.Any( i=>i.CircleId == circleId) ?? true; return ACL?.Any( i=>i.CircleId == circleId) ?? true;
} }
public string GetOwnerId()
{
return AuthorId;
}
public ICircleAuthorization[] GetACL() public ICircleAuthorization[] GetACL()
{ {
return ACL.ToArray(); return ACL.ToArray();
@ -93,5 +84,8 @@ namespace Yavsc.Models.Blog
[InverseProperty("Post")] [InverseProperty("Post")]
public virtual List<Comment> Comments { get; set; } public virtual List<Comment> Comments { get; set; }
[NotMapped]
public string OwnerId => AuthorId;
} }
} }

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Yavsc.ViewModels.BlogSpot
{
public class NewPost
{
[Required]
public string Title{ get; set; }
[Required]
public string Content { get; set; }
}
}

View File

@ -27,7 +27,7 @@ namespace Yavsc.Controllers
[HttpGet] [HttpGet]
public IEnumerable<BlogPost> GetBlogspot() public IEnumerable<BlogPost> GetBlogspot()
{ {
return _context.Blogspot.Where(b => b.Visible).OrderByDescending(b => b.UserModified); return _context.BlogSpot.Where(b => b.Visible).OrderByDescending(b => b.UserModified);
} }
// GET: api/BlogApi/5 // GET: api/BlogApi/5
@ -39,7 +39,7 @@ namespace Yavsc.Controllers
return BadRequest(ModelState); return BadRequest(ModelState);
} }
BlogPost blog = _context.Blogspot.Single(m => m.Id == id); BlogPost blog = _context.BlogSpot.Single(m => m.Id == id);
if (blog == null) if (blog == null)
{ {
@ -93,7 +93,7 @@ namespace Yavsc.Controllers
return BadRequest(ModelState); return BadRequest(ModelState);
} }
_context.Blogspot.Add(blog); _context.BlogSpot.Add(blog);
try try
{ {
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
@ -122,13 +122,13 @@ namespace Yavsc.Controllers
return BadRequest(ModelState); return BadRequest(ModelState);
} }
BlogPost blog = _context.Blogspot.Single(m => m.Id == id); BlogPost blog = _context.BlogSpot.Single(m => m.Id == id);
if (blog == null) if (blog == null)
{ {
return NotFound(); return NotFound();
} }
_context.Blogspot.Remove(blog); _context.BlogSpot.Remove(blog);
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
return Ok(blog); return Ok(blog);
@ -145,7 +145,7 @@ namespace Yavsc.Controllers
private bool BlogExists(long id) private bool BlogExists(long id)
{ {
return _context.Blogspot.Count(e => e.Id == id) > 0; return _context.BlogSpot.Count(e => e.Id == id) > 0;
} }
} }
} }

View File

@ -45,7 +45,7 @@ namespace Yavsc.Controllers
{ {
return new BadRequestObjectResult(ModelState); return new BadRequestObjectResult(ModelState);
} }
var article = await _context.Blogspot.FirstOrDefaultAsync var article = await _context.BlogSpot.FirstOrDefaultAsync
(p=> p.Id == post.ReceiverId); (p=> p.Id == post.ReceiverId);
if (article==null) { if (article==null) {

View File

@ -27,7 +27,7 @@ namespace Yavsc.Controllers
return BadRequest(ModelState); return BadRequest(ModelState);
} }
Models.Blog.BlogPost blogpost = _context.Blogspot.Single(x=>x.Id == id); Models.Blog.BlogPost blogpost = _context.BlogSpot.Single(x=>x.Id == id);
if (blogpost == null) if (blogpost == null)
{ {
@ -39,7 +39,6 @@ namespace Yavsc.Controllers
if (!User.IsInRole(Constants.AdminGroupName)) if (!User.IsInRole(Constants.AdminGroupName))
return BadRequest(); return BadRequest();
blogpost.Rate = rate;
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
return Ok(); return Ok();

View File

@ -9,6 +9,7 @@ using Yavsc.Models.Account;
using Yavsc.ViewModels.Account; using Yavsc.ViewModels.Account;
using Yavsc.Helpers; using Yavsc.Helpers;
using Yavsc.Abstract.Identity; using Yavsc.Abstract.Identity;
using System.Diagnostics;
namespace Yavsc.WebApi.Controllers namespace Yavsc.WebApi.Controllers
{ {
@ -129,7 +130,7 @@ namespace Yavsc.WebApi.Controllers
return new BadRequestObjectResult( return new BadRequestObjectResult(
new { error = "user not found" }); new { error = "user not found" });
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var uuid = User.GetUserId();
var userData = await _dbContext.Users var userData = await _dbContext.Users
.Include(u=>u.PostalAddress) .Include(u=>u.PostalAddress)
.Include(u=>u.AccountBalance) .Include(u=>u.AccountBalance)

View File

@ -1,5 +1,6 @@
 
using IdentityServer4.Models; using IdentityServer8;
using IdentityServer8.Models;
using Yavsc.Settings; using Yavsc.Settings;
namespace Yavsc; namespace Yavsc;
@ -65,17 +66,20 @@ public static class Config
// interactive client using code flow + pkce // interactive client using code flow + pkce
new Client new Client
{ {
ClientId = "interactive", ClientId = "mvc",
ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) }, ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
AllowedGrantTypes = GrantTypes.Code, AllowedGrantTypes = GrantTypes.Code,
RedirectUris = { "https://localhost:5003/signin-oidc" }, RedirectUris = { "https://localhost:5003/signin-oidc",
FrontChannelLogoutUri = "https://localhost:5003/signout-oidc", "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" }, PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc" },
AllowOfflineAccess = true, AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "scope2" } AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"scope2" }
}, },
}; };

View File

@ -13,16 +13,16 @@ using Yavsc.ViewModels.Account;
using Yavsc.Helpers; using Yavsc.Helpers;
using Yavsc.Abstract.Manage; using Yavsc.Abstract.Manage;
using Yavsc.Interface; using Yavsc.Interface;
using IdentityServer4.Test; using IdentityServer8.Test;
using IdentityServer4.Services; using IdentityServer8.Services;
using IdentityServer4.Stores; using IdentityServer8.Stores;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Yavsc.Models.Access; using Yavsc.Models.Access;
using IdentityServer4.Models; using IdentityServer8.Models;
using Yavsc.Extensions; using Yavsc.Extensions;
using IdentityServer4.Events; using IdentityServer8.Events;
using IdentityServer4.Extensions; using IdentityServer8.Extensions;
using IdentityServer4; using IdentityServer8;
using IdentityModel; using IdentityModel;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Unicode; using System.Text.Unicode;
@ -278,7 +278,7 @@ namespace Yavsc.Controllers
var context = await _interaction.GetAuthorizationContextAsync(returnUrl); var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null) if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)
{ {
var local = context.IdP == IdentityServer4.IdentityServerConstants.LocalIdentityProvider; var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;
// this is meant to short circuit the UI and only trigger the one external IdP // this is meant to short circuit the UI and only trigger the one external IdP
var vm = new LoginViewModel var vm = new LoginViewModel
@ -380,7 +380,7 @@ namespace Yavsc.Controllers
if (User?.Identity.IsAuthenticated == true) if (User?.Identity.IsAuthenticated == true)
{ {
var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value; var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider) if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)
{ {
var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp); var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);
if (providerSupportsSignout) if (providerSupportsSignout)

View File

@ -93,7 +93,7 @@ namespace Yavsc.Controllers
var user = await GetCurrentUserAsync(); var user = await GetCurrentUserAsync();
long pc = _dbContext.Blogspot.Count(x => x.AuthorId == user.Id); long pc = _dbContext.BlogSpot.Count(x => x.AuthorId == user.Id);

View File

@ -57,7 +57,7 @@ namespace Yavsc.Controllers
{ {
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
ViewData["Title"] = id; ViewData["Title"] = id;
return View("Title", _context.Blogspot.Include( return View("Title", _context.BlogSpot.Include(
b => b.Author b => b.Author
).Where(x => x.Title == id && (x.Visible || x.AuthorId == uid )).OrderByDescending( ).Where(x => x.Title == id && (x.Visible || x.AuthorId == uid )).OrderByDescending(
x => x.DateCreated x => x.DateCreated
@ -78,7 +78,7 @@ namespace Yavsc.Controllers
return NotFound(); return NotFound();
} }
BlogPost blog = _context.Blogspot BlogPost blog = _context.BlogSpot
.Include(p => p.Author) .Include(p => p.Author)
.Include(p => p.Tags) .Include(p => p.Tags)
.Include(p => p.Comments) .Include(p => p.Comments)
@ -128,10 +128,9 @@ namespace Yavsc.Controllers
Title = blogInput.Title, Title = blogInput.Title,
Content = blogInput.Content, Content = blogInput.Content,
Photo = blogInput.Photo, Photo = blogInput.Photo,
Rate = 0,
AuthorId = User.GetUserId() AuthorId = User.GetUserId()
}; };
_context.Blogspot.Add(post); _context.BlogSpot.Add(post);
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
@ -150,7 +149,7 @@ namespace Yavsc.Controllers
} }
ViewData["PostTarget"]="Edit"; ViewData["PostTarget"]="Edit";
BlogPost blog = _context.Blogspot.Include(x => x.Author).Include(x => x.ACL).Single(m => m.Id == id); BlogPost blog = _context.BlogSpot.Include(x => x.Author).Include(x => x.ACL).Single(m => m.Id == id);
if (blog == null) if (blog == null)
{ {
@ -212,7 +211,7 @@ namespace Yavsc.Controllers
return NotFound(); return NotFound();
} }
BlogPost blog = _context.Blogspot.Include( BlogPost blog = _context.BlogSpot.Include(
b => b.Author b => b.Author
).Single(m => m.Id == id); ).Single(m => m.Id == id);
if (blog == null) if (blog == null)
@ -229,9 +228,9 @@ namespace Yavsc.Controllers
public IActionResult DeleteConfirmed(long id) public IActionResult DeleteConfirmed(long id)
{ {
var uid = User.GetUserId(); var uid = User.GetUserId();
BlogPost blog = _context.Blogspot.Single(m => m.Id == id && m.AuthorId == uid ); BlogPost blog = _context.BlogSpot.Single(m => m.Id == id && m.AuthorId == uid );
_context.Blogspot.Remove(blog); _context.BlogSpot.Remove(blog);
_context.SaveChanges(User.GetUserId()); _context.SaveChanges(User.GetUserId());
return RedirectToAction("Index"); return RedirectToAction("Index");

View File

@ -47,7 +47,7 @@ namespace Yavsc.Controllers
// GET: Comments/Create // GET: Comments/Create
public IActionResult Create() public IActionResult Create()
{ {
ViewData["ReceiverId"] = new SelectList(_context.Blogspot, "Id", "Post"); ViewData["ReceiverId"] = new SelectList(_context.BlogSpot, "Id", "Post");
return View(); return View();
} }
@ -64,7 +64,7 @@ namespace Yavsc.Controllers
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
ViewData["ReceiverId"] = new SelectList(_context.Blogspot, "Id", "Post", comment.ReceiverId); ViewData["ReceiverId"] = new SelectList(_context.BlogSpot, "Id", "Post", comment.ReceiverId);
return View(comment); return View(comment);
} }
@ -81,7 +81,7 @@ namespace Yavsc.Controllers
{ {
return NotFound(); return NotFound();
} }
ViewData["ReceiverId"] = new SelectList(_context.Blogspot, "Id", "Post", comment.ReceiverId); ViewData["ReceiverId"] = new SelectList(_context.BlogSpot, "Id", "Post", comment.ReceiverId);
return View(comment); return View(comment);
} }
@ -96,7 +96,7 @@ namespace Yavsc.Controllers
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
ViewData["ReceiverId"] = new SelectList(_context.Blogspot, "Id", "Post", comment.ReceiverId); ViewData["ReceiverId"] = new SelectList(_context.BlogSpot, "Id", "Post", comment.ReceiverId);
return View(comment); return View(comment);
} }

View File

@ -2,16 +2,16 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4.Events; using IdentityServer8.Events;
using IdentityServer4.Models; using IdentityServer8.Models;
using IdentityServer4.Services; using IdentityServer8.Services;
using IdentityServer4.Extensions; using IdentityServer8.Extensions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Validation; using IdentityServer8.Validation;
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using Yavsc; using Yavsc;
@ -122,7 +122,7 @@ namespace IdentityServerHost.Quickstart.UI
var scopes = model.ScopesConsented; var scopes = model.ScopesConsented;
if (ConsentOptions.EnableOfflineAccess == false) if (ConsentOptions.EnableOfflineAccess == false)
{ {
scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess); scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);
} }
grantedConsent = new ConsentResponse grantedConsent = new ConsentResponse
@ -210,7 +210,7 @@ namespace IdentityServerHost.Quickstart.UI
} }
if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess) if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)
{ {
apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null)); apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));
} }
vm.ApiScopes = apiScopes; vm.ApiScopes = apiScopes;
@ -253,7 +253,7 @@ namespace IdentityServerHost.Quickstart.UI
{ {
return new ScopeViewModel return new ScopeViewModel
{ {
Value = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess, Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,
DisplayName = ConsentOptions.OfflineAccessDisplayName, DisplayName = ConsentOptions.OfflineAccessDisplayName,
Description = ConsentOptions.OfflineAccessDescription, Description = ConsentOptions.OfflineAccessDescription,
Emphasize = true, Emphasize = true,

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4.Models; using IdentityServer8.Models;
namespace IdentityServerHost.Quickstart.UI namespace IdentityServerHost.Quickstart.UI
{ {

View File

@ -6,12 +6,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Configuration; using IdentityServer8.Configuration;
using IdentityServer4.Events; using IdentityServer8.Events;
using IdentityServer4.Extensions; using IdentityServer8.Extensions;
using IdentityServer4.Models; using IdentityServer8.Models;
using IdentityServer4.Services; using IdentityServer8.Services;
using IdentityServer4.Validation; using IdentityServer8.Validation;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -103,7 +103,7 @@ namespace Yavsc.Controllers
var scopes = model.ScopesConsented; var scopes = model.ScopesConsented;
if (ConsentOptions.EnableOfflineAccess == false) if (ConsentOptions.EnableOfflineAccess == false)
{ {
scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess); scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);
} }
grantedConsent = new ConsentResponse grantedConsent = new ConsentResponse
@ -185,7 +185,7 @@ namespace Yavsc.Controllers
} }
if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess) if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)
{ {
apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null)); apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));
} }
vm.ApiScopes = apiScopes; vm.ApiScopes = apiScopes;
@ -222,7 +222,7 @@ namespace Yavsc.Controllers
{ {
return new ScopeViewModel return new ScopeViewModel
{ {
Value = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess, Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,
DisplayName = ConsentOptions.OfflineAccessDisplayName, DisplayName = ConsentOptions.OfflineAccessDisplayName,
Description = ConsentOptions.OfflineAccessDescription, Description = ConsentOptions.OfflineAccessDescription,
Emphasize = true, Emphasize = true,

View File

@ -2,15 +2,15 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4.Services; using IdentityServer8.Services;
using IdentityServer4.Stores; using IdentityServer8.Stores;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using IdentityServer4.Events; using IdentityServer8.Events;
using IdentityServer4.Extensions; using IdentityServer8.Extensions;
using Yavsc; using Yavsc;
using Yavsc.Models.Access; using Yavsc.Models.Access;

View File

@ -14,6 +14,7 @@ namespace Yavsc
var result = context.Result; var result = context.Result;
if (result is ViewResult) if (result is ViewResult)
{ {
#pragma warning disable ASP0019 // Suggest using IHeaderDictionary.Append or the indexer
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Type-Options")) if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Type-Options"))
{ {
@ -50,6 +51,8 @@ namespace Yavsc
{ {
context.HttpContext.Response.Headers.Add("Referrer-Policy", referrer_policy); context.HttpContext.Response.Headers.Add("Referrer-Policy", referrer_policy);
} }
#pragma warning restore ASP0019 // Suggest using IHeaderDictionary.Append or the indexer
} }
} }
} }

View File

@ -1,39 +0,0 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Yavsc.Extensions {
public static class AppBuilderExtensions {
public static IApplicationBuilder UseWhen(this IApplicationBuilder app,
Func<HttpContext, bool> condition, Action<IApplicationBuilder> configuration) {
if (app == null) {
throw new ArgumentNullException(nameof(app));
}
if (condition == null) {
throw new ArgumentNullException(nameof(condition));
}
if (configuration == null) {
throw new ArgumentNullException(nameof(configuration));
}
var builder = app.New();
configuration(builder);
return app.Use(next => {
builder.Run(next);
var branch = builder.Build();
return context => {
if (condition(context)) {
return branch(context);
}
return next(context);
};
});
}
}
}

View File

@ -1,4 +1,4 @@
using IdentityServer4.Models; using IdentityServer8.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Yavsc.Models.Access; using Yavsc.Models.Access;

View File

@ -1,6 +1,7 @@
using System.Globalization; using System.Globalization;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Util.Store; using Google.Apis.Util.Store;
using IdentityServer4; using IdentityServer8;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
@ -12,6 +13,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Newtonsoft.Json; using Newtonsoft.Json;
using Yavsc.Abstract.Workflow; using Yavsc.Abstract.Workflow;
@ -107,24 +109,24 @@ internal static class HostingExtensions
} }
} }
RegisterBilling<HairCutQuery>(BillingCodes.Brush, new Func<ApplicationDbContext,long,IDecidableQuery> RegisterBilling<HairCutQuery>(BillingCodes.Brush, new Func<ApplicationDbContext, long, IDecidableQuery>
( ( db, id) => ((db, id) =>
{ {
var query = db.HairCutQueries.Include(q=>q.Prestation).Include(q=>q.Regularisation).Single(q=>q.Id == id) ; var query = db.HairCutQueries.Include(q => q.Prestation).Include(q => q.Regularisation).Single(q => q.Id == id);
query.SelectedProfile = db.BrusherProfile.Single(b=>b.UserId == query.PerformerId); query.SelectedProfile = db.BrusherProfile.Single(b => b.UserId == query.PerformerId);
return query; return query;
})) ; }));
RegisterBilling<HairMultiCutQuery>(BillingCodes.MBrush,new Func<ApplicationDbContext,long,IDecidableQuery> RegisterBilling<HairMultiCutQuery>(BillingCodes.MBrush, new Func<ApplicationDbContext, long, IDecidableQuery>
( (db, id) => db.HairMultiCutQueries.Include(q=>q.Regularisation).Single(q=>q.Id == id))); ((db, id) => db.HairMultiCutQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
RegisterBilling<RdvQuery>(BillingCodes.Rdv, new Func<ApplicationDbContext,long,IDecidableQuery> RegisterBilling<RdvQuery>(BillingCodes.Rdv, new Func<ApplicationDbContext, long, IDecidableQuery>
( (db, id) => db.RdvQueries.Include(q=>q.Regularisation).Single(q=>q.Id == id))); ((db, id) => db.RdvQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
} }
public static void RegisterBilling<T>(string code, Func<ApplicationDbContext,long,IDecidableQuery> getter) where T : IBillable public static void RegisterBilling<T>(string code, Func<ApplicationDbContext, long, IDecidableQuery> getter) where T : IBillable
{ {
BillingService.Billing.Add(code,getter) ; BillingService.Billing.Add(code, getter);
BillingService.GlobalBillingMap.Add(typeof(T).Name,code); BillingService.GlobalBillingMap.Add(typeof(T).Name, code);
} }
public static WebApplication ConfigureServices(this WebApplicationBuilder builder) public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
@ -175,8 +177,7 @@ internal static class HostingExtensions
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
var identityServerBuilder = services.AddIdentityServer(options =>
services.AddIdentityServer(options =>
{ {
options.Events.RaiseErrorEvents = true; options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true; options.Events.RaiseInformationEvents = true;
@ -187,18 +188,30 @@ internal static class HostingExtensions
options.EmitStaticAudienceClaim = true; options.EmitStaticAudienceClaim = true;
}) })
.AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients) .AddInMemoryClients(Config.Clients)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddAspNetIdentity<ApplicationUser>() .AddAspNetIdentity<ApplicationUser>()
; ;
if (builder.Environment.IsDevelopment())
{
identityServerBuilder.AddDeveloperSigningCredential();
}
else
{
var key = builder.Configuration["YOUR-KEY-NAME"];
var pfxBytes = Convert.FromBase64String(key);
var cert = new X509Certificate2(pfxBytes, (string)null, X509KeyStorageFlags.MachineKeySet);
identityServerBuilder.AddSigningCredential(cert);
}
services.AddSession(); services.AddSession();
// TODO .AddServerSideSessionStore<YavscServerSideSessionStore>() // TODO .AddServerSideSessionStore<YavscServerSideSessionStore>()
services.AddAuthentication() var authenticationBuilder = services.AddAuthentication();
.AddGoogle(options => authenticationBuilder.AddGoogle(options =>
{ {
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
@ -208,6 +221,7 @@ internal static class HostingExtensions
options.ClientId = googleClientId; options.ClientId = googleClientId;
options.ClientSecret = googleClientSecret; options.ClientSecret = googleClientSecret;
}); });
services.Configure<RequestLocalizationOptions>(options => services.Configure<RequestLocalizationOptions>(options =>
{ {
CultureInfo[] supportedCultures = new[] CultureInfo[] supportedCultures = new[]
@ -355,7 +369,7 @@ internal static class HostingExtensions
var localization = services.GetRequiredService<IStringLocalizer<YavscLocalization>>(); var localization = services.GetRequiredService<IStringLocalizer<YavscLocalization>>();
Startup.Configure(app, siteSettings, smtpSettings, authorizationService, Startup.Configure(app, siteSettings, smtpSettings, authorizationService,
payPalSettings, googleAuthSettings, localization, loggerFactory, payPalSettings, googleAuthSettings, localization, loggerFactory,
app.Environment.EnvironmentName ); app.Environment.EnvironmentName);
app.ConfigureFileServerApp(); app.ConfigureFileServerApp();
return app; return app;

View File

@ -1,6 +1,6 @@
using System.Security.Claims; using System.Security.Claims;
using IdentityServer4; using IdentityServer8;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;

View File

@ -29,7 +29,7 @@ namespace Yavsc.Helpers
{ {
if (readerId == null) if (readerId == null)
{ {
var userPosts = dbContext.Blogspot.Include( var userPosts = dbContext.BlogSpot.Include(
b => b.Author b => b.Author
).Where(x => ((x.AuthorId == posterId) && (x.Visible))).ToArray(); ).Where(x => ((x.AuthorId == posterId) && (x.Visible))).ToArray();
return userPosts; return userPosts;
@ -40,7 +40,7 @@ namespace Yavsc.Helpers
dbContext.Circle.Include(c => c.Members) dbContext.Circle.Include(c => c.Members)
.Where(c => c.Members.Any(m => m.MemberId == readerId)) .Where(c => c.Members.Any(m => m.MemberId == readerId))
.Select(c => c.Id).ToArray(); .Select(c => c.Id).ToArray();
return dbContext.Blogspot.Include( return dbContext.BlogSpot.Include(
b => b.Author b => b.Author
).Include(p => p.ACL).Where(x => x.Author.Id == posterId && ).Include(p => p.ACL).Where(x => x.Author.Id == posterId &&
(x.Visible && (x.Visible &&

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Yavsc.Migrations
{
/// <inheritdoc />
public partial class blogspotcase : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Blogspot_AspNetUsers_AuthorId",
table: "Blogspot");
migrationBuilder.DropForeignKey(
name: "FK_BlogTag_Blogspot_PostId",
table: "BlogTag");
migrationBuilder.DropForeignKey(
name: "FK_CircleAuthorizationToBlogPost_Blogspot_BlogPostId",
table: "CircleAuthorizationToBlogPost");
migrationBuilder.DropForeignKey(
name: "FK_Comment_Blogspot_ReceiverId",
table: "Comment");
migrationBuilder.DropPrimaryKey(
name: "PK_Blogspot",
table: "Blogspot");
migrationBuilder.DropColumn(
name: "Rate",
table: "Blogspot");
migrationBuilder.RenameTable(
name: "Blogspot",
newName: "BlogSpot");
migrationBuilder.RenameIndex(
name: "IX_Blogspot_AuthorId",
table: "BlogSpot",
newName: "IX_BlogSpot_AuthorId");
migrationBuilder.AddPrimaryKey(
name: "PK_BlogSpot",
table: "BlogSpot",
column: "Id");
migrationBuilder.AddForeignKey(
name: "FK_BlogSpot_AspNetUsers_AuthorId",
table: "BlogSpot",
column: "AuthorId",
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_BlogTag_BlogSpot_PostId",
table: "BlogTag",
column: "PostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_CircleAuthorizationToBlogPost_BlogSpot_BlogPostId",
table: "CircleAuthorizationToBlogPost",
column: "BlogPostId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Comment_BlogSpot_ReceiverId",
table: "Comment",
column: "ReceiverId",
principalTable: "BlogSpot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_BlogSpot_AspNetUsers_AuthorId",
table: "BlogSpot");
migrationBuilder.DropForeignKey(
name: "FK_BlogTag_BlogSpot_PostId",
table: "BlogTag");
migrationBuilder.DropForeignKey(
name: "FK_CircleAuthorizationToBlogPost_BlogSpot_BlogPostId",
table: "CircleAuthorizationToBlogPost");
migrationBuilder.DropForeignKey(
name: "FK_Comment_BlogSpot_ReceiverId",
table: "Comment");
migrationBuilder.DropPrimaryKey(
name: "PK_BlogSpot",
table: "BlogSpot");
migrationBuilder.RenameTable(
name: "BlogSpot",
newName: "Blogspot");
migrationBuilder.RenameIndex(
name: "IX_BlogSpot_AuthorId",
table: "Blogspot",
newName: "IX_Blogspot_AuthorId");
migrationBuilder.AddColumn<int>(
name: "Rate",
table: "Blogspot",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.AddPrimaryKey(
name: "PK_Blogspot",
table: "Blogspot",
column: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Blogspot_AspNetUsers_AuthorId",
table: "Blogspot",
column: "AuthorId",
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_BlogTag_Blogspot_PostId",
table: "BlogTag",
column: "PostId",
principalTable: "Blogspot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_CircleAuthorizationToBlogPost_Blogspot_BlogPostId",
table: "CircleAuthorizationToBlogPost",
column: "BlogPostId",
principalTable: "Blogspot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Comment_Blogspot_ReceiverId",
table: "Comment",
column: "ReceiverId",
principalTable: "Blogspot",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -725,9 +725,6 @@ namespace Yavsc.Migrations
.HasMaxLength(1024) .HasMaxLength(1024)
.HasColumnType("character varying(1024)"); .HasColumnType("character varying(1024)");
b.Property<int>("Rate")
.HasColumnType("integer");
b.Property<string>("Title") b.Property<string>("Title")
.IsRequired() .IsRequired()
.HasMaxLength(1024) .HasMaxLength(1024)
@ -748,7 +745,7 @@ namespace Yavsc.Migrations
b.HasIndex("AuthorId"); b.HasIndex("AuthorId");
b.ToTable("Blogspot"); b.ToTable("BlogSpot");
}); });
modelBuilder.Entity("Yavsc.Models.Blog.BlogTag", b => modelBuilder.Entity("Yavsc.Models.Blog.BlogTag", b =>

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using IdentityServer4.Models; using IdentityServer8.Models;
namespace Yavsc.Models.Access namespace Yavsc.Models.Access
{ {

View File

@ -123,7 +123,7 @@ namespace Yavsc.Models
/// Users posts /// Users posts
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public DbSet<Blog.BlogPost> Blogspot { get; set; } public DbSet<Blog.BlogPost> BlogSpot { get; set; }
/// <summary> /// <summary>
/// Skills powered by this site /// Skills powered by this site

View File

@ -15,6 +15,7 @@ namespace Yavsc
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true) .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.Build(); .Build();
var app = builder.ConfigureServices().ConfigurePipeline(); var app = builder.ConfigureServices().ConfigurePipeline();
app.UseSession(); app.UseSession();
app.Run(); app.Run();

View File

@ -1,6 +1,6 @@
using IdentityServer4.Models; using IdentityServer8.Models;
using IdentityServer4.Stores; using IdentityServer8.Stores;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Yavsc.Models; using Yavsc.Models;

View File

@ -24,7 +24,7 @@ namespace Yavsc.ViewComponents
Where(c=>c.Members.Any(m=>m.MemberId == viewerId)) Where(c=>c.Members.Any(m=>m.MemberId == viewerId))
.Select(c=>c.Id).ToArrayAsync(); .Select(c=>c.Id).ToArrayAsync();
var allposts = _context.Blogspot var allposts = _context.BlogSpot
.Include(b => b.Author) .Include(b => b.Author)
.Include(p=>p.ACL) .Include(p=>p.ACL)
.Include(p=>p.Tags) .Include(p=>p.Tags)

View File

@ -22,7 +22,7 @@ namespace Yavsc.ViewComponents
{ {
if (target!=null) if (target!=null)
{ {
var oid = target.GetOwnerId(); var oid = target.OwnerId;
ViewBag.ACL = dbContext.Circle.Where( ViewBag.ACL = dbContext.Circle.Where(
c=>c.OwnerId == oid) c=>c.OwnerId == oid)
.Select( .Select(

View File

@ -41,12 +41,6 @@
<dd> <dd>
@Html.DisplayFor(model => model.DateCreated) @Html.DisplayFor(model => model.DateCreated)
</dd> </dd>
<dt>
@Html.DisplayNameFor(model => model.Rate)
</dt>
<dd>
@Html.DisplayFor(model => model.Rate)
</dd>
<dt> <dt>
@Html.DisplayNameFor(model => model.Title) @Html.DisplayNameFor(model => model.Title)
</dt> </dt>

View File

@ -25,9 +25,6 @@
<th> <th>
@Html.DisplayNameFor(model => model.UserModified) @Html.DisplayNameFor(model => model.UserModified)
</th> </th>
<th>
@Html.DisplayNameFor(model => model.Rate)
</th>
<th> <th>
@Html.DisplayNameFor(model => model.Title) @Html.DisplayNameFor(model => model.Title)
</th> </th>
@ -57,9 +54,6 @@
<td> <td>
@Html.DisplayFor(modelItem => item.UserModified) @Html.DisplayFor(modelItem => item.UserModified)
</td> </td>
<td>
@Html.DisplayFor(modelItem => item.Rate)
</td>
<td> <td>
@Html.DisplayFor(modelItem => item.Title) @Html.DisplayFor(modelItem => item.Title)
</td> </td>

View File

@ -1,13 +1,13 @@
@using System.Diagnostics @using System.Diagnostics
@{ @{
var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer4.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First(); var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();
} }
<div class="welcome-page"> <div class="welcome-page">
<h1> <h1>
<img src="~/icon.jpg"> <img src="~/icon.jpg">
Welcome to IdentityServer4 Welcome to IdentityServer8
<small class="text-muted">(version @version)</small> <small class="text-muted">(version @version)</small>
</h1> </h1>
@ -25,8 +25,8 @@
</li> </li>
<li> <li>
Here are links to the Here are links to the
<a href="https://github.com/identityserver/IdentityServer4">source code repository</a>, <a href="https://github.com/identityserver/IdentityServer8">source code repository</a>,
and <a href="https://github.com/IdentityServer/IdentityServer4/tree/main/samples">ready to use samples</a>. and <a href="https://github.com/IdentityServer/IdentityServer8/tree/main/samples">ready to use samples</a>.
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -117,7 +117,7 @@ Hello !!!
</li> </li>
<li> <li>
Here are links to the Here are links to the
<a href="https://github.com/identityserver/IdentityServer4">source code repository</a>, <a href="https://github.com/identityserver/IdentityServer8">source code repository</a>,
and <a href="https://github.com/IdentityServer/IdentityServer4/tree/main/samples">ready to use samples</a>. and <a href="https://github.com/IdentityServer/IdentityServer8/tree/main/samples">ready to use samples</a>.
</li> </li>
</ul> </ul>

View File

@ -12,24 +12,25 @@
<PackageReference Include="bootstrap" Version="5.3.3" > <PackageReference Include="bootstrap" Version="5.3.3" >
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="IdentityServer4" Version="4.1.2" /> <PackageReference Include="HigginsSoft.IdentityServer8" Version="8.0.4" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" /> <PackageReference Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.4" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.12">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.12" IncludeAssets="All" />
<PackageReference Include="Google.Apis.Compute.v1" Version="1.54.0" /> <PackageReference Include="Google.Apis.Compute.v1" Version="1.54.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" /> <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />
@ -37,11 +38,10 @@
<PackageReference Include="MimeKit" Version="4.3.0" /> <PackageReference Include="MimeKit" Version="4.3.0" />
<PackageReference Include="pazof.rules" Version="1.1.3" /> <PackageReference Include="pazof.rules" Version="1.1.3" />
<PackageReference Include="RazorEngine.NetCore" Version="3.1.0" /> <PackageReference Include="RazorEngine.NetCore" Version="3.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.0" /> <PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.2" IncludeAssets="All" />
<PackageReference Include="AsciiDocNet" Version="1.0.0-alpha6" /> <PackageReference Include="AsciiDocNet" Version="1.0.0-alpha6" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />

View File

@ -15,7 +15,7 @@
"Title": "Yavsc", "Title": "Yavsc",
"Slogan": "Yavsc!", "Slogan": "Yavsc!",
"StyleSheet": "/css/default.css", "StyleSheet": "/css/default.css",
"Authority": "http://127.0.0.1:5000/", "Authority": "https://127.0.0.1:5001/",
"Owner": { "Owner": {
"Name": "[Site owner's name]", "Name": "[Site owner's name]",
"EMail": "[Site owner's e-mail address]" "EMail": "[Site owner's e-mail address]"

View File

@ -12,13 +12,13 @@ using Microsoft.AspNetCore.Mvc;
// But, this redirect URI doesn't need to match the OAuth parameter, it's serialized in the query state, // But, this redirect URI doesn't need to match the OAuth parameter, it's serialized in the query state,
// to be used once the identification ends. // to be used once the identification ends.
var properties = new AuthenticationProperties { RedirectUri = returnUrl }; var properties = new AuthenticationProperties { RedirectUri = returnUrl };
return new ChallengeResult("Bearer", properties); return new ChallengeResult("Yavsc", properties);
} }
[HttpGet("~/signout")] [HttpGet("~/signout")]
public async Task<IActionResult> SignOut(string returnUrl="/") { public async Task<IActionResult> SignOut(string returnUrl="/") {
await HttpContext.SignOutAsync("Bearer"); await HttpContext.SignOutAsync("Yavsc");
return Redirect(returnUrl); return Redirect(returnUrl);
} }
} }

View File

@ -36,123 +36,38 @@ namespace testOauthClient.Controllers
return View(); return View();
} }
public async Task<IActionResult> CallApi()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var content = await client.GetStringAsync("https://localhost:5001/api/me");
ViewBag.Json = content;
return View("json");
}
[HttpPost] [HttpPost]
public async Task<IActionResult> GetUserInfo(CancellationToken cancellationToken) public async Task<IActionResult> GetUserInfo(CancellationToken cancellationToken)
{ {
var accessToken = await HttpContext.GetTokenAsync("access_token");
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
var request = new HttpRequestMessage(HttpMethod.Get, "http://dev.pschneider.fr/api/me"); var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:5001/api/me");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await client.SendAsync(request, cancellationToken); var response = await client.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
return View("Index", model: await response.Content.ReadAsStringAsync()); return View("UserInfo", model: await response.Content.ReadAsStringAsync());
} }
} }
#if FALSECODE
[HttpPost]
public async Task<IActionResult> PostFiles(string subdir)
{
string results;
_logger.LogInformation($"{Request.Form.Files.Count} file(s) to send");
// TODO better uri construction in production environment
List<FormFile> args = new List<FormFile>();
foreach (var formFile in Request.Form.Files)
{
_logger.LogWarning($"Treating {formFile.ContentDisposition}");
MemoryStream memStream = new MemoryStream();
const int sz = 1024 * 64;
byte[] buffer = new byte[sz];
using (var innerStream = formFile.OpenReadStream())
{
int szRead = 0;
do
{
szRead = innerStream.Read(buffer, 0, sz);
memStream.Write(buffer, 0, szRead);
} while (szRead > 0);
}
memStream.Seek(0, SeekOrigin.Begin);
args.Add(
new FormFile(memStream, 0, formFile.Length, formFile.Name, formFile.Name )
{
ContentDisposition = formFile.ContentDisposition,
ContentType = formFile.ContentType
});
}
string uri = "http://dev.pschneider.fr/api/fs/" + System.Uri.EscapeDataString(subdir);
_logger.LogInformation($"Posting data to '{uri}'...");
results = await RequestHelper.PostMultipart(uri, args.ToArray(), AccessToken);
_logger.LogInformation("Data posted.");
return View("Index", model: results);
}
[HttpPost]
public async Task<IActionResult> PostDeviceInfo(CancellationToken cancellationToken)
{
/*
using (var client = new HttpClient()) {
var request = new HttpRequestMessage(HttpMethod.Post, "http://dev.pschneider.fr/api/gcm/register");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
var json = JsonConvert.
SerializeObject(new Yavsc.Models.Identity.GoogleCloudMobileDeclaration { DeviceId= "devid01", GCMRegistrationId = "1234" } );
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();
return View("Index", model: await response.Content.ReadAsStringAsync());
}*/
GCMRegistrationRecord result = null;
var authHeader = $"Bearer {AccessToken}";
_logger.LogWarning($"using authorization Header {authHeader}");
try
{
using (var request = new SimpleJsonPostMethod(
"http://dev.pschneider.fr/api/gcm/register", authHeader))
{
result = await request.Invoke<GCMRegistrationRecord>(new
GCMRegistrationRecord
{
GCMRegistrationId = "testGoogleRegistrationIdValue",
DeviceId = "TestDeviceId",
Model = "TestModel",
Platform = "External Web",
Version = "0.0.1-rc1"
});
}
}
catch (Exception ex)
{
return View("Index", model: new { error = ex.Message });
}
return View("Index", model: result?.ToString());
}
#endif
protected string AccessToken
{
get
{
var claim = HttpContext.User?.FindFirst("access_token");
if (claim == null)
{
throw new InvalidOperationException("no access_token");
}
return claim.Value;
}
}
public IActionResult About() public IActionResult About()
{ {
ViewData["Message"] = "Your application description page."; ViewData["Message"] = "Your application description page.";
@ -167,18 +82,6 @@ namespace testOauthClient.Controllers
return View(); return View();
} }
public async Task<IActionResult> CallApi()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var content = await client.GetStringAsync("https://localhost:6001/identity");
ViewBag.Json = JArray.Parse(content).ToString();
return View("json");
}
public IActionResult Logout() public IActionResult Logout()
{ {
return SignOut("Cookies", "oidc"); return SignOut("Cookies", "oidc");

View File

@ -22,7 +22,7 @@ using System.IdentityModel.Tokens.Jwt;
{ {
options.Authority = "https://localhost:5001"; options.Authority = "https://localhost:5001";
options.ClientId = "interactive"; options.ClientId = "mvc";
options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0"; options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
options.ResponseType = "code"; options.ResponseType = "code";

View File

@ -2,6 +2,27 @@
@{ @{
ViewData["Title"] = "Home Page"; ViewData["Title"] = "Home Page";
} }
@using Microsoft.AspNetCore.Authentication
<h2>Claims</h2>
<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
<h2>Properties</h2>
<dl>
@foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)
{
<dt>@prop.Key</dt>
<dd>@prop.Value</dd>
}
</dl>
<div class="jumbotron"> <div class="jumbotron">
@if (User?.Identity?.IsAuthenticated ?? false) { @if (User?.Identity?.IsAuthenticated ?? false) {

View File

@ -0,0 +1,7 @@
@model string
@{
ViewData["Title"] = "User Info";
}
<h2>@ViewData["Title"].</h2>
<code>@Model</code>

View File

@ -0,0 +1 @@
<pre>@ViewBag.Json</pre>

View File

@ -6,18 +6,13 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Authentication": {
"Yavsc" : {
"TokenEndpoint": "http://dev.pschneider.fr/connect/token",
"AuthorizationEndpoint": "http://dev.pschneider.fr/connect/authorize",
"ClientId": "interactive",
"ClientSecret": "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0"
}
},
"Kestrel": { "Kestrel": {
"Endpoints": "Endpoints":
{ {
"http": { "Http": {
"Url": "http://localhost:5002"
},
"Https": {
"Url": "https://localhost:5003" "Url": "https://localhost:5003"
} }
} }

View File

@ -1,13 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" /> <ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityModel.AspNetCore" Version="4.3.0" /> <PackageReference Include="IdentityModel.AspNetCore" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Update="Views\Shared\Json.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
</Project> </Project>