Fix #3068 - support microsites in .NET MAUI
This commit is contained in:
@ -34,9 +34,9 @@ namespace Oqtane.Controllers
|
||||
private readonly IAliasRepository _aliases;
|
||||
private readonly ILogger<InstallationController> _filelogger;
|
||||
private readonly ITenantManager _tenantManager;
|
||||
private readonly ServerStateManager _serverState;
|
||||
private readonly IServerStateManager _serverState;
|
||||
|
||||
public InstallationController(IConfigManager configManager, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache, IHttpContextAccessor accessor, IAliasRepository aliases, ILogger<InstallationController> filelogger, ITenantManager tenantManager, ServerStateManager serverState)
|
||||
public InstallationController(IConfigManager configManager, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache, IHttpContextAccessor accessor, IAliasRepository aliases, ILogger<InstallationController> filelogger, ITenantManager tenantManager, IServerStateManager serverState)
|
||||
{
|
||||
_configManager = configManager;
|
||||
_installationManager = installationManager;
|
||||
@ -119,9 +119,9 @@ namespace Oqtane.Controllers
|
||||
|
||||
private List<ClientAssembly> GetAssemblyList()
|
||||
{
|
||||
int siteId = _tenantManager.GetAlias().SiteId;
|
||||
var siteKey = _tenantManager.GetAlias().SiteKey;
|
||||
|
||||
return _cache.GetOrCreate($"assemblieslist:{siteId}", entry =>
|
||||
return _cache.GetOrCreate($"assemblieslist:{siteKey}", entry =>
|
||||
{
|
||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
var assemblyList = new List<ClientAssembly>();
|
||||
@ -134,7 +134,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
// get site assemblies which should be downloaded to client
|
||||
var assemblies = _serverState.GetServerState(siteId).Assemblies;
|
||||
var assemblies = _serverState.GetServerState(siteKey).Assemblies;
|
||||
|
||||
// populate assembly list
|
||||
foreach (var assembly in assemblies)
|
||||
@ -179,9 +179,11 @@ namespace Oqtane.Controllers
|
||||
|
||||
private byte[] GetAssemblies(string list)
|
||||
{
|
||||
var siteKey = _tenantManager.GetAlias().SiteKey;
|
||||
|
||||
if (list == "*")
|
||||
{
|
||||
return _cache.GetOrCreate("assemblies", entry =>
|
||||
return _cache.GetOrCreate($"assemblies:{siteKey}", entry =>
|
||||
{
|
||||
return GetZIP(list);
|
||||
});
|
||||
|
@ -62,7 +62,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
services.AddSingleton<ILoggerProvider, FileLoggerProvider>();
|
||||
services.AddSingleton<AutoValidateAntiforgeryTokenFilter>();
|
||||
services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
|
||||
services.AddSingleton<ServerStateManager>();
|
||||
services.AddSingleton<IServerStateManager, ServerStateManager>();
|
||||
return services;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface IServerStateManager
|
||||
{
|
||||
ServerState GetServerState(string siteKey);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ namespace Oqtane.Infrastructure
|
||||
var config = context.RequestServices.GetService(typeof(IConfigManager)) as IConfigManager;
|
||||
string path = context.Request.Path.ToString();
|
||||
|
||||
|
||||
if (config.IsInstalled() && !path.StartsWith("/_blazor"))
|
||||
{
|
||||
// get alias (note that this also sets SiteState.Alias)
|
||||
@ -43,6 +44,14 @@ namespace Oqtane.Infrastructure
|
||||
});
|
||||
context.Items.Add(Constants.HttpContextSiteSettingsKey, sitesettings);
|
||||
|
||||
// handle first request to site
|
||||
var serverState = context.RequestServices.GetService(typeof(IServerStateManager)) as IServerStateManager;
|
||||
if (!serverState.GetServerState(alias.SiteKey).IsInitialized)
|
||||
{
|
||||
var sites = context.RequestServices.GetService(typeof(ISiteRepository)) as ISiteRepository;
|
||||
sites.InitializeSite(alias);
|
||||
}
|
||||
|
||||
// rewrite path by removing alias path prefix from reserved route (api,pages,files) requests for consistent routes
|
||||
if (!string.IsNullOrEmpty(alias.Path))
|
||||
{
|
||||
|
@ -5,9 +5,9 @@ namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class ServerState
|
||||
{
|
||||
public int SiteId { get; set; }
|
||||
public string SiteKey { get; set; }
|
||||
public List<string> Assemblies { get; set; } = new List<string>();
|
||||
public List<Resource>Scripts { get; set; } = new List<Resource>();
|
||||
public bool IsMigrated { get; set; } = false;
|
||||
public bool IsInitialized { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using Oqtane.Models;
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
// singleton
|
||||
public class ServerStateManager
|
||||
public class ServerStateManager : IServerStateManager
|
||||
{
|
||||
private List<ServerState> _serverStates { get; set; }
|
||||
|
||||
@ -14,36 +14,19 @@ namespace Oqtane.Infrastructure
|
||||
_serverStates = new List<ServerState>();
|
||||
}
|
||||
|
||||
public ServerState GetServerState(int siteId)
|
||||
public ServerState GetServerState(string siteKey)
|
||||
{
|
||||
var serverState = _serverStates.FirstOrDefault(item => item.SiteId == siteId);
|
||||
var serverState = _serverStates.FirstOrDefault(item => item.SiteKey == siteKey);
|
||||
if (serverState == null)
|
||||
{
|
||||
serverState = new ServerState();
|
||||
serverState.SiteId = siteId;
|
||||
serverState.SiteKey = siteKey;
|
||||
serverState.Assemblies = new List<string>();
|
||||
serverState.Scripts = new List<Resource>();
|
||||
return serverState;
|
||||
}
|
||||
else
|
||||
{
|
||||
return serverState;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetServerState(int siteId, ServerState serverState)
|
||||
{
|
||||
var serverstate = _serverStates.FirstOrDefault(item => item.SiteId == siteId);
|
||||
if (serverstate == null)
|
||||
{
|
||||
serverState.SiteId = siteId;
|
||||
serverState.IsInitialized = false;
|
||||
_serverStates.Add(serverState);
|
||||
}
|
||||
else
|
||||
{
|
||||
serverstate.Assemblies = serverState.Assemblies;
|
||||
serverstate.Scripts = serverState.Scripts;
|
||||
}
|
||||
return serverState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Oqtane.Models;
|
||||
@ -57,7 +58,7 @@ namespace Oqtane.Infrastructure
|
||||
alias.BaseUrl = "";
|
||||
if (httpcontext.Request.Headers.ContainsKey("User-Agent") && httpcontext.Request.Headers["User-Agent"] == Shared.Constants.MauiUserAgent)
|
||||
{
|
||||
alias.BaseUrl = alias.Protocol + alias.Name;
|
||||
alias.BaseUrl = alias.Protocol + alias.Name.Replace("/" + alias.Path, "");
|
||||
}
|
||||
_siteState.Alias = alias;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Oqtane.Repository;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -38,10 +37,11 @@ namespace Oqtane.Pages
|
||||
private readonly IVisitorRepository _visitors;
|
||||
private readonly IAliasRepository _aliases;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly ServerStateManager _serverState;
|
||||
private readonly IThemeRepository _themes;
|
||||
private readonly IServerStateManager _serverState;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public HostModel(IConfigManager configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, IJwtManager jwtManager, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors, IAliasRepository aliases, ISettingRepository settings, ServerStateManager serverState, ILogManager logger)
|
||||
public HostModel(IConfigManager configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, IJwtManager jwtManager, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors, IAliasRepository aliases, ISettingRepository settings, IThemeRepository themes, IServerStateManager serverState, ILogManager logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_tenantManager = tenantManager;
|
||||
@ -55,6 +55,7 @@ namespace Oqtane.Pages
|
||||
_visitors = visitors;
|
||||
_aliases = aliases;
|
||||
_settings = settings;
|
||||
_themes = themes;
|
||||
_serverState = serverState;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -113,7 +114,7 @@ namespace Oqtane.Pages
|
||||
}
|
||||
}
|
||||
|
||||
var site = _sites.InitializeSite(alias);
|
||||
var site = _sites.GetSite(alias.SiteId);
|
||||
if (site != null && (!site.IsDeleted || url.Contains("admin/site")) && site.Runtime != "Hybrid")
|
||||
{
|
||||
Route route = new Route(url, alias.Path);
|
||||
@ -167,12 +168,13 @@ namespace Oqtane.Pages
|
||||
}
|
||||
|
||||
// stylesheets
|
||||
var themes = _themes.GetThemes().ToList();
|
||||
var resources = new List<Resource>();
|
||||
if (string.IsNullOrEmpty(page.ThemeType))
|
||||
{
|
||||
page.ThemeType = site.DefaultThemeType;
|
||||
}
|
||||
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
||||
var theme = themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
||||
if (theme?.Resources != null)
|
||||
{
|
||||
resources.AddRange(theme.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet).ToList());
|
||||
@ -199,7 +201,7 @@ namespace Oqtane.Pages
|
||||
}
|
||||
HeadResources += ParseScripts(site.HeadContent);
|
||||
BodyResources += ParseScripts(site.BodyContent);
|
||||
var scripts = _serverState.GetServerState(site.SiteId).Scripts;
|
||||
var scripts = _serverState.GetServerState(alias.SiteKey).Scripts;
|
||||
foreach (var script in scripts)
|
||||
{
|
||||
AddScript(script, alias);
|
||||
|
@ -11,7 +11,7 @@ namespace Oqtane.Repository
|
||||
Site GetSite(int siteId);
|
||||
Site GetSite(int siteId, bool tracking);
|
||||
void DeleteSite(int siteId);
|
||||
Site InitializeSite(Alias alias);
|
||||
void InitializeSite(Alias alias);
|
||||
void CreatePages(Site site, List<PageTemplate> pageTemplates, Alias alias);
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ namespace Oqtane.Repository
|
||||
private readonly IPermissionRepository _permissions;
|
||||
private readonly ITenantManager _tenants;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly ServerStateManager _serverState;
|
||||
private readonly IServerStateManager _serverState;
|
||||
private readonly string settingprefix = "SiteEnabled:";
|
||||
|
||||
public ModuleDefinitionRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions, ITenantManager tenants, ISettingRepository settings, ServerStateManager serverState)
|
||||
public ModuleDefinitionRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions, ITenantManager tenants, ISettingRepository settings, IServerStateManager serverState)
|
||||
{
|
||||
_db = context;
|
||||
_cache = cache;
|
||||
@ -179,6 +179,8 @@ namespace Oqtane.Repository
|
||||
|
||||
if (siteId != -1)
|
||||
{
|
||||
var siteKey = _tenants.GetAlias().SiteKey;
|
||||
|
||||
// get all module definition permissions for site
|
||||
List<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList();
|
||||
|
||||
@ -186,7 +188,7 @@ namespace Oqtane.Repository
|
||||
var settings = _settings.GetSettings(EntityNames.ModuleDefinition).ToList();
|
||||
|
||||
// populate module definition site settings and permissions
|
||||
var serverState = _serverState.GetServerState(siteId);
|
||||
var serverState = _serverState.GetServerState(siteKey);
|
||||
foreach (ModuleDefinition moduledefinition in ModuleDefinitions)
|
||||
{
|
||||
moduledefinition.SiteId = siteId;
|
||||
@ -251,7 +253,6 @@ namespace Oqtane.Repository
|
||||
}
|
||||
}
|
||||
}
|
||||
_serverState.SetServerState(siteId, serverState);
|
||||
|
||||
// clean up any orphaned permissions
|
||||
var ids = new HashSet<int>(ModuleDefinitions.Select(item => item.ModuleDefinitionId));
|
||||
|
@ -27,13 +27,13 @@ namespace Oqtane.Repository
|
||||
private readonly IThemeRepository _themeRepository;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IConfigurationRoot _config;
|
||||
private readonly ServerStateManager _serverState;
|
||||
private readonly IServerStateManager _serverState;
|
||||
private readonly ILogManager _logger;
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
public SiteRepository(TenantDBContext context, IRoleRepository roleRepository, IProfileRepository profileRepository, IFolderRepository folderRepository, IPageRepository pageRepository,
|
||||
IModuleRepository moduleRepository, IPageModuleRepository pageModuleRepository, IModuleDefinitionRepository moduleDefinitionRepository, IThemeRepository themeRepository, IServiceProvider serviceProvider,
|
||||
IConfigurationRoot config, ServerStateManager serverState, ILogManager logger)
|
||||
IConfigurationRoot config, IServerStateManager serverState, ILogManager logger)
|
||||
{
|
||||
_db = context;
|
||||
_roleRepository = roleRepository;
|
||||
@ -95,23 +95,25 @@ namespace Oqtane.Repository
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
public Site InitializeSite(Alias alias)
|
||||
public void InitializeSite(Alias alias)
|
||||
{
|
||||
var site = GetSite(alias.SiteId);
|
||||
|
||||
// load themes and module definitions
|
||||
site.Themes = _themeRepository.GetThemes().ToList();
|
||||
var moduleDefinitions = _moduleDefinitionRepository.GetModuleDefinitions(alias.SiteId);
|
||||
|
||||
// site migrations
|
||||
var serverstate = _serverState.GetServerState(alias.SiteId);
|
||||
if (!serverstate.IsMigrated)
|
||||
var serverstate = _serverState.GetServerState(alias.SiteKey);
|
||||
if (!serverstate.IsInitialized)
|
||||
{
|
||||
// ensure migrations are only executed once
|
||||
// ensure site initialization is only executed once
|
||||
lock (_lock)
|
||||
{
|
||||
if (!serverstate.IsMigrated)
|
||||
if (!serverstate.IsInitialized)
|
||||
{
|
||||
var site = GetSite(alias.SiteId);
|
||||
|
||||
// initialize theme Assemblies and Scripts
|
||||
site.Themes = _themeRepository.GetThemes().ToList();
|
||||
|
||||
// initialize module Assemblies and Scripts
|
||||
var moduleDefinitions = _moduleDefinitionRepository.GetModuleDefinitions(alias.SiteId);
|
||||
|
||||
// execute migrations
|
||||
var version = ProcessSiteMigrations(alias, site);
|
||||
version = ProcessPageTemplates(alias, site, moduleDefinitions, version);
|
||||
if (site.Version != version)
|
||||
@ -119,13 +121,11 @@ namespace Oqtane.Repository
|
||||
site.Version = version;
|
||||
UpdateSite(site);
|
||||
}
|
||||
serverstate.IsMigrated = true;
|
||||
_serverState.SetServerState(alias.SiteId, serverstate);
|
||||
|
||||
serverstate.IsInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return site;
|
||||
}
|
||||
}
|
||||
|
||||
private string ProcessSiteMigrations(Alias alias, Site site)
|
||||
|
@ -22,10 +22,10 @@ namespace Oqtane.Repository
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ITenantManager _tenants;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly ServerStateManager _serverState;
|
||||
private readonly IServerStateManager _serverState;
|
||||
private readonly string settingprefix = "SiteEnabled:";
|
||||
|
||||
public ThemeRepository(MasterDBContext context, IMemoryCache cache, ITenantManager tenants, ISettingRepository settings, ServerStateManager serverState)
|
||||
public ThemeRepository(MasterDBContext context, IMemoryCache cache, ITenantManager tenants, ISettingRepository settings, IServerStateManager serverState)
|
||||
{
|
||||
_db = context;
|
||||
_cache = cache;
|
||||
@ -157,11 +157,13 @@ namespace Oqtane.Repository
|
||||
|
||||
if (siteId != -1)
|
||||
{
|
||||
var siteKey = _tenants.GetAlias().SiteKey;
|
||||
|
||||
// get settings for site
|
||||
var settings = _settings.GetSettings(EntityNames.Theme).ToList();
|
||||
|
||||
// populate theme site settings
|
||||
var serverState = _serverState.GetServerState(siteId);
|
||||
var serverState = _serverState.GetServerState(siteKey);
|
||||
foreach (Theme theme in Themes)
|
||||
{
|
||||
theme.SiteId = siteId;
|
||||
@ -206,7 +208,6 @@ namespace Oqtane.Repository
|
||||
}
|
||||
}
|
||||
}
|
||||
_serverState.SetServerState(siteId, serverState);
|
||||
}
|
||||
|
||||
return Themes;
|
||||
|
Reference in New Issue
Block a user