From 7ca66d0467e994f1b2e494b8b539ca2310da5c7c Mon Sep 17 00:00:00 2001 From: Evgenii Kolosov <108291208+Ljutyj@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:04:24 +0300 Subject: [PATCH] VCST-2120: Fix icon URL in module list (#2863) fix: Fix icon URL in module list (#2863) Co-authored-by: Artem Dudarev --- .../Controllers/Api/ModulesController.cs | 51 +++++++++++++++++-- src/VirtoCommerce.Platform.Web/Startup.cs | 12 ++--- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs b/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs index 25428c1c48..f1412ccbb2 100644 --- a/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs +++ b/src/VirtoCommerce.Platform.Web/Controllers/Api/ModulesController.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; using VirtoCommerce.Platform.Core; @@ -42,6 +43,7 @@ public class ModulesController : Controller private readonly IPlatformRestarter _platformRestarter; private static readonly object _lockObject = new object(); private static readonly FormOptions _defaultFormOptions = new FormOptions(); + private readonly ILocalModuleCatalog _localModuleCatalog; public ModulesController( IExternalModuleCatalog externalModuleCatalog, @@ -52,7 +54,8 @@ public ModulesController( IOptions platformOptions, IOptions externalModuleCatalogOptions, IOptions localStorageModuleCatalogOptions, - IPlatformRestarter platformRestarter) + IPlatformRestarter platformRestarter, + ILocalModuleCatalog localModuleCatalog) { _externalModuleCatalog = externalModuleCatalog; _moduleInstaller = moduleInstaller; @@ -63,6 +66,7 @@ public ModulesController( _externalModuleCatalogOptions = externalModuleCatalogOptions.Value; _localStorageModuleCatalogOptions = localStorageModuleCatalogOptions.Value; _platformRestarter = platformRestarter; + _localModuleCatalog = localModuleCatalog; } /// @@ -90,11 +94,48 @@ public ActionResult GetModules() { EnsureModulesCatalogInitialized(); - var retVal = _externalModuleCatalog.Modules.OfType().OrderBy(x => x.Id).ThenBy(x => x.Version) - .Select(x => new ModuleDescriptor(x)) - .ToArray(); + var allModules = _externalModuleCatalog.Modules + .OfType() + .OrderBy(x => x.Id) + .ThenBy(x => x.Version) + .Select(x => new ModuleDescriptor(x)) + .ToList(); - return Ok(retVal); + _localModuleCatalog.Initialize(); + var localModules = _localModuleCatalog.Modules.OfType().ToDictionary(x => x.Id); + + foreach (var module in allModules.Where(x => !string.IsNullOrEmpty(x.IconUrl))) + { + module.IconUrl = localModules.TryGetValue(module.Id, out var localModule) && IconFileExists(localModule) + ? localModule.IconUrl + : null; + } + + return Ok(allModules); + } + + private static bool IconFileExists(ManifestModuleInfo module) + { + // PathString should start from "/" + var moduleIconUrl = module.IconUrl; + if (!moduleIconUrl.StartsWith('/')) + { + moduleIconUrl = "/" + moduleIconUrl; + } + + var basePath = new PathString($"/modules/$({module.Id})"); + var iconUrlPath = new PathString(moduleIconUrl); + + if (!iconUrlPath.StartsWithSegments(basePath, out var subPath) || + string.IsNullOrEmpty(subPath.Value) || + !Directory.Exists(module.FullPhysicalPath)) + { + return false; + } + + using var fileProvider = new PhysicalFileProvider(module.FullPhysicalPath); + + return fileProvider.GetFileInfo(subPath.Value).Exists; } /// diff --git a/src/VirtoCommerce.Platform.Web/Startup.cs b/src/VirtoCommerce.Platform.Web/Startup.cs index 578cce8aad..eda4e598ed 100644 --- a/src/VirtoCommerce.Platform.Web/Startup.cs +++ b/src/VirtoCommerce.Platform.Web/Startup.cs @@ -507,13 +507,13 @@ public void ConfigureServices(IServiceCollection services) var healthBuilder = services.AddHealthChecks() .AddCheck("Modules health", failureStatus: HealthStatus.Unhealthy, - tags: new[] { "Modules" }) + tags: ["Modules"]) .AddCheck("Cache health", failureStatus: HealthStatus.Degraded, - tags: new[] { "Cache" }) + tags: ["Cache"]) .AddCheck("Redis health", failureStatus: HealthStatus.Unhealthy, - tags: new[] { "Cache" }); + tags: ["Cache"]); var connectionString = Configuration.GetConnectionString("VirtoCommerce"); switch (databaseProvider) @@ -522,19 +522,19 @@ public void ConfigureServices(IServiceCollection services) healthBuilder.AddMySql(connectionString, name: "MySql health", failureStatus: HealthStatus.Unhealthy, - tags: new[] { "Database" }); + tags: ["Database"]); break; case "PostgreSql": healthBuilder.AddNpgSql(connectionString, name: "PostgreSql health", failureStatus: HealthStatus.Unhealthy, - tags: new[] { "Database" }); + tags: ["Database"]); break; default: healthBuilder.AddSqlServer(connectionString, name: "SQL Server health", failureStatus: HealthStatus.Unhealthy, - tags: new[] { "Database" }); + tags: ["Database"]); break; }