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

View file

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

View file

@ -33,12 +33,16 @@ using Yavsc.Server.Helpers;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Protocols.Configuration;
using IdentityModel;
using System.Security.Claims;
using IdentityServer8.Security;
namespace Yavsc.Extensions;
public static class HostingExtensions
{
public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app,
bool enableDirectoryBrowsing = false)
{
@ -191,11 +195,13 @@ public static class HostingExtensions
{
policy
.RequireAuthenticatedUser()
.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "Performer");
.RequireClaim(JwtClaimTypes.Role, "Performer");
});
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));
@ -284,12 +290,13 @@ public static class HostingExtensions
// see https://IdentityServer8.readthedocs.io/en/latest/topics/resources.html
options.EmitStaticAudienceClaim = true;
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryClients(Config.Clients)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>()
.AddAspNetIdentity<ApplicationUser>()
;
if (builder.Environment.IsDevelopment())
{
@ -306,9 +313,9 @@ public static class HostingExtensions
RSA rsa = RSA.Create();
rsa.ImportFromPem(File.ReadAllText(certFileInfo.FullName));
var signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256)
{
CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false }
};
{
CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false }
};
identityServerBuilder.AddSigningCredential(signingCredentials);
}
return identityServerBuilder;
@ -372,7 +379,7 @@ public static class HostingExtensions
app.UseAuthorization();
app.UseCors("default");
app.MapDefaultControllerRoute();
//pp.MapRazorPages();
//app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");
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 RazorEngine.Compilation.ImpromptuInterface.Optimization;
using Yavsc.Helpers;
using Yavsc.Migrations;
using Yavsc.Models;
using Yavsc.Models.Blog;
using Yavsc.ViewModels.Auth;
@ -33,6 +34,10 @@ public class PermissionHandler : IAuthorizationHandler
{
context.Succeed(requirement);
}
else if (context.User.IsInRole("Administrator"))
{
context.Succeed(requirement);
}
}
else if (requirement is EditPermission || requirement is DeletePermission)
{

View file

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

View file

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

View file

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

View file

@ -10,14 +10,15 @@
<PackageReference Include="popper.js" Version="1.16.1">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="bootstrap" Version="5.3.3">
<PackageReference Include="bootstrap" Version="5.3.7">
<PrivateAssets>all</PrivateAssets>
</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="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.UI" Version="9.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.6">
@ -30,15 +31,15 @@
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" 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.Razor" Version="2.3.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.6" />
<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="SixLabors.ImageSharp" Version="3.1.9" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
</ItemGroup>
<ItemGroup>

View file

@ -35,3 +35,9 @@ img.blogphoto {
padding: .3em;
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);
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
--#{$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-disabled-color: #{$nav-link-disabled-color};
// scss-docs-end nav-css-vars
@ -28,9 +27,8 @@
@include font-size(var(--#{$prefix}nav-link-font-size));
font-weight: var(--#{$prefix}nav-link-font-weight);
color: var(--#{$prefix}nav-link-color);
background-color: var(--#{$prefix}nav-link-background-color);
text-decoration: if($link-decoration == none, null, none);
background-color: var(--#{$prefix}nav-tabs-link-active-bg);
background: none;
border: 0;
@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;
// scss-docs-end list-group-variables
// Image thumbnails
// 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;
// scss-docs-end thumbnail-variables
// Figures
// 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
$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;
line-height: $input-line-height;
color: $input-color;
appearance: none; // Fix appearance for date inputs in Safari
background-color: $input-bg;
background-clip: padding-box;
border: $input-border-width solid $input-border-color;