From 8faabbb5ff849b2f18fd5c5d84a1aca24db5358b Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Thu, 17 Sep 2026 22:22:18 +0100 Subject: [PATCH] refacto site settings --- .../FileSystem/AbstractFileSystemHelpers.cs | 13 ---- .../Controllers/Business/BillingController.cs | 20 +++-- .../accounting/AccountController.cs | 9 ++- src/Yavsc.Api/Program.cs | 1 - src/Yavsc.Api/appsettings-api.json | 4 +- src/Yavsc.Blogs.Tests/BlogApiTests.cs | 8 +- .../Controllers/FileSystemApiController.cs | 18 +++-- .../Controllers/FileSystemStreamController.cs | 14 +++- src/Yavsc.Blogs/appsettings-blogs.json | 3 +- .../EstimateSignatureFileHelperTests.cs | 14 ++-- .../Accounting/AccountController.cs | 20 +++-- .../Contracting/FrontOfficeController.cs | 10 ++- .../Controllers/FileSystemController.cs | 13 +++- src/Yavsc.Org/Extensions/HostingExtensions.cs | 12 +-- src/Yavsc.Org/Helpers/TeXHelpers.cs | 8 +- src/Yavsc.Org/Services/BlogSpotService.cs | 9 ++- src/Yavsc.Org/Startup.cs | 21 +++--- .../ViewComponents/BillViewComponent.cs | 48 +++++++----- .../ViewComponents/DirectoryViewComponent.cs | 19 ++--- .../Shared/Components/Bill/Bill_pdf.cshtml | 4 +- .../Components/Estimate/Estimate_pdf.cshtml | 2 +- src/Yavsc.Org/Views/Shared/_Nav.cshtml | 8 +- src/Yavsc.Server/Config.cs | 3 +- src/Yavsc.Server/Helpers/BillingHelpers.cs | 5 +- .../Helpers/EstimateSignatureFileHelper.cs | 3 +- src/Yavsc.Server/Helpers/FileSystemHelpers.cs | 57 +++++++------- src/Yavsc.Server/Services/BlogSpotService.cs | 75 ++++++++++--------- src/Yavsc.Server/Settings/SiteSettings.cs | 57 +++++--------- 28 files changed, 255 insertions(+), 223 deletions(-) diff --git a/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs b/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs index 14bc86435..7665df8ab 100644 --- a/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs +++ b/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs @@ -7,8 +7,6 @@ namespace Yavsc.Server.Helpers { public static class AbstractFileSystemHelpers { - public static string UserBillsDirName { set; get; } - public static string UserFilesDirName { set; get; } /// /// Is Valid this Path? @@ -64,17 +62,6 @@ namespace Yavsc.Server.Helpers return sb.ToString(); } - public static UserDirectoryInfo GetUserFiles(string userId, string subdir) - { - UserDirectoryInfo di = new UserDirectoryInfo(UserFilesDirName, userId, subdir); - return di; - } - public static bool IsRegularFile(string userName, string subdir) - { - FileInfo fi = new FileInfo( Path.Combine(Path.Combine(UserFilesDirName, userName), subdir)); - return fi.Exists; - } - // Server side only supports POSIX file systems public const char RemoteDirectorySeparator = '/'; diff --git a/src/Yavsc.Api/Controllers/Business/BillingController.cs b/src/Yavsc.Api/Controllers/Business/BillingController.cs index d10e166e3..ba099e7c7 100644 --- a/src/Yavsc.Api/Controllers/Business/BillingController.cs +++ b/src/Yavsc.Api/Controllers/Business/BillingController.cs @@ -35,6 +35,7 @@ namespace Yavsc.ApiControllers private readonly ILogger logger; private readonly IBillingService billingService; + private readonly SiteSettings siteSettings; public BillingController( IAuthorizationService authorizationService, @@ -43,7 +44,8 @@ namespace Yavsc.ApiControllers ApplicationDbContext context, IOptions googleSettings, IYavscMessageSender GCMSender, - IBillingService billingService + IBillingService billingService, + IOptions siteSettings ) { _googleSettings=googleSettings.Value; @@ -53,6 +55,7 @@ namespace Yavsc.ApiControllers this._localizer = SR; _GCMSender=GCMSender; this.billingService=billingService; + this.siteSettings = siteSettings.Value; } [HttpGet("facture-{billingCode}-{id}.pdf"), Authorize] @@ -65,7 +68,7 @@ namespace Yavsc.ApiControllers return new ChallengeResult(); } - var fi = bill.GetBillInfo(billingService); + var fi = bill.GetBillInfo(billingService, siteSettings); if (!fi.Exists) return Ok(new { Error = "Not generated" }); return File(fi.OpenRead(), "application/x-pdf", fi.Name); @@ -229,7 +232,7 @@ namespace Yavsc.ApiControllers } if (Request.Form.Files.Count!=1) return new BadRequestResult(); - await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"pro"); + await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"pro", siteSettings); estimate.ProviderValidationDate = DateTime.UtcNow; dbContext.SaveChanges(User.GetUserId()); // Notify the client @@ -273,7 +276,7 @@ namespace Yavsc.ApiControllers } var filename = AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, id); - FileInfo fi = new FileInfo(Path.Combine(AbstractFileSystemHelpers.UserBillsDirName, filename)); + FileInfo fi = new FileInfo(Path.Combine(siteSettings.Bills, filename)); if (!fi.Exists) return NotFound(new { Error = "Professional signature not found" }); return File(fi.OpenRead(), "application/x-pdf", filename); ; } @@ -310,7 +313,7 @@ namespace Yavsc.ApiControllers } if (Request.Form.Files.Count!=1) return new BadRequestResult(); - await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"cli"); + await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"cli", siteSettings); estimate.ClientValidationDate = DateTime.UtcNow; dbContext.SaveChanges(User.GetUserId()); return Ok (new { ClientValidationDate = estimate.ClientValidationDate }); @@ -327,9 +330,9 @@ namespace Yavsc.ApiControllers } var filename = AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, id); - FileInfo fi = new FileInfo(Path.Combine(AbstractFileSystemHelpers.UserBillsDirName, filename)); + FileInfo fi = new FileInfo(Path.Combine(siteSettings.Bills, filename)); if (!fi.Exists) return NotFound(new { Error = "Professional signature not found" }); - return File(fi.OpenRead(), "application/x-pdf", filename); ; + return File(fi.OpenRead(), "application/x-pdf", filename); } /// @@ -405,7 +408,8 @@ namespace Yavsc.ApiControllers FileReceivedInfo fi; try { - fi = await User.ReceiveEstimateSignatureAsync(id, type, payload, token); + fi = await User.ReceiveEstimateSignatureAsync(id, type, payload, + siteSettings, token); } catch (Exception ex) { diff --git a/src/Yavsc.Api/Controllers/accounting/AccountController.cs b/src/Yavsc.Api/Controllers/accounting/AccountController.cs index 155274cdf..f0986e98f 100644 --- a/src/Yavsc.Api/Controllers/accounting/AccountController.cs +++ b/src/Yavsc.Api/Controllers/accounting/AccountController.cs @@ -2,13 +2,13 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Http; using ImageMagick; using Yavsc.Models; using Yavsc.Api.Helpers; using Yavsc.Server.Helpers; using System.Diagnostics; +using Microsoft.Extensions.Options; namespace Yavsc.WebApi.Controllers { @@ -28,13 +28,16 @@ namespace Yavsc.WebApi.Controllers ]; readonly ApplicationDbContext _dbContext; + private readonly SiteSettings siteSettings; private readonly ILogger _logger; public ApiAccountController( - ILoggerFactory loggerFactory, ApplicationDbContext dbContext) + ILoggerFactory loggerFactory, ApplicationDbContext dbContext, + IOptions siteSettings) { _logger = loggerFactory.CreateLogger(nameof(ApiAccountController)); _dbContext = dbContext; + this.siteSettings = siteSettings.Value; } [HttpGet("me")] @@ -146,7 +149,7 @@ namespace Yavsc.WebApi.Controllers try { - var info = user.ReceiveAvatar(avatarFile); + var info = user.ReceiveAvatar(avatarFile, siteSettings); await _dbContext.SaveChangesAsync(); return Ok(new { diff --git a/src/Yavsc.Api/Program.cs b/src/Yavsc.Api/Program.cs index 5f7ef25c0..be4ae6579 100644 --- a/src/Yavsc.Api/Program.cs +++ b/src/Yavsc.Api/Program.cs @@ -21,7 +21,6 @@ internal class Program var builder = WebApplication.CreateBuilder(args); builder.AddConfiguration("api"); - Config.SiteSetup = builder.Configuration.GetSection("Site").Get() ?? new SiteSettings(); var services = builder.Services; diff --git a/src/Yavsc.Api/appsettings-api.json b/src/Yavsc.Api/appsettings-api.json index 1bde1d39f..b16e7b8b4 100644 --- a/src/Yavsc.Api/appsettings-api.json +++ b/src/Yavsc.Api/appsettings-api.json @@ -5,7 +5,9 @@ "CorsAllowedOrigins": [ "https://yavsc.pschneider.fr", "https://blogs.pschneider.fr" - ] + ], + "Bills": "bills", + "TempDir": "temp" }, "Logging": { "LogLevel": { diff --git a/src/Yavsc.Blogs.Tests/BlogApiTests.cs b/src/Yavsc.Blogs.Tests/BlogApiTests.cs index c57c31c3f..de10cac30 100644 --- a/src/Yavsc.Blogs.Tests/BlogApiTests.cs +++ b/src/Yavsc.Blogs.Tests/BlogApiTests.cs @@ -338,10 +338,9 @@ public sealed class BlogApiTests : IClassFixture ResetAndSeedDefaultUser(); using var http = NewClient(subject: "tester"); - var previousRoot = AbstractFileSystemHelpers.UserFilesDirName; + var previousRoot = "blog"; var tempRoot = Path.Combine(Path.GetTempPath(), "yavsc-blogs-tests-files-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempRoot); - AbstractFileSystemHelpers.UserFilesDirName = tempRoot; try { @@ -405,7 +404,6 @@ public sealed class BlogApiTests : IClassFixture } finally { - AbstractFileSystemHelpers.UserFilesDirName = previousRoot; try { Directory.Delete(tempRoot, recursive: true); } catch { } } } @@ -480,10 +478,9 @@ public sealed class BlogApiTests : IClassFixture ResetAndSeedDefaultUser(); using var http = NewClient(subject: "tester"); - var previousRoot = AbstractFileSystemHelpers.UserFilesDirName; + var previousRoot = "blog"; var tempRoot = Path.Combine(Path.GetTempPath(), "yavsc-blogs-tests-files-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempRoot); - AbstractFileSystemHelpers.UserFilesDirName = tempRoot; try { @@ -578,7 +575,6 @@ public sealed class BlogApiTests : IClassFixture } finally { - AbstractFileSystemHelpers.UserFilesDirName = previousRoot; try { Directory.Delete(tempRoot, recursive: true); } catch { } } } diff --git a/src/Yavsc.Blogs/Controllers/FileSystemApiController.cs b/src/Yavsc.Blogs/Controllers/FileSystemApiController.cs index 5e8345034..b714af4e0 100644 --- a/src/Yavsc.Blogs/Controllers/FileSystemApiController.cs +++ b/src/Yavsc.Blogs/Controllers/FileSystemApiController.cs @@ -12,6 +12,7 @@ namespace Yavsc.Blogs.Controllers using Yavsc.Server.Helpers; using Yavsc.Abstract.Helpers; using Yavsc.Server.Models.FileSystem; + using Microsoft.Extensions.Options; [Authorize,Route(APIPrefix + "/fs")] public partial class FileSystemApiController : Controller @@ -19,15 +20,18 @@ namespace Yavsc.Blogs.Controllers readonly ApplicationDbContext dbContext; private readonly IAuthorizationService AuthorizationService; private readonly ILogger _logger; + private readonly SiteSettings siteSettings; public FileSystemApiController(ApplicationDbContext context, IAuthorizationService authorizationService, - ILoggerFactory loggerFactory) + ILoggerFactory loggerFactory, + IOptions siteSettings) { AuthorizationService = authorizationService; dbContext = context; _logger = loggerFactory.CreateLogger(); + this.siteSettings = siteSettings.Value; } [HttpGet()] @@ -41,7 +45,7 @@ namespace Yavsc.Blogs.Controllers { if (!ModelState.IsValid) return new BadRequestObjectResult(ModelState); // _logger.LogInformation($"listing files from {User.Identity.Name}{subdir}"); - var files = AbstractFileSystemHelpers.GetUserFiles(User.GetUserId(), subdir); + var files = FileSystemHelpers.GetUserFiles(siteSettings, User.GetUserId(), subdir); return Ok(files); } @@ -53,7 +57,7 @@ namespace Yavsc.Blogs.Controllers List received = new List(); InvalidPathException pathex = null; try { - destDir = User.EnsureDestinationDirectory(subdir); + destDir = User.EnsureDestinationDirectory(subdir, siteSettings); } catch (InvalidPathException ex) { pathex = ex; } @@ -108,7 +112,7 @@ namespace Yavsc.Blogs.Controllers var user = dbContext.Users.Single( u => u.Id == uid ); - var info = user.MoveUserFileToDir(query.Id, query.To); + var info = user.MoveUserFileToDir(query.Id, query.To, siteSettings); if (!info.Done) return new BadRequestObjectResult(info); return Ok(new { moved = query.Id }); } @@ -131,11 +135,11 @@ namespace Yavsc.Blogs.Controllers try { 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, siteSettings); if (!result.Done) return new BadRequestObjectResult(result); } else { - var result = user.MoveUserDir(query.Id, query.To); + var result = user.MoveUserDir(query.Id, query.To, siteSettings); if (!result.Done) return new BadRequestObjectResult(result); } } @@ -161,7 +165,7 @@ namespace Yavsc.Blogs.Controllers ); try { - var result = user.DeleteUserDirOrFile(id); + var result = user.DeleteUserDirOrFile(id, siteSettings); if (!result.Done) return new BadRequestObjectResult(result); } diff --git a/src/Yavsc.Blogs/Controllers/FileSystemStreamController.cs b/src/Yavsc.Blogs/Controllers/FileSystemStreamController.cs index bc6485dd4..1de56b310 100644 --- a/src/Yavsc.Blogs/Controllers/FileSystemStreamController.cs +++ b/src/Yavsc.Blogs/Controllers/FileSystemStreamController.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.SignalR; using Yavsc.Server.Helpers; using static Yavsc.Constants; using Yavsc.Server.Hubs; +using Microsoft.Extensions.Options; namespace Yavsc.Blogs.Controllers { @@ -21,13 +22,20 @@ namespace Yavsc.Blogs.Controllers private readonly IHubContext hubContext; readonly ApplicationDbContext dbContext; - public FileSystemStreamController(ApplicationDbContext context, ILiveProcessor liveProcessor, ILoggerFactory loggerFactory, - IHubContext hubContext) + private readonly SiteSettings siteSettings; + + public FileSystemStreamController( + ApplicationDbContext context, + ILiveProcessor liveProcessor, + ILoggerFactory loggerFactory, + IHubContext hubContext, + IOptions siteSettings) { this.dbContext = context; this.logger = loggerFactory.CreateLogger(); this.liveProcessor = liveProcessor; this.hubContext = hubContext; + this.siteSettings = siteSettings.Value; } [Authorize, Route("put/{filename}")] @@ -55,7 +63,7 @@ namespace Yavsc.Blogs.Controllers ); - string destDir = HttpContext.User.EnsureDestinationDirectory(filePath); + string destDir = HttpContext.User.EnsureDestinationDirectory(filePath, siteSettings); logger.LogInformation($"Saving flow to {destDir}"); var userId = User.GetUserId(); var user = await dbContext.Users.FirstAsync(u => u.Id == userId); diff --git a/src/Yavsc.Blogs/appsettings-blogs.json b/src/Yavsc.Blogs/appsettings-blogs.json index 3888af71f..34134c937 100644 --- a/src/Yavsc.Blogs/appsettings-blogs.json +++ b/src/Yavsc.Blogs/appsettings-blogs.json @@ -8,7 +8,8 @@ "CorsAllowedOrigins": [ "https://localhost:5005", "https://api.pschneider.fr" - ] + ], + "Blog": "blog" }, "ConnectionStrings": { "YavscConnection": "Server=localhost;Port=5432;Database=lame-db-name;Username=lame-user-name;Password=lame-password;" diff --git a/src/Yavsc.Org.Tests/EstimateSignatureFileHelperTests.cs b/src/Yavsc.Org.Tests/EstimateSignatureFileHelperTests.cs index 91a4e1532..b7b4d3591 100644 --- a/src/Yavsc.Org.Tests/EstimateSignatureFileHelperTests.cs +++ b/src/Yavsc.Org.Tests/EstimateSignatureFileHelperTests.cs @@ -18,6 +18,7 @@ namespace Yavsc.Org.Tests; public class EstimateSignatureFileHelperTests : IDisposable { private readonly string _tempRoot; + private SiteSettings siteSettings; public EstimateSignatureFileHelperTests() { @@ -28,7 +29,7 @@ public class EstimateSignatureFileHelperTests : IDisposable Path.GetTempPath(), "yavsc-sig-tests-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_tempRoot); - AbstractFileSystemHelpers.UserFilesDirName = _tempRoot; + this.siteSettings = new SiteSettings { Blog = _tempRoot }; } public void Dispose() @@ -71,7 +72,7 @@ public class EstimateSignatureFileHelperTests : IDisposable }; // Act - var fi = Run(user, 123L, SignatureType.Pro, payload); + var fi = Run(user, 123L, SignatureType.Pro, payload, this.siteSettings); // Assert: file exists, sits under the user's root, and // parses as a yavsc.signature/v1 envelope. @@ -98,7 +99,8 @@ public class EstimateSignatureFileHelperTests : IDisposable var ct = TestContext.Current.CancellationToken; await Assert.ThrowsAsync(() => EstimateSignatureFileHelper.ReceiveEstimateSignatureAsync( - user, 1L, SignatureType.Pro, payload: null!, token: ct)); + user, 1L, SignatureType.Pro, payload: null!, + siteSettings, token: ct)); } [Fact] @@ -109,19 +111,19 @@ public class EstimateSignatureFileHelperTests : IDisposable var ct = TestContext.Current.CancellationToken; await Assert.ThrowsAsync(() => EstimateSignatureFileHelper.ReceiveEstimateSignatureAsync( - user, 0L, SignatureType.Pro, payload, token: ct)); + user, 0L, SignatureType.Pro, payload, this.siteSettings, token: ct)); } // --- helpers ---------------------------------------------------- private static FileReceivedInfo Run( - ClaimsPrincipal user, long estimateId, SignatureType type, SignaturePadPayload payload) + ClaimsPrincipal user, long estimateId, SignatureType type, SignaturePadPayload payload, SiteSettings siteSettings) { // The helper is async; tests that don't care about the // result can call it sync via .GetAwaiter().GetResult() // because we know it never throws in the happy path. return EstimateSignatureFileHelper - .ReceiveEstimateSignatureAsync(user, estimateId, type, payload, CancellationToken.None) + .ReceiveEstimateSignatureAsync(user, estimateId, type, payload, siteSettings, CancellationToken.None) .GetAwaiter().GetResult(); } diff --git a/src/Yavsc.Org/Controllers/Accounting/AccountController.cs b/src/Yavsc.Org/Controllers/Accounting/AccountController.cs index 3fd8a0159..04f60aa1d 100644 --- a/src/Yavsc.Org/Controllers/Accounting/AccountController.cs +++ b/src/Yavsc.Org/Controllers/Accounting/AccountController.cs @@ -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); } diff --git a/src/Yavsc.Org/Controllers/Contracting/FrontOfficeController.cs b/src/Yavsc.Org/Controllers/Contracting/FrontOfficeController.cs index b86d0ab4a..549d80942 100644 --- a/src/Yavsc.Org/Controllers/Contracting/FrontOfficeController.cs +++ b/src/Yavsc.Org/Controllers/Contracting/FrontOfficeController.cs @@ -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 userManager, IBillingService billing, ILoggerFactory loggerFactory, - IStringLocalizer SR) + IStringLocalizer SR, + IOptions siteSettings) { _context = context; _userManager = userManager; _logger = loggerFactory.CreateLogger(); _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) diff --git a/src/Yavsc.Org/Controllers/FileSystemController.cs b/src/Yavsc.Org/Controllers/FileSystemController.cs index e4f18b39c..21a3325ff 100644 --- a/src/Yavsc.Org/Controllers/FileSystemController.cs +++ b/src/Yavsc.Org/Controllers/FileSystemController.cs @@ -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.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); } } diff --git a/src/Yavsc.Org/Extensions/HostingExtensions.cs b/src/Yavsc.Org/Extensions/HostingExtensions.cs index e986620f1..567d05233 100644 --- a/src/Yavsc.Org/Extensions/HostingExtensions.cs +++ b/src/Yavsc.Org/Extensions/HostingExtensions.cs @@ -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,24 @@ 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) { - 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 +1267,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() diff --git a/src/Yavsc.Org/Helpers/TeXHelpers.cs b/src/Yavsc.Org/Helpers/TeXHelpers.cs index daacb7417..f7cc812fb 100644 --- a/src/Yavsc.Org/Helpers/TeXHelpers.cs +++ b/src/Yavsc.Org/Helpers/TeXHelpers.cs @@ -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")); diff --git a/src/Yavsc.Org/Services/BlogSpotService.cs b/src/Yavsc.Org/Services/BlogSpotService.cs index 39e9329f1..aa00d4121 100644 --- a/src/Yavsc.Org/Services/BlogSpotService.cs +++ b/src/Yavsc.Org/Services/BlogSpotService.cs @@ -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) { _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 ); diff --git a/src/Yavsc.Org/Startup.cs b/src/Yavsc.Org/Startup.cs index 558a95665..497ee6389 100644 --- a/src/Yavsc.Org/Startup.cs +++ b/src/Yavsc.Org/Startup.cs @@ -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(), environmentName); + CheckApp(siteSettings.Value, loggerFactory.CreateLogger(), 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")); } diff --git a/src/Yavsc.Org/ViewComponents/BillViewComponent.cs b/src/Yavsc.Org/ViewComponents/BillViewComponent.cs index 1db521f86..a4698e2f6 100644 --- a/src/Yavsc.Org/ViewComponents/BillViewComponent.cs +++ b/src/Yavsc.Org/ViewComponents/BillViewComponent.cs @@ -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 localizer; + private readonly SiteSettings siteSettings; - public BillViewComponent(ApplicationDbContext dbContext, + public BillViewComponent(ApplicationDbContext dbContext, IStringLocalizer localizer, - IBillingService billing) + IBillingService billing, + IOptions siteSettings) { this.billing = billing; this.dbContext = dbContext; this.localizer = localizer; + this.siteSettings = siteSettings.Value; } - public async Task InvokeAsync(string code, IBillable billable, OutputFormat format, bool asBill) + public async Task 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); - + } } diff --git a/src/Yavsc.Org/ViewComponents/DirectoryViewComponent.cs b/src/Yavsc.Org/ViewComponents/DirectoryViewComponent.cs index fea78afb0..fb8748d3c 100644 --- a/src/Yavsc.Org/ViewComponents/DirectoryViewComponent.cs +++ b/src/Yavsc.Org/ViewComponents/DirectoryViewComponent.cs @@ -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 _userManager; private readonly SignInManager _signInManager; - public DirectoryViewComponent(UserManager userManager, - SignInManager signInManager) + private readonly SiteSettings siteSettings; + + public DirectoryViewComponent( + UserManager userManager, + SignInManager signInManager, + IOptions siteSettings) { _userManager = userManager; _signInManager = signInManager; + this.siteSettings = siteSettings.Value; } public async Task 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; } } } diff --git a/src/Yavsc.Org/Views/Shared/Components/Bill/Bill_pdf.cshtml b/src/Yavsc.Org/Views/Shared/Components/Bill/Bill_pdf.cshtml index d053469a4..f49fad802 100644 --- a/src/Yavsc.Org/Views/Shared/Components/Bill/Bill_pdf.cshtml +++ b/src/Yavsc.Org/Views/Shared/Components/Bill/Bill_pdf.cshtml @@ -6,8 +6,8 @@ @using Yavsc.Helpers @model Yavsc.ViewModels.Gen.PdfGenerationViewModel -@{ - Model.GenerateEstimatePdf(); +@{ + ViewBag.Settings.GenerateEstimatePdf(Model); } @if (Model.Generated) {
diff --git a/src/Yavsc.Org/Views/Shared/Components/Estimate/Estimate_pdf.cshtml b/src/Yavsc.Org/Views/Shared/Components/Estimate/Estimate_pdf.cshtml index d053469a4..bef19b35a 100644 --- a/src/Yavsc.Org/Views/Shared/Components/Estimate/Estimate_pdf.cshtml +++ b/src/Yavsc.Org/Views/Shared/Components/Estimate/Estimate_pdf.cshtml @@ -7,7 +7,7 @@ @model Yavsc.ViewModels.Gen.PdfGenerationViewModel @{ - Model.GenerateEstimatePdf(); + SiteSettings.Value.GenerateEstimatePdf(Model); } @if (Model.Generated) {
diff --git a/src/Yavsc.Org/Views/Shared/_Nav.cshtml b/src/Yavsc.Org/Views/Shared/_Nav.cshtml index 23dc76fb7..385884fc0 100644 --- a/src/Yavsc.Org/Views/Shared/_Nav.cshtml +++ b/src/Yavsc.Org/Views/Shared/_Nav.cshtml @@ -1,13 +1,13 @@