misc
Some checks failed
Dotnet build and test / log-the-inputs (push) Successful in 9s
Dotnet build and test / build (push) Failing after 1m33s

This commit is contained in:
Paul Schneider
2025-07-07 07:49:18 +01:00
parent 15d35e5508
commit e6f8947c08
36 changed files with 328 additions and 146 deletions

26
.vscode/launch.json vendored
View File

@ -4,6 +4,32 @@
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "C#: sampleWebAsWebApiClient Debug",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/src/sampleWebAsWebApiClient/sampleWebAsWebApiClient.csproj"
},
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/<target-framework>/<project-name.dll>",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
/* { /* {

6
.vscode/tasks.json vendored
View File

@ -9,8 +9,12 @@
"args": [ "args": [
"build", "build",
"/property:GenerateFullPaths=true", "/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign" "/consoleloggerparameters:NoSummary;ForceNoAlign",
], ],
"group": "build",
"isBuildCommand": true,
"isTestCommand": false,
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{ {

View File

@ -111,9 +111,9 @@ namespace Yavsc.ApiControllers
var user = dbContext.Users.Single( var user = dbContext.Users.Single(
u => u.Id == uid u => u.Id == uid
); );
var info = user.MoveUserFileToDir(query.id, query.to); var info = user.MoveUserFileToDir(query.Id, query.To);
if (!info.Done) return new BadRequestObjectResult(info); if (!info.Done) return new BadRequestObjectResult(info);
return Ok(new { moved = query.id }); return Ok(new { moved = query.Id });
} }
[HttpPost] [HttpPost]
@ -124,21 +124,21 @@ namespace Yavsc.ApiControllers
if (!ModelState.IsValid) { if (!ModelState.IsValid) {
var idvr = new ValidRemoteUserFilePathAttribute(); var idvr = new ValidRemoteUserFilePathAttribute();
return this.BadRequest(new { id = idvr.IsValid(query.id), to = idvr.IsValid(query.to), errors = ModelState }); return this.BadRequest(new { id = idvr.IsValid(query.Id), to = idvr.IsValid(query.To), errors = ModelState });
} }
_logger.LogInformation($"Valid move query: {query.id} => {query.to}"); _logger.LogInformation($"Valid move query: {query.Id} => {query.To}");
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = dbContext.Users.Single( var user = dbContext.Users.Single(
u => u.Id == uid u => u.Id == uid
); );
try { try {
if (Config.UserFilesOptions.FileProvider.GetFileInfo(Path.Combine(user.UserName, query.id)).Exists) if (Config.UserFilesOptions.FileProvider.GetFileInfo(Path.Combine(user.UserName, query.Id)).Exists)
{ {
var result = user.MoveUserFile(query.id, query.to); var result = user.MoveUserFile(query.Id, query.To);
if (!result.Done) return new BadRequestObjectResult(result); if (!result.Done) return new BadRequestObjectResult(result);
} }
else { else {
var result = user.MoveUserDir(query.id, query.to); var result = user.MoveUserDir(query.Id, query.To);
if (!result.Done) return new BadRequestObjectResult(result); if (!result.Done) return new BadRequestObjectResult(result);
} }
} }

View File

@ -1,23 +1,16 @@
using Yavsc.Attributes.Validation; using Yavsc.Attributes.Validation;
namespace Yavsc.Models.FileSystem namespace Yavsc.Models.FileSystem
{ {
public class RenameFileQuery {
public class MoveFileQuery
{
[ValidRemoteUserFilePath] [ValidRemoteUserFilePath]
[YaStringLength(1, 512)] [YaStringLength(1, 512)]
public string id { get; set; } public required string Id { get; set; }
[YaStringLength(0, 512)] [YaStringLength(0, 512)]
[ValidRemoteUserFilePath] [ValidRemoteUserFilePath]
public string to { get; set; } public required string To { get; set; }
}
public class MoveFileQuery {
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public string id { get; set; }
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public string to { get; set; }
} }
} }

View File

@ -0,0 +1,15 @@
using Yavsc.Attributes.Validation;
namespace Yavsc.Models.FileSystem
{
public class RenameFileQuery
{
[ValidRemoteUserFilePath]
[YaStringLength(1, 512)]
public required string Id { get; set; }
[YaStringLength(0, 512)]
[ValidRemoteUserFilePath]
public required string To { get; set; }
}
}

View File

@ -37,7 +37,7 @@ namespace Yavsc.Controllers
} }
// GET: api/Estimate{?ownerId=User.GetUserId()} // GET: api/Estimate{?ownerId=User.GetUserId()}
[HttpGet] [HttpGet]
public IActionResult GetEstimates(string ownerId = null) public IActionResult GetEstimates(string? ownerId = null)
{ {
if (ownerId == null) ownerId = User.GetUserId(); if (ownerId == null) ownerId = User.GetUserId();
else if (!UserIsAdminOrThis(ownerId)) // throw new Exception("Not authorized") ; else if (!UserIsAdminOrThis(ownerId)) // throw new Exception("Not authorized") ;

View File

@ -32,7 +32,8 @@ public class NativeConfidentialController : Controller
[FromBody] DeviceDeclaration declaration) [FromBody] DeviceDeclaration declaration)
{ {
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier); var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (uid == null)
throw new InvalidOperationException("no name identifier from claims");
if (!ModelState.IsValid) if (!ModelState.IsValid)
{ {
_logger.LogError("Invalid model for GCMD"); _logger.LogError("Invalid model for GCMD");

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using Yavsc.Models; using Yavsc.Models;
using Yavsc.Api.Helpers; using Yavsc.Api.Helpers;
using Yavsc.Server.Helpers; using Yavsc.Server.Helpers;
using System.Diagnostics;
namespace Yavsc.WebApi.Controllers namespace Yavsc.WebApi.Controllers
{ {
@ -30,9 +31,9 @@ namespace Yavsc.WebApi.Controllers
return new BadRequestObjectResult( return new BadRequestObjectResult(
new { error = "user not found" }); new { error = "user not found" });
var uid = User.GetUserId(); var uid = User.GetUserId();
Debug.Assert(uid != null, "uid is null");
var userData = await GetUserData(uid); var userData = await GetUserData(uid);
Debug.Assert(userData != null, "userData is null");
var user = new Yavsc.Models.Auth.Me(userData.Id, userData.UserName, userData.Email, var user = new Yavsc.Models.Auth.Me(userData.Id, userData.UserName, userData.Email,
userData.Avatar, userData.Avatar,
userData.PostalAddress, userData.DedicatedGoogleCalendar); userData.PostalAddress, userData.DedicatedGoogleCalendar);
@ -57,7 +58,7 @@ namespace Yavsc.WebApi.Controllers
[HttpGet("myhost")] [HttpGet("myhost")]
public IActionResult MyHost () public IActionResult MyHost ()
{ {
return Ok(new { host = Request.ForHost() }); return Ok(new { host = Request.ForwardedFor() });
} }

View File

@ -13,8 +13,8 @@ namespace Yavsc.Api.Helpers
public static class RequestHelpers public static class RequestHelpers
{ {
// Check for some apache proxy header, if any // Check for some apache proxy header, if any
public static string ForHost(this HttpRequest request) { public static string? ForwardedFor(this HttpRequest request) {
string host = request.Headers["X-Forwarded-For"]; string? host = request.Headers["X-Forwarded-For"];
if (string.IsNullOrEmpty(host)) { if (string.IsNullOrEmpty(host)) {
host = request.Host.Value; host = request.Host.Value;
} else { // Using X-Forwarded-For last address } else { // Using X-Forwarded-For last address

View File

@ -9,7 +9,7 @@ namespace Yavsc.Api.Helpers
{ {
public static class UserHelpers public static class UserHelpers
{ {
public static string GetUserId(this ClaimsPrincipal user) public static string? GetUserId(this ClaimsPrincipal user)
{ {
return user.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"); return user.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");
} }

View File

@ -11,8 +11,6 @@
*/ */
using IdentityModel; using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Yavsc.Helpers; using Yavsc.Helpers;
@ -63,7 +61,8 @@ internal class Program
options.IncludeErrorDetails = true; options.IncludeErrorDetails = true;
options.Authority = "https://localhost:5001"; options.Authority = "https://localhost:5001";
options.TokenValidationParameters = options.TokenValidationParameters =
new() { ValidateAudience = false }; new() { ValidateAudience = false, RoleClaimType = JwtClaimTypes.Role };
options.MapInboundClaims = true;
}); });
services.AddDbContext<ApplicationDbContext>(options => services.AddDbContext<ApplicationDbContext>(options =>
@ -74,9 +73,9 @@ internal class Program
.AddTransient<ICalendarManager, CalendarManager>(); .AddTransient<ICalendarManager, CalendarManager>();
services.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>(); services.AddTransient<IFileSystemAuthManager, FileSystemAuthManager>();
/* /*
services.AddIdentityApiEndpoints<ApplicationUser>();
services.AddSingleton<IConnexionManager, HubConnectionManager>(); services.AddSingleton<IConnexionManager, HubConnectionManager>();
services.AddSingleton<ILiveProcessor, LiveProcessor>(); services.AddSingleton<ILiveProcessor, LiveProcessor>();
services.AddIdentityApiEndpoints<ApplicationUser>();
services.AddSession(); services.AddSession();
*/ */
WorkflowHelpers.ConfigureBillingService(); WorkflowHelpers.ConfigureBillingService();
@ -106,10 +105,5 @@ internal class Program
// app.UseSession(); // app.UseSession();
await app.RunAsync(); await app.RunAsync();
} }
;
} }
} }

View File

@ -5,14 +5,14 @@ namespace Yavsc
public static class Constants public static class Constants
{ {
public static readonly Scope[] SiteScopes = {  public static readonly Scope[] SiteScopes = {
new Scope { Id = "profile", Description = "Your profile informations" },   new Scope { Id = "profile", Description = "Your profile informations" },
new Scope { Id = "book" , Description ="Your booking interface"},   new Scope { Id = "book" , Description ="Your booking interface"},
new Scope { Id = "blog" , Description ="Your blogging interface"},   new Scope { Id = "blog" , Description ="Your blogging interface"},
new Scope { Id = "estimate" , Description ="Your estimation interface"},   new Scope { Id = "estimate" , Description ="Your estimation interface"},
new Scope { Id = "contract" , Description ="Your contract signature access"},  new Scope { Id = "contract" , Description ="Your contract signature access"},
new Scope { Id = "admin" , Description ="Your administration rights on this site"},  new Scope { Id = "admin" , Description ="Your administration rights on this site"},
new Scope { Id = "moderation" , Description ="Your moderator interface"},  new Scope { Id = "moderation" , Description ="Your moderator interface"},
new Scope { Id = "frontoffice" , Description ="Your front office interface" } new Scope { Id = "frontoffice" , Description ="Your front office interface" }
}; };
@ -54,7 +54,5 @@ namespace Yavsc
public const string LivePath = "/live/cast"; public const string LivePath = "/live/cast";
public const string StreamingPath = "/api/stream/put"; public const string StreamingPath = "/api/stream/put";
public const string RoleClaimName = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
} }
} }

View File

@ -85,7 +85,7 @@ public static class Config
IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email, IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess, IdentityServerConstants.StandardScopes.OfflineAccess,
"scope2" } "scope2" },
}, },
}; };

View File

@ -29,11 +29,13 @@ using Microsoft.Extensions.Localization;
namespace Yavsc namespace Yavsc
{ {
using System.Diagnostics;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Models; using Models;
using Models.Chat; using Models.Chat;
using Yavsc.Abstract.Chat; using Yavsc.Abstract.Chat;
using Yavsc.Helpers;
using Yavsc.Services; using Yavsc.Services;
public partial class ChatHub : Hub, IDisposable public partial class ChatHub : Hub, IDisposable
{ {
@ -192,10 +194,11 @@ namespace Yavsc
NotifyUserInRoom(NotificationTypes.Error, room, "already registered."); NotifyUserInRoom(NotificationTypes.Error, room, "already registered.");
return; return;
} }
string userName = Context.User.Identity.Name; Debug.Assert(Context.User != null);
string userName = Context.User.GetUserName();
var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName); var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName);
var newroom = new ChatRoom { Name = room, OwnerId = user.Id }; var newroom = new ChatRoom { Name = room, OwnerId = Context.User.GetUserId() };
ChatRoomInfo chanInfo; ChatRoomInfo chanInfo;
if (_cxManager.TryGetChanInfo(room, out chanInfo)) if (_cxManager.TryGetChanInfo(room, out chanInfo))
{ {
@ -319,7 +322,7 @@ namespace Yavsc
async Task NotifyUser(string type, string targetId, string message) async Task NotifyUser(string type, string targetId, string message)
{ {
_logger.LogInformation("notifying user {type} {targetId} : {message}"); _logger.LogInformation($"notifying user {type} {targetId} : {message}");
await Clients.Caller.SendAsync("notifyUser", type, targetId, message); await Clients.Caller.SendAsync("notifyUser", type, targetId, message);
} }
@ -331,6 +334,8 @@ namespace Yavsc
[Authorize] [Authorize]
public async Task SendPV(string userName, string message) public async Task SendPV(string userName, string message)
{ {
// Authorized code
Debug.Assert(Context.User != null);
_logger.LogInformation($"Sending pv to {userName}"); _logger.LogInformation($"Sending pv to {userName}");
if (!InputValidator.ValidateUserName(userName)) if (!InputValidator.ValidateUserName(userName))
@ -344,19 +349,21 @@ namespace Yavsc
return ; return ;
} }
_logger.LogInformation($"Message form is validated."); _logger.LogInformation($"Message form is validated.");
var identityUserName = Context.User.GetUserName();
if (userName[0] != '?') if (userName[0] != '?' && Context.User!=null)
if (!Context.User.IsInRole(Constants.AdminGroupName)) if (!Context.User.IsInRole(Constants.AdminGroupName))
{ {
var bl = _dbContext.BlackListed var bl = _dbContext.BlackListed
.Include(r => r.User) .Include(r => r.User)
.Include(r => r.Owner) .Include(r => r.Owner)
.Where(r => r.User.UserName == Context.User.Identity.Name && r.Owner.UserName == userName) .Where(r => r.User.UserName == identityUserName && r.Owner.UserName == userName)
.Select(r => r.OwnerId); .Select(r => r.OwnerId);
if (bl.Count() > 0) if (bl.Count() > 0)
{ {
_logger.LogError($"Black listed : {Context.User.Identity.Name}"); _logger.LogError($"Black listed : {identityUserName}");
await NotifyUser(NotificationTypes.PrivateMessageDenied, userName, "you are black listed."); await NotifyUser(NotificationTypes.PrivateMessageDenied, userName, "you are black listed.");
return; return;
} }
@ -372,7 +379,7 @@ namespace Yavsc
_logger.LogInformation($"cx: {connectionId}"); _logger.LogInformation($"cx: {connectionId}");
var cli = Clients.Client(connectionId); var cli = Clients.Client(connectionId);
_logger.LogInformation($"cli: {cli.ToString()}"); _logger.LogInformation($"cli: {cli.ToString()}");
await cli.SendAsync("addPV", Context.User.Identity.Name, message); await cli.SendAsync("addPV", identityUserName, message);
_logger.LogInformation($"Sent pv to cx {connectionId}"); _logger.LogInformation($"Sent pv to cx {connectionId}");
} }
} }
@ -380,6 +387,9 @@ namespace Yavsc
[Authorize] [Authorize]
public async Task SendStream(string connectionId, long streamId, string message) public async Task SendStream(string connectionId, long streamId, string message)
{ {
// Authorized code
Debug.Assert(Context.User != null);
Debug.Assert(Context.User.Identity != null);
if (!InputValidator.ValidateMessage(message)) return; if (!InputValidator.ValidateMessage(message)) return;
var sender = Context.User.Identity.Name; var sender = Context.User.Identity.Name;
var cli = Clients.Client(connectionId); var cli = Clients.Client(connectionId);

View File

@ -42,24 +42,24 @@ namespace Yavsc.Models
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[InverseProperty("Author"), JsonIgnore] [InverseProperty("Author"), JsonIgnore]
public virtual List<Blog.BlogPost> Posts { get; set; } public virtual List<Blog.BlogPost>? Posts { get; set; }
/// <summary> /// <summary>
/// User's contact list /// User's contact list
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[InverseProperty("Owner"), JsonIgnore] [InverseProperty("Owner"), JsonIgnore]
public virtual List<Contact> Book { get; set; } public virtual List<Contact>? Book { get; set; }
/// <summary> /// <summary>
/// External devices using the API /// External devices using the API
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[InverseProperty("DeviceOwner"), JsonIgnore] [InverseProperty("DeviceOwner"), JsonIgnore]
public virtual List<DeviceDeclaration> DeviceDeclaration { get; set; } public virtual List<DeviceDeclaration>? DeviceDeclaration { get; set; }
[InverseProperty("Owner"), JsonIgnore] [InverseProperty("Owner"), JsonIgnore]
public virtual List<ChatConnection> Connections { get; set; } public virtual List<ChatConnection>? Connections { get; set; }
/// <summary> /// <summary>
/// User's circles /// User's circles
@ -67,7 +67,7 @@ namespace Yavsc.Models
/// <returns></returns> /// <returns></returns>
[InverseProperty("Owner"), JsonIgnore] [InverseProperty("Owner"), JsonIgnore]
public virtual List<Circle> Circles { get; set; } public virtual List<Circle>? Circles { get; set; }
/// <summary> /// <summary>
/// Billing postal address /// Billing postal address
@ -82,14 +82,14 @@ namespace Yavsc.Models
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[MaxLength(512)] [MaxLength(512)]
public string DedicatedGoogleCalendar { get; set; } public string? DedicatedGoogleCalendar { get; set; }
public override string ToString() public override string ToString()
{ {
return this.Id + " " + this.AccountBalance?.Credits.ToString() + this.Email + " " + this.UserName + " $" + this.AccountBalance?.Credits.ToString(); return this.Id + " " + this.AccountBalance?.Credits.ToString() + this.Email + " " + this.UserName + " $" + this.AccountBalance?.Credits.ToString();
} }
public virtual List<BankIdentity> BankInfo { get; set; } public virtual List<BankIdentity>? BankInfo { get; set; }
public long DiskQuota { get; set; } = 512 * 1024 * 1024; public long DiskQuota { get; set; } = 512 * 1024 * 1024;
public long DiskUsage { get; set; } = 0; public long DiskUsage { get; set; } = 0;
@ -98,21 +98,21 @@ namespace Yavsc.Models
[JsonIgnore] [JsonIgnore]
[InverseProperty("Owner")] [InverseProperty("Owner")]
public virtual List<BlackListed> BlackList { get; set; } public virtual List<BlackListed>? BlackList { get; set; }
public bool AllowMonthlyEmail { get; set; } = false; public bool AllowMonthlyEmail { get; set; } = false;
[JsonIgnore] [JsonIgnore]
[InverseProperty("Owner")] [InverseProperty("Owner")]
public virtual List<ChatRoom> Rooms { get; set; } public virtual List<ChatRoom>? Rooms { get; set; }
[JsonIgnore] [JsonIgnore]
[InverseProperty("User")] [InverseProperty("User")]
public virtual List<ChatRoomAccess> RoomAccess { get; set; } public virtual List<ChatRoomAccess>? RoomAccess { get; set; }
[JsonIgnore] [JsonIgnore]
[InverseProperty("Member")] [InverseProperty("Member")]
public virtual List<CircleMember> Membership { get; set; } public virtual List<CircleMember>? Membership { get; set; }
IAccountBalance? IApplicationUser.AccountBalance => AccountBalance; IAccountBalance? IApplicationUser.AccountBalance => AccountBalance;

View File

@ -0,0 +1,13 @@
using Yavsc.Models.Blog;
public class BlogPostEdition
{
public string Content { get; internal set; }
public string Title { get; internal set; }
public string Photo { get; internal set; }
internal static BlogPostEdition From(BlogPost blog)
{
throw new NotImplementedException();
}
}

View File

@ -25,7 +25,7 @@ public class BlogSpotService
_context = context; _context = context;
} }
public BlogPost Create(string userId, BlogPostBase blogInput) public BlogPost Create(string userId, BlogPostEditViewModel blogInput)
{ {
BlogPost post = new BlogPost BlogPost post = new BlogPost
{ {
@ -38,7 +38,7 @@ public class BlogSpotService
_context.SaveChanges(userId); _context.SaveChanges(userId);
return post; return post;
} }
public async Task<BlogPost> GetPostForEdition(ClaimsPrincipal user, long blogPostId) public async Task<BlogPostEditViewModel> GetPostForEdition(ClaimsPrincipal user, long blogPostId)
{ {
var blog = await _context.BlogSpot.Include(x => x.Author).Include(x => x.ACL).SingleAsync(m => m.Id == blogPostId); var blog = await _context.BlogSpot.Include(x => x.Author).Include(x => x.ACL).SingleAsync(m => m.Id == blogPostId);
var auth = await _authorizationService.AuthorizeAsync(user, blog, new EditPermission()); var auth = await _authorizationService.AuthorizeAsync(user, blog, new EditPermission());
@ -46,7 +46,7 @@ public class BlogSpotService
{ {
throw new AuthorizationFailureException(auth); throw new AuthorizationFailureException(auth);
} }
return blog; return BlogPostEditViewModel.From(blog);
} }
public async Task<BlogPost> Details(ClaimsPrincipal user, long blogPostId) public async Task<BlogPost> Details(ClaimsPrincipal user, long blogPostId)
@ -182,4 +182,12 @@ public class BlogSpotService
x => x.DateCreated x => x.DateCreated
).ToList(); ).ToList();
} }
public async Task<BlogPost?> GetBlogPostAsync(long value)
{
return await _context.BlogSpot
.Include(b => b.Author)
.Include(b => b.ACL)
.SingleOrDefaultAsync(x => x.Id == value);
}
} }

View File

@ -1,13 +1,9 @@
using System.Text;
using System;
using System.Net; using System.Net;
using System.Threading.Tasks;
using MailKit.Net.Smtp; using MailKit.Net.Smtp;
using MailKit.Security; using MailKit.Security;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using MimeKit; using MimeKit;
using Yavsc.Abstract.Manage;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Yavsc.Interface; using Yavsc.Interface;
using Yavsc.Settings; using Yavsc.Settings;
@ -27,8 +23,7 @@ namespace Yavsc.Services
public MailSender( public MailSender(
IOptions<SiteSettings> sitesOptions, IOptions<SiteSettings> sitesOptions,
IOptions<SmtpSettings> smtpOptions, IOptions<SmtpSettings> smtpOptions,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory
IStringLocalizer<Yavsc.YavscLocalization> localizer
) )
{ {
this.localizer = localizer; this.localizer = localizer;

View File

@ -57,7 +57,7 @@ namespace Yavsc.Services
var roles = await this._userManager.GetRolesAsync(user); var roles = await this._userManager.GetRolesAsync(user);
if (roles.Count()>0) if (roles.Count()>0)
{ {
claims.AddRange(roles.Select(r => new Claim(Constants.RoleClaimName, r))); claims.AddRange(roles.Select(r => new Claim(JwtClaimTypes.Role, r)));
} }
} }
return claims; return claims;
@ -66,9 +66,9 @@ namespace Yavsc.Services
public async Task GetProfileDataAsync(ProfileDataRequestContext context) public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{ {
var subjectId = GetSubjectId(context.Subject); var subjectId = GetSubjectId(context.Subject);
if (subjectId==null) return; if (subjectId == null) return;
var user = await _userManager.FindByIdAsync(subjectId); var user = await _userManager.FindByIdAsync(subjectId);
if (user==null) return ; if (user == null) return;
context.IssuedClaims = await GetClaimsFromUserAsync(context, user); context.IssuedClaims = await GetClaimsFromUserAsync(context, user);
} }

View File

@ -21,7 +21,6 @@ namespace Yavsc.ViewModels.Blog
[Display(Name = "Liste de contrôle d'accès")] [Display(Name = "Liste de contrôle d'accès")]
public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; } public virtual List<CircleAuthorizationToBlogPost>? ACL { get; set; }
public bool Publish { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Yavsc.Models.Blog;
namespace Yavsc.ViewModels.Blog; namespace Yavsc.ViewModels.Blog;
@ -8,4 +9,37 @@ public class BlogPostEditViewModel : BlogPostBase
[Required] [Required]
public required long Id { get; set; } public required long Id { get; set; }
public bool Publish { get; set; }
public BlogPostEditViewModel()
{
}
public static BlogPostEditViewModel From(BlogPost blogInput)
{
return new BlogPostEditViewModel
{
Id = blogInput.Id,
Title = blogInput.Title,
Publish = false,
Photo = blogInput.Photo,
Content = blogInput.Content,
ACL = blogInput.ACL
};
}
public static BlogPostEditViewModel FromViewModel(BlogPostEditViewModel blogInput)
{
return new BlogPostEditViewModel
{
Id = blogInput.Id,
Title = blogInput.Title,
Publish = false,
Photo = blogInput.Photo,
Content = blogInput.Content,
ACL = blogInput.ACL
};
}
} }

View File

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
<PackageReference Include="HigginsSoft.IdentityServer8" Version="8.0.4" /> <PackageReference Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" /> <PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
@ -19,20 +19,14 @@
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.6" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageReference Include="Google.Apis.Calendar.v3" Version="1.60.0.2993" /> <PackageReference Include="Google.Apis.Calendar.v3" Version="1.69.0.3746" />
<PackageReference Include="PayPalMerchantSDK" Version="2.16.250" /> <PackageReference Include="PayPalMerchantSDK" Version="2.16.250" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
<PackageReference Include="RazorEngine.NetCore" Version="3.1.0" /> <PackageReference Include="RazorEngine.NetCore" Version="3.1.0" />
<PackageReference Include="MailKit" Version="4.12.1" /> <PackageReference Include="MailKit" Version="4.13.0" />
<PackageReference Include="MimeKit" Version="4.12.0" /> <PackageReference Include="MimeKit" Version="4.13.0" />
<PackageReference Include="pazof.rules" Version="1.1.3" /> <PackageReference Include="pazof.rules" Version="1.1.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Xml" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" /> <ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -69,12 +69,19 @@ namespace Yavsc.Controllers
public async Task<IActionResult> Details(long? id) public async Task<IActionResult> Details(long? id)
{ {
if (id == null) return this.NotFound(); if (id == null) return this.NotFound();
try
{
var blog = await blogSpotService.Details(User, id.Value); var blog = await blogSpotService.Details(User, id.Value);
ViewData["apicmtctlr"] = "/api/blogcomments"; ViewData["apicmtctlr"] = "/api/blogcomments";
ViewData["moderatoFlag"] = User.IsInRole(Constants.BlogModeratorGroupName); ViewData["moderatoFlag"] = User.IsInRole(Constants.BlogModeratorGroupName);
return View(blog); return View(blog);
}
catch (AuthorizationFailureException ex)
{
return Challenge();
}
} }
void SetLangItems() void SetLangItems()
{ {
@ -98,12 +105,12 @@ namespace Yavsc.Controllers
// POST: Blog/Create // POST: Blog/Create
[HttpPost, Authorize, ValidateAntiForgeryToken] [HttpPost, Authorize, ValidateAntiForgeryToken]
public IActionResult Create(BlogPostBase blogInput) public IActionResult Create(BlogPostEditViewModel blogInput)
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
BlogPost post = blogSpotService.Create(User.GetUserId(), BlogPost post = blogSpotService.Create(User.GetUserId(),
blogInput); BlogPostEditViewModel.FromViewModel(blogInput));
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
return View("Edit", blogInput); return View("Edit", blogInput);
@ -119,20 +126,13 @@ namespace Yavsc.Controllers
} }
try try
{ {
BlogPost blog = await blogSpotService.GetPostForEdition(User, id.Value); var blog = await blogSpotService.GetPostForEdition(User, id.Value);
if (blog == null) if (blog == null)
{ {
return NotFound(); return NotFound();
} }
SetLangItems(); SetLangItems();
return View(new BlogPostEditViewModel return View(blog);
{
Id = blog.Id,
Title = blog.Title,
Content = blog.Content,
ACL = blog.ACL,
Photo = blog.Photo
});
} }
catch (AuthorizationFailureException) catch (AuthorizationFailureException)
@ -164,7 +164,7 @@ namespace Yavsc.Controllers
return NotFound(); return NotFound();
} }
BlogPost blog = await blogSpotService.GetPostForEdition(User, id.Value); var blog = await blogSpotService.GetBlogPostAsync(id.Value);
if (blog == null) if (blog == null)
{ {
return NotFound(); return NotFound();

View File

@ -33,12 +33,16 @@ using Yavsc.Server.Helpers;
using System.Security.Cryptography; using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Protocols.Configuration; using Microsoft.IdentityModel.Protocols.Configuration;
using IdentityModel;
using System.Security.Claims;
using IdentityServer8.Security;
namespace Yavsc.Extensions; namespace Yavsc.Extensions;
public static class HostingExtensions public static class HostingExtensions
{ {
public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app, public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app,
bool enableDirectoryBrowsing = false) bool enableDirectoryBrowsing = false)
{ {
@ -191,11 +195,13 @@ public static class HostingExtensions
{ {
policy policy
.RequireAuthenticatedUser() .RequireAuthenticatedUser()
.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "Performer"); .RequireClaim(JwtClaimTypes.Role, "Performer");
}); });
options.AddPolicy("AdministratorOnly", policy => options.AddPolicy("AdministratorOnly", policy =>
{ {
_ = policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName); _ = policy
.RequireAuthenticatedUser()
.RequireClaim(JwtClaimTypes.Role, Constants.AdminGroupName);
}); });
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName)); options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
@ -284,12 +290,13 @@ public static class HostingExtensions
// see https://IdentityServer8.readthedocs.io/en/latest/topics/resources.html // see https://IdentityServer8.readthedocs.io/en/latest/topics/resources.html
options.EmitStaticAudienceClaim = true; options.EmitStaticAudienceClaim = true;
}) })
.AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryClients(Config.Clients) .AddInMemoryClients(Config.Clients)
.AddInMemoryApiScopes(Config.ApiScopes) .AddInMemoryApiScopes(Config.ApiScopes)
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>() .AddProfileService<ProfileService>()
.AddAspNetIdentity<ApplicationUser>()
; ;
if (builder.Environment.IsDevelopment()) if (builder.Environment.IsDevelopment())
{ {
@ -372,7 +379,7 @@ public static class HostingExtensions
app.UseAuthorization(); app.UseAuthorization();
app.UseCors("default"); app.UseCors("default");
app.MapDefaultControllerRoute(); app.MapDefaultControllerRoute();
//pp.MapRazorPages(); //app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub"); app.MapHub<ChatHub>("/chatHub");
WorkflowHelpers.ConfigureBillingService(); WorkflowHelpers.ConfigureBillingService();
@ -408,3 +415,86 @@ public static class HostingExtensions
} }
} }
} }
public class MyIdentityStore : IUserClaimStore<IdentityUser>
{
public Task AddClaimsAsync(IdentityUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> CreateAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> DeleteAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
public Task<IdentityUser?> FindByIdAsync(string userId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityUser?> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IList<Claim>> GetClaimsAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string?> GetNormalizedUserNameAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string> GetUserIdAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<string?> GetUserNameAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IList<IdentityUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task RemoveClaimsAsync(IdentityUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task ReplaceClaimAsync(IdentityUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetNormalizedUserNameAsync(IdentityUser user, string? normalizedName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task SetUserNameAsync(IdentityUser user, string? userName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<IdentityResult> UpdateAsync(IdentityUser user, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using RazorEngine.Compilation.ImpromptuInterface.Optimization; using RazorEngine.Compilation.ImpromptuInterface.Optimization;
using Yavsc.Helpers; using Yavsc.Helpers;
using Yavsc.Migrations;
using Yavsc.Models; using Yavsc.Models;
using Yavsc.Models.Blog; using Yavsc.Models.Blog;
using Yavsc.ViewModels.Auth; using Yavsc.ViewModels.Auth;
@ -33,6 +34,10 @@ public class PermissionHandler : IAuthorizationHandler
{ {
context.Succeed(requirement); context.Succeed(requirement);
} }
else if (context.User.IsInRole("Administrator"))
{
context.Succeed(requirement);
}
} }
else if (requirement is EditPermission || requirement is DeletePermission) else if (requirement is EditPermission || requirement is DeletePermission)
{ {

View File

@ -20,11 +20,11 @@ install_service:
sudo systemctl enable yavsc sudo systemctl enable yavsc
pushInProd: publish pushInProd: publish
sudo systemctl stop $(SERVICE_PROD) @sudo systemctl stop $(SERVICE_PROD)
sudo cp -a bin/$(CONFIGURATION)/$(DOTNET_FRAMEWORK)/publish/* $(DESTDIR) @sudo cp -a bin/$(CONFIGURATION)/$(DOTNET_FRAMEWORK)/publish/* $(DESTDIR)
sudo chown -R $(USER_AND_GROUP) $(DESTDIR) @sudo chown -R $(USER_AND_GROUP) $(DESTDIR)
sudo sync @sudo sync
sudo systemctl start $(SERVICE_PROD) @sudo systemctl start $(SERVICE_PROD)
%.min.js: %.js %.min.js: %.js
jsmin < $^ > $@ jsmin < $^ > $@

View File

@ -1,7 +1,5 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Yavsc.Helpers;
using Yavsc.Server.Helpers; using Yavsc.Server.Helpers;
using Yavsc.Settings; using Yavsc.Settings;

View File

@ -1,4 +1,4 @@
@model Yavsc.ViewModels.Blog.BlogPostBase @model BlogPostEditViewModel
@{ @{
ViewData["Title"] = "Blog post edition"; ViewData["Title"] = "Blog post edition";

View File

@ -10,14 +10,15 @@
<PackageReference Include="popper.js" Version="1.16.1"> <PackageReference Include="popper.js" Version="1.16.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="bootstrap" Version="5.3.3"> <PackageReference Include="bootstrap" Version="5.3.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.4" /> <PackageReference Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" />
<PackageReference Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.5-preview-net9" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.6"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.6">
@ -30,15 +31,15 @@
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.6" />
<PackageReference Include="Google.Apis.Compute.v1" Version="1.54.0" /> <PackageReference Include="Google.Apis.Compute.v1" Version="1.70.0.3829" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" /> <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.3.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.6" /> <PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.4" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.1" />
<PackageReference Include="AsciiDocNet" Version="1.0.0-alpha6" /> <PackageReference Include="AsciiDocNet" Version="1.0.0-alpha6" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -35,3 +35,9 @@ img.blogphoto {
padding: .3em; padding: .3em;
border: solid black 1px; border: solid black 1px;
} }
input[type='checkbox'] {
appearance: auto;
min-width: 1em;
min-height: 1em;
}

View File

@ -10,7 +10,6 @@
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size); @include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight}; --#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$prefix}nav-link-color: #{$nav-link-color}; --#{$prefix}nav-link-color: #{$nav-link-color};
--#{$prefix}nav-link-background-color: #{$dropdown-dark-bg};
--#{$prefix}nav-link-hover-color: #{$nav-link-hover-color}; --#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
--#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color}; --#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
// scss-docs-end nav-css-vars // scss-docs-end nav-css-vars
@ -28,9 +27,8 @@
@include font-size(var(--#{$prefix}nav-link-font-size)); @include font-size(var(--#{$prefix}nav-link-font-size));
font-weight: var(--#{$prefix}nav-link-font-weight); font-weight: var(--#{$prefix}nav-link-font-weight);
color: var(--#{$prefix}nav-link-color); color: var(--#{$prefix}nav-link-color);
background-color: var(--#{$prefix}nav-link-background-color);
text-decoration: if($link-decoration == none, null, none); text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}nav-tabs-link-active-bg); background: none;
border: 0; border: 0;
@include transition($nav-link-transition); @include transition($nav-link-transition);

View File

@ -1607,6 +1607,7 @@ $list-group-action-active-color: var(--#{$prefix}body-color) !default;
$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default; $list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;
// scss-docs-end list-group-variables // scss-docs-end list-group-variables
// Image thumbnails // Image thumbnails
// scss-docs-start thumbnail-variables // scss-docs-start thumbnail-variables
@ -1618,6 +1619,7 @@ $thumbnail-border-radius: var(--#{$prefix}border-radius) !default;
$thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default; $thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default;
// scss-docs-end thumbnail-variables // scss-docs-end thumbnail-variables
// Figures // Figures
// scss-docs-start figure-variables // scss-docs-start figure-variables
@ -1745,3 +1747,5 @@ $kbd-bg: var(--#{$prefix}body-color) !default;
$nested-kbd-font-weight: null !default; // Deprecated in v5.2.0, removing in v6 $nested-kbd-font-weight: null !default; // Deprecated in v5.2.0, removing in v6
$pre-color: null !default; $pre-color: null !default;
@import "variables-dark"; // TODO: can be removed safely in v6, only here to avoid breaking changes in v5.3

View File

@ -11,7 +11,6 @@
font-weight: $input-font-weight; font-weight: $input-font-weight;
line-height: $input-line-height; line-height: $input-line-height;
color: $input-color; color: $input-color;
appearance: none; // Fix appearance for date inputs in Safari
background-color: $input-bg; background-color: $input-bg;
background-clip: padding-box; background-clip: padding-box;
border: $input-border-width solid $input-border-color; border: $input-border-width solid $input-border-color;

View File

@ -2120,9 +2120,6 @@ progress {
font-weight: 400; font-weight: 400;
line-height: 1.5; line-height: 1.5;
color: var(--bs-body-color); color: var(--bs-body-color);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: var(--bs-body-bg); background-color: var(--bs-body-bg);
background-clip: padding-box; background-clip: padding-box;
border: var(--bs-border-width) solid var(--bs-border-color); border: var(--bs-border-width) solid var(--bs-border-color);

View File

@ -11,7 +11,6 @@
font-weight: $input-font-weight; font-weight: $input-font-weight;
line-height: $input-line-height; line-height: $input-line-height;
color: $input-color; color: $input-color;
appearance: none; // Fix appearance for date inputs in Safari
background-color: $input-bg; background-color: $input-bg;
background-clip: padding-box; background-clip: padding-box;
border: $input-border-width solid $input-border-color; border: $input-border-width solid $input-border-color;

View File

@ -127,7 +127,7 @@ namespace yavscTests
services.AddAuthorizationBuilder() services.AddAuthorizationBuilder()
.AddPolicy("AdministratorOnly", policy => .AddPolicy("AdministratorOnly", policy =>
{ {
policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Constants.AdminGroupName); policy.RequireClaim(JwtClaimType.Role, Constants.AdminGroupName);
}) })
.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName)) .AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName))
.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddPolicy("Bearer", new AuthorizationPolicyBuilder()