refacto site settings
Some checks failed
Dotnet build and test / build (pull_request) Failing after 8m29s

This commit is contained in:
Paul Schneider 2026-09-17 22:22:18 +01:00
commit 3bc4142383
Signed by: notazof
GPG key ID: 1DD5D838E5343B06
33 changed files with 399 additions and 315 deletions

View file

@ -490,14 +490,17 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
if (result.Succeeded)
{
_logger.LogInformation(3, "User created a new account with password.");
await _emailSender.SendEmailAsync(Config.SiteSetup.Owner.Name, Config.SiteSetup.Owner.EMail,
$"[{_siteSettings.Title}] Inscription avec mot de passe: {user.UserName} ", $"{user.Id}/{user.UserName}/{user.Email}");
await _emailSender.SendEmailAsync(
_siteSettings.Owner.Name,
_siteSettings.Owner.EMail,
$"[{_siteSettings.Title}] Inscription avec mot de passe: {user.UserName} ",
$"{user.Id}/{user.UserName}/{user.Email}");
// TODO user.DiskQuota = Startup.SiteSetup.UserFiles.Quota;
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
// Send an email with this link
Uri authority = new Uri(Config.Authority);
Uri authority = new Uri(_siteSettings.Authority);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Action("ConfirmEmail", "Account",
@ -703,10 +706,15 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
await _signInManager.SignInAsync(user, isPersistent: false);
await _emailSender.SendEmailAsync(Config.SiteSetup.Owner.Name, Config.SiteSetup.Owner.EMail,
$"[{_siteSettings.Title}] Inscription via {info.LoginProvider}: {user.UserName} ", $"{user.Id}/{user.UserName}/{user.Email}");
await _emailSender.SendEmailAsync(
_siteSettings.Owner.Name,
_siteSettings.Owner.EMail,
$"[{_siteSettings.Title}] Inscription via {info.LoginProvider}: {user.UserName} ",
$"{user.Id}/{user.UserName}/{user.Email}");
_logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
_logger.LogInformation(6,
"User created an account using {Name} provider.",
info.LoginProvider);
return Redirect(returnUrl);
}

View file

@ -109,8 +109,9 @@ namespace Yavsc.Org.Controllers
{
if (ModelState.IsValid)
{
Models.Blog.BlogPost post = blogSpotService.Create(User.GetUserId(),
blogInput, Request.Form.Files);
var uid = User.GetUserId();
Models.Blog.BlogPost post = blogSpotService.Create(uid, blogInput);
blogSpotService.AttachFiles(Request.Form.Files, uid, post.Id);
return RedirectToAction("Index");
}
return View("Edit", blogInput);

View file

@ -8,6 +8,7 @@ namespace Yavsc.Controllers
using Helpers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Models;
using ViewModels.FrontOffice;
using Yavsc.Server.Helpers;
@ -20,18 +21,21 @@ namespace Yavsc.Controllers
readonly ILogger _logger;
readonly IStringLocalizer _SR;
private readonly IBillingService _billing;
private readonly SiteSettings _siteSettings;
public FrontOfficeController(ApplicationDbContext context,
UserManager<ApplicationUser> userManager,
IBillingService billing,
ILoggerFactory loggerFactory,
IStringLocalizer<FrontOfficeController> SR)
IStringLocalizer<FrontOfficeController> SR,
IOptions<SiteSettings> siteSettings)
{
_context = context;
_userManager = userManager;
_logger = loggerFactory.CreateLogger<FrontOfficeController>();
_SR = SR;
_billing = billing;
_siteSettings = siteSettings.Value;
}
public ActionResult Index()
{
@ -95,8 +99,8 @@ namespace Yavsc.Controllers
[HttpGet]
public IActionResult EstimatePdf(long id)
{
ViewBag.TempDir = Config.SiteSetup.TempDir;
ViewBag.BillsDir = AbstractFileSystemHelpers.UserBillsDirName;
ViewBag.TempDir = _siteSettings.TempDir;
ViewBag.BillsDir = _siteSettings.Bills;
var estimate = _context.Estimates.Include(x => x.Query)
.Include(x => x.Query.Client)
.Include(x => x.Query.PerformerProfile)

View file

@ -1,20 +1,25 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
namespace Yavsc.Org.Controllers
{
public class FileSystemController : Controller
{
public FileSystemController()
private SiteSettings _siteSettings;
public FileSystemController(IOptions<SiteSettings> siteSettings)
{
_siteSettings = siteSettings.Value;
}
// Removed redundant empty constructor block
public IActionResult Index(string subdir="")
{
{
if (subdir !=null)
if (!subdir.IsValidYavscPath())
return new BadRequestResult();
var files = AbstractFileSystemHelpers.GetUserFiles(User.GetUserId(), subdir);
var files = FileSystemHelpers.GetUserFiles(_siteSettings, User.GetUserId(), subdir);
return View(files);
}
}

View file

@ -1044,7 +1044,7 @@ public static class HostingExtensions
Startup.Configure(app, siteSettings, smtpSettings,
payPalSettings, googleAuthSettings, localization, loggerFactory,
app.Environment.EnvironmentName);
app.ConfigureFileServerApp();
app.ConfigureFileServerApp(siteSettings.Value);
app.UseSession();
return app;
}
@ -1238,24 +1238,44 @@ ADD COLUMN IF NOT EXISTS ""Moderated"" boolean NOT NULL DEFAULT FALSE;");
#nullable disable
public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app,
SiteSettings settings,
bool enableDirectoryBrowsing = false)
{
if (settings.GitRepository == null)
{
throw new InvalidOperationException("GitRepository path is not configured in SiteSettings.");
}
if (settings.Blog == null)
{
throw new InvalidOperationException("Blog path is not configured in SiteSettings.");
}
if (settings.Avatars == null)
{
throw new InvalidOperationException("Avatars path is not configured in SiteSettings.");
}
if (settings.Bills == null)
{
throw new InvalidOperationException("Bills path is not configured in SiteSettings.");
}
if (settings.TempDir == null)
{
throw new InvalidOperationException("TempDir path is not configured in SiteSettings.");
}
var userFilesDirInfo = new DirectoryInfo(Config.SiteSetup.Blog);
AbstractFileSystemHelpers.UserFilesDirName = userFilesDirInfo.FullName;
var userFilesDirInfo = new DirectoryInfo(settings.Blog);
if (!userFilesDirInfo.Exists) userFilesDirInfo.Create();
Config.UserFilesOptions = new FileServerOptions()
{
FileProvider = new PhysicalFileProvider(AbstractFileSystemHelpers.UserFilesDirName),
FileProvider = new PhysicalFileProvider(userFilesDirInfo.FullName),
RequestPath = PathString.FromUriComponent(Constants.UserFilesPath),
EnableDirectoryBrowsing = enableDirectoryBrowsing,
};
Config.UserFilesOptions.EnableDefaultFiles = true;
Config.UserFilesOptions.StaticFileOptions.ServeUnknownFileTypes = true;
var avatarsDirInfo = new DirectoryInfo(Config.SiteSetup.Avatars);
var avatarsDirInfo = new DirectoryInfo(settings.Avatars);
if (!avatarsDirInfo.Exists) avatarsDirInfo.Create();
Config.AvatarsDirName = avatarsDirInfo.FullName;
@ -1267,7 +1287,7 @@ ADD COLUMN IF NOT EXISTS ""Moderated"" boolean NOT NULL DEFAULT FALSE;");
};
var gitdirinfo = new DirectoryInfo(Config.SiteSetup.GitRepository);
var gitdirinfo = new DirectoryInfo(settings.GitRepository);
Config.GitDirName = gitdirinfo.FullName;
if (!gitdirinfo.Exists) gitdirinfo.Create();
Config.GitOptions = new FileServerOptions()

View file

@ -91,7 +91,7 @@ namespace Yavsc.Helpers
result = result.Replace("\n","\\tabularnewline ");
return new TeXString(result);
}
public static string NewLinesWith(this string target, string separator)
{
@ -115,11 +115,11 @@ namespace Yavsc.Helpers
return new TeXString(string.Join(lineSeparator,texlines));
}
public static bool GenerateEstimatePdf(this PdfGenerationViewModel Model)
public static bool GenerateEstimatePdf(this SiteSettings settings, PdfGenerationViewModel Model)
{
string errorMsg = null;
var billdir = Model.DestDir;
var tempdir = Config.SiteSetup.TempDir;
var tempdir = settings.TempDir;
string name = Model.BaseFileName;
string fullname = new FileInfo(
System.IO.Path.Combine(tempdir, name)).FullName;
@ -154,7 +154,7 @@ namespace Yavsc.Helpers
{
errorMsg = $"Pdf generation failed with exit code: {p.ExitCode}";
}
else
else
{
fi.Delete();
var di = new DirectoryInfo(Path.Combine(tempdir,$"{Model.BaseFileName}.t2d"));

View file

@ -2,6 +2,8 @@ using System.Diagnostics;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Yavsc;
using Yavsc.Blogspot;
using Yavsc.Models;
using Yavsc.Models.Access;
@ -18,14 +20,17 @@ public class OldBlogSpotService
private readonly ApplicationDbContext _context;
private readonly IAuthorizationService _authorizationService;
private readonly IFileSystemAuthManager fileSystemAuthManager;
private readonly SiteSettings siteSettings;
public OldBlogSpotService(ApplicationDbContext context,
IAuthorizationService authorizationService,
IFileSystemAuthManager fileSystemAuthManager)
IFileSystemAuthManager fileSystemAuthManager,
IOptions<SiteSettings> siteSettings)
{
_authorizationService = authorizationService;
_context = context;
this.fileSystemAuthManager = fileSystemAuthManager;
this.siteSettings = siteSettings.Value;
}
public Yavsc.Models.Blog.BlogPost Create(string userId, Yavsc.Models.Blog.BlogPost post, IFormFileCollection files)
@ -45,7 +50,7 @@ public class OldBlogSpotService
// Créer un répertoire pour les fichiers du blog
string blogFilesSubdir = $"blogs/{post.Id}";
string destDir = Path.Combine(
AbstractFileSystemHelpers.UserFilesDirName,
siteSettings.Blog,
user.UserName,
blogFilesSubdir
);

View file

@ -21,13 +21,10 @@ public class Startup
{
Config.GoogleSettings = googleSettings.Value;
ResourcesHelpers.GlobalLocalizer = localizer;
Config.SiteSetup = siteSettings.Value;
Config.SmtpSetup = smtpSettings.Value;
Config.Authority = siteSettings.Value.Authority;
string blogsDir = siteSettings.Value.Blog ?? throw new Exception("blogsDir is not set.");
string billsDir = siteSettings.Value.Bills ?? throw new Exception("billsDir is not set.");
AbstractFileSystemHelpers.UserFilesDirName = new DirectoryInfo(blogsDir).FullName;
AbstractFileSystemHelpers.UserBillsDirName = new DirectoryInfo(billsDir).FullName;
Config.Temp = siteSettings.Value.TempDir;
Config.PayPalSettings = payPalSettings.Value;
@ -35,7 +32,7 @@ public class Startup
// TODO implement an installation & upgrade procedure
// Create required directories
foreach (string dir in new string[] { AbstractFileSystemHelpers.UserFilesDirName, AbstractFileSystemHelpers.UserBillsDirName, Config.Temp })
foreach (string dir in new string[] { blogsDir, billsDir, Config.Temp })
{
if (dir == null)
{
@ -48,27 +45,27 @@ public class Startup
di.Create();
}
}
CheckApp(loggerFactory.CreateLogger<Startup>(), environmentName);
CheckApp(siteSettings.Value, loggerFactory.CreateLogger<Startup>(), environmentName);
}
public static void CheckApp(ILogger logger, string environmentName)
public static void CheckApp(SiteSettings settings, ILogger logger, string environmentName)
{
var appData = Environment.GetEnvironmentVariable("APPDATA");
if (appData == null)
{
logger.LogWarning("AppData was not found in environment variables");
if (Config.SiteSetup.DataDir == null) {
Config.SiteSetup.DataDir = "AppData"+environmentName;
logger.LogInformation("Using: "+Config.SiteSetup.DataDir);
} else logger.LogInformation("Using value from settings: "+Config.SiteSetup.DataDir);
DirectoryInfo di = new DirectoryInfo(Config.SiteSetup.DataDir);
if (settings.DataDir == null) {
settings.DataDir = "AppData"+environmentName;
logger.LogInformation("Using: "+settings.DataDir);
} else logger.LogInformation("Using value from settings: "+settings.DataDir);
DirectoryInfo di = new DirectoryInfo(settings.DataDir);
if (!di.Exists)
{
di.Create();
logger.LogWarning("Created dir : "+di.FullName);
}
logger.LogInformation("Using existing directory: "+di.FullName);
Environment.SetEnvironmentVariable("APPDATA", Config.SiteSetup.DataDir);
Environment.SetEnvironmentVariable("APPDATA", settings.DataDir);
logger.LogWarning("It has been set to : "+Environment.GetEnvironmentVariable("APPDATA"));
}

View file

@ -8,7 +8,7 @@ using Yavsc.ViewModels;
using Yavsc.ViewModels.Gen;
using Yavsc.Services;
using Microsoft.EntityFrameworkCore;
using Yavsc.Server.Helpers;
using Microsoft.Extensions.Options;
namespace Yavsc.ViewComponents
{
@ -17,20 +17,29 @@ namespace Yavsc.ViewComponents
readonly ApplicationDbContext dbContext;
readonly IBillingService billing;
readonly IStringLocalizer<BillViewComponent> localizer;
private readonly SiteSettings siteSettings;
public BillViewComponent(ApplicationDbContext dbContext,
public BillViewComponent(ApplicationDbContext dbContext,
IStringLocalizer<BillViewComponent> localizer,
IBillingService billing)
IBillingService billing,
IOptions<SiteSettings> siteSettings)
{
this.billing = billing;
this.dbContext = dbContext;
this.localizer = localizer;
this.siteSettings = siteSettings.Value;
}
public async Task<IViewComponentResult> InvokeAsync(string code, IBillable billable, OutputFormat format, bool asBill)
public async Task<IViewComponentResult> InvokeAsync(
string code,
IBillable billable,
OutputFormat format,
bool asBill,
SiteSettings settings
)
{
var di = new DirectoryInfo(Config.SiteSetup.Bills);
var dia = new DirectoryInfo(Config.SiteSetup.Avatars);
var di = new DirectoryInfo(settings.Bills);
var dia = new DirectoryInfo(settings.Avatars);
ViewBag.BillsDir = di.FullName;
ViewBag.AvatarsDir = dia.FullName;
ViewBag.AsBill = asBill; // vrai pour une facture, sinon, c'est un devis
@ -56,9 +65,9 @@ namespace Yavsc.ViewComponents
ViewBag.PerformerProfile = profile;
ViewBag.ActivityLabel = (await dbContext.Activities.SingleAsync(a => a.Code == billable.ActivityCode)).Name;
var proaddr = profile.OrganizationAddress.Address;
ViewBag.PerformerOrganizationAddress = proaddr.SplitAddressToTeX() ;
ViewBag.FooterPerformerOrganizationAddress = proaddr.SplitAddressToTeX(", ");
var proAddr = profile.OrganizationAddress.Address;
ViewBag.PerformerOrganizationAddress = proAddr.SplitAddressToTeX() ;
ViewBag.FooterPerformerOrganizationAddress = proAddr.SplitAddressToTeX(", ");
ViewBag.PerformerAddress = performer.PostalAddress?.Address.SplitAddressToTeX() ;
switch (format) {
@ -75,23 +84,24 @@ namespace Yavsc.ViewComponents
tex = writer.ToString();
}
ViewComponentContext.ViewContext.Writer = oldWriter;
var genrtrData = new PdfGenerationViewModel
{
var pdfGenerationViewModel = new PdfGenerationViewModel
{
Temp = Config.Temp,
TeXSource = tex,
DestDir = AbstractFileSystemHelpers.UserBillsDirName,
TeXSource = tex,
DestDir = settings.Blog,
BaseFileName = billable.GetFileBaseName(billing)
};
if (genrtrData.GenerateEstimatePdf()) {
return this.View(new { Generated = genrtrData.BaseFileName+".pdf" });
if (settings.GenerateEstimatePdf(pdfGenerationViewModel)) {
return this.View(new { Generated = pdfGenerationViewModel.BaseFileName+".pdf" });
} else {
return View(new { Error = genrtrData.GenerationErrorMessage } );
return View(new { Error = pdfGenerationViewModel.GenerationErrorMessage } );
}
}
ViewBag.BillFileInfo = billable.GetBillInfo(billing);
ViewBag.BillFileInfo = billable.GetBillInfo(billing, siteSettings);
ViewBag.Settings = settings;
return View("Default",billable);
}
}

View file

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Yavsc.Models;
using Yavsc.Server.Helpers;
using Yavsc.ViewModels.UserFiles;
@ -11,24 +12,24 @@ namespace Yavsc.ViewComponents
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public DirectoryViewComponent(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager)
private readonly SiteSettings siteSettings;
public DirectoryViewComponent(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IOptions<SiteSettings> siteSettings)
{
_userManager = userManager;
_signInManager = signInManager;
this.siteSettings = siteSettings.Value;
}
public async Task<IViewComponentResult> InvokeAsync(string dirname)
{
string uid = ViewContext.HttpContext.User.GetUserId();
IViewComponentResult result = null;
result = View(new UserDirectoryInfo(
AbstractFileSystemHelpers.UserFilesDirName,
return View(new UserDirectoryInfo(
siteSettings.Blog,
uid, dirname));
return result;
}
}
}

View file

@ -6,8 +6,8 @@
@using Yavsc.Helpers
@model Yavsc.ViewModels.Gen.PdfGenerationViewModel
@{
Model.GenerateEstimatePdf();
@{
ViewBag.Settings.GenerateEstimatePdf(Model);
}
@if (Model.Generated) {
<div>

View file

@ -7,7 +7,7 @@
@model Yavsc.ViewModels.Gen.PdfGenerationViewModel
@{
Model.GenerateEstimatePdf();
SiteSettings.Value.GenerateEstimatePdf(Model);
}
@if (Model.Generated) {
<div>

View file

@ -1,13 +1,13 @@
<nav class="navbar navbar-expand-sm navbar-dark bg-dark" aria-label="Yavsc"
style="background-image: url('@Config.SiteSetup.Banner');
style="background-image: url('@SiteSettings.Value.Banner');
background-position: 0%;
background-attachment: fixed;">
<a class="navbar-brand" href="/">
<img src="~/images/yavsc-logo.svg" alt="Yavsc" style="height:32px; margin-right:8px; display:inline-block; vertical-align:middle;" />
@Config.SiteSetup.Title
@SiteSettings.Value.Title
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbar" aria-controls="navbar"
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbar" aria-controls="navbar"
aria-expanded="true" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

View file

@ -33,7 +33,8 @@
"Bills": "bills",
"Blog": "blog",
"TempDir": "temp",
"DataDir": "data"
"DataDir": "data",
"GitRepository": "git"
},
"Smtp": {
"Host": "[YOURSMTPHOST]",