create server-side SiteService
This commit is contained in:
parent
7d1b4d916e
commit
ed7904b673
|
@ -17,7 +17,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddOqtaneScopedServices(this IServiceCollection services)
|
public static IServiceCollection AddOqtaneClientScopedServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddScoped<SiteState>();
|
services.AddScoped<SiteState>();
|
||||||
services.AddScoped<IInstallationService, InstallationService>();
|
services.AddScoped<IInstallationService, InstallationService>();
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
private List<Page> _pages;
|
private List<Page> _pages;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
public override string RenderMode => RenderModes.Static;
|
//public override string RenderMode => RenderModes.Static;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace Oqtane.Client
|
||||||
builder.Services.AddOqtaneAuthentication();
|
builder.Services.AddOqtaneAuthentication();
|
||||||
|
|
||||||
// register scoped core services
|
// register scoped core services
|
||||||
builder.Services.AddOqtaneScopedServices();
|
builder.Services.AddOqtaneClientScopedServices();
|
||||||
|
|
||||||
var serviceProvider = builder.Services.BuildServiceProvider();
|
var serviceProvider = builder.Services.BuildServiceProvider();
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,7 @@ namespace Oqtane.Services
|
||||||
|
|
||||||
public async Task<List<Site>> GetSitesAsync()
|
public async Task<List<Site>> GetSitesAsync()
|
||||||
{
|
{
|
||||||
List<Site> sites = await GetJsonAsync<List<Site>>(Apiurl);
|
return await GetJsonAsync<List<Site>>(Apiurl);
|
||||||
return sites.OrderBy(item => item.Name).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Site> GetSiteAsync(int siteId)
|
public async Task<Site> GetSiteAsync(int siteId)
|
||||||
|
|
|
@ -3,192 +3,49 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using System.Linq;
|
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Oqtane.Security;
|
using Oqtane.Services;
|
||||||
using System.Globalization;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
using Oqtane.Extensions;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
[Route(ControllerRoutes.ApiRoute)]
|
[Route(ControllerRoutes.ApiRoute)]
|
||||||
public class SiteController : Controller
|
public class SiteController : Controller
|
||||||
{
|
{
|
||||||
private readonly ISiteRepository _sites;
|
private readonly ISiteService _siteService;
|
||||||
private readonly IPageRepository _pages;
|
|
||||||
private readonly IThemeRepository _themes;
|
|
||||||
private readonly IModuleRepository _modules;
|
|
||||||
private readonly IPageModuleRepository _pageModules;
|
|
||||||
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
|
||||||
private readonly ILanguageRepository _languages;
|
|
||||||
private readonly IUserPermissions _userPermissions;
|
|
||||||
private readonly ISettingRepository _settings;
|
|
||||||
private readonly ISyncManager _syncManager;
|
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly IMemoryCache _cache;
|
|
||||||
private readonly Alias _alias;
|
|
||||||
|
|
||||||
public SiteController(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IModuleRepository modules, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache)
|
public SiteController(ISiteService siteService, ILogManager logger)
|
||||||
{
|
{
|
||||||
_sites = sites;
|
_siteService = siteService;
|
||||||
_pages = pages;
|
|
||||||
_themes = themes;
|
|
||||||
_modules = modules;
|
|
||||||
_pageModules = pageModules;
|
|
||||||
_moduleDefinitions = moduleDefinitions;
|
|
||||||
_languages = languages;
|
|
||||||
_userPermissions = userPermissions;
|
|
||||||
_settings = settings;
|
|
||||||
_syncManager = syncManager;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cache = cache;
|
|
||||||
_alias = tenantManager.GetAlias();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>
|
// GET: api/<controller>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
public IEnumerable<Site> Get()
|
public async Task<IEnumerable<Site>> Get()
|
||||||
{
|
{
|
||||||
return _sites.GetSites();
|
return await _siteService.GetSitesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/5
|
// GET api/<controller>/5
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public Site Get(int id)
|
public async Task<Site> Get(int id)
|
||||||
{
|
{
|
||||||
if (!User.Identity.IsAuthenticated)
|
return await _siteService.GetSiteAsync(id);
|
||||||
{
|
|
||||||
return _cache.GetOrCreate($"site:{HttpContext.GetAlias().SiteKey}", entry =>
|
|
||||||
{
|
|
||||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
|
||||||
return GetSite(id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetSite(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Site GetSite(int siteid)
|
|
||||||
{
|
|
||||||
var site = _sites.GetSite(siteid);
|
|
||||||
if (site != null && site.SiteId == _alias.SiteId)
|
|
||||||
{
|
|
||||||
// site settings
|
|
||||||
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
|
||||||
.Where(item => !item.IsPrivate || User.IsInRole(RoleNames.Admin))
|
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
|
||||||
|
|
||||||
// populate File Extensions
|
|
||||||
site.ImageFiles = site.Settings.ContainsKey("ImageFiles") && !string.IsNullOrEmpty(site.Settings["ImageFiles"])
|
|
||||||
? site.Settings["ImageFiles"] : Constants.ImageFiles;
|
|
||||||
site.UploadableFiles = site.Settings.ContainsKey("UploadableFiles") && !string.IsNullOrEmpty(site.Settings["UploadableFiles"])
|
|
||||||
? site.Settings["UploadableFiles"] : Constants.UploadableFiles;
|
|
||||||
|
|
||||||
// pages
|
|
||||||
List<Setting> settings = _settings.GetSettings(EntityNames.Page).ToList();
|
|
||||||
site.Pages = new List<Page>();
|
|
||||||
foreach (Page page in _pages.GetPages(site.SiteId))
|
|
||||||
{
|
|
||||||
if (!page.IsDeleted && _userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList) && (Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate) || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList)))
|
|
||||||
{
|
|
||||||
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
|
||||||
site.Pages.Add(page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
site.Pages = GetPagesHierarchy(site.Pages);
|
|
||||||
|
|
||||||
// modules
|
|
||||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(site.SiteId).ToList();
|
|
||||||
settings = _settings.GetSettings(EntityNames.Module).ToList();
|
|
||||||
site.Modules = new List<Module>();
|
|
||||||
foreach (PageModule pagemodule in _pageModules.GetPageModules(site.SiteId).Where(pm => !pm.IsDeleted && _userPermissions.IsAuthorized(User, PermissionNames.View, pm.Module.PermissionList)))
|
|
||||||
{
|
|
||||||
if(Utilities.IsPageModuleVisible(pagemodule.EffectiveDate, pagemodule.ExpiryDate) || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
|
||||||
{
|
|
||||||
Module module = new Module
|
|
||||||
{
|
|
||||||
SiteId = pagemodule.Module.SiteId,
|
|
||||||
ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName,
|
|
||||||
AllPages = pagemodule.Module.AllPages,
|
|
||||||
PermissionList = pagemodule.Module.PermissionList,
|
|
||||||
CreatedBy = pagemodule.Module.CreatedBy,
|
|
||||||
CreatedOn = pagemodule.Module.CreatedOn,
|
|
||||||
ModifiedBy = pagemodule.Module.ModifiedBy,
|
|
||||||
ModifiedOn = pagemodule.Module.ModifiedOn,
|
|
||||||
DeletedBy = pagemodule.DeletedBy,
|
|
||||||
DeletedOn = pagemodule.DeletedOn,
|
|
||||||
IsDeleted = pagemodule.IsDeleted,
|
|
||||||
|
|
||||||
PageModuleId = pagemodule.PageModuleId,
|
|
||||||
ModuleId = pagemodule.ModuleId,
|
|
||||||
PageId = pagemodule.PageId,
|
|
||||||
Title = pagemodule.Title,
|
|
||||||
Pane = pagemodule.Pane,
|
|
||||||
Order = pagemodule.Order,
|
|
||||||
ContainerType = pagemodule.ContainerType,
|
|
||||||
EffectiveDate = pagemodule.EffectiveDate,
|
|
||||||
ExpiryDate = pagemodule.ExpiryDate,
|
|
||||||
|
|
||||||
ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == pagemodule.Module.ModuleDefinitionName)),
|
|
||||||
|
|
||||||
Settings = settings
|
|
||||||
.Where(item => item.EntityId == pagemodule.ModuleId)
|
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue)
|
|
||||||
};
|
|
||||||
|
|
||||||
site.Modules.Add(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
site.Modules = site.Modules.OrderBy(item => item.PageId).ThenBy(item => item.Pane).ThenBy(item => item.Order).ToList();
|
|
||||||
|
|
||||||
// languages
|
|
||||||
site.Languages = _languages.GetLanguages(site.SiteId).ToList();
|
|
||||||
var defaultCulture = CultureInfo.GetCultureInfo(Constants.DefaultCulture);
|
|
||||||
site.Languages.Add(new Language { Code = defaultCulture.Name, Name = defaultCulture.DisplayName, Version = Constants.Version, IsDefault = !site.Languages.Any(l => l.IsDefault) });
|
|
||||||
|
|
||||||
// themes
|
|
||||||
site.Themes = _themes.FilterThemes(_themes.GetThemes().ToList());
|
|
||||||
|
|
||||||
return site;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (site != null)
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Get Attempt {SiteId}", siteid);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST api/<controller>
|
// POST api/<controller>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
public Site Post([FromBody] Site site)
|
public async Task<Site> Post([FromBody] Site site)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
site = _sites.AddSite(site);
|
site = await _siteService.AddSiteAsync(site);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Create);
|
|
||||||
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Create, "Site Added {Site}", site);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -202,20 +59,11 @@ namespace Oqtane.Controllers
|
||||||
// PUT api/<controller>/5
|
// PUT api/<controller>/5
|
||||||
[HttpPut("{id}")]
|
[HttpPut("{id}")]
|
||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
public Site Put(int id, [FromBody] Site site)
|
public async Task<Site> Put(int id, [FromBody] Site site)
|
||||||
{
|
{
|
||||||
var current = _sites.GetSite(site.SiteId, false);
|
if (ModelState.IsValid)
|
||||||
if (ModelState.IsValid && site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && site.SiteId == id && current != null)
|
|
||||||
{
|
{
|
||||||
site = _sites.UpdateSite(site);
|
site = await _siteService.UpdateSiteAsync(site);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Update);
|
|
||||||
string action = SyncEventActions.Refresh;
|
|
||||||
if (current.RenderMode != site.RenderMode || current.Runtime != site.Runtime)
|
|
||||||
{
|
|
||||||
action = SyncEventActions.Reload;
|
|
||||||
}
|
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, action);
|
|
||||||
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -229,60 +77,9 @@ namespace Oqtane.Controllers
|
||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
public void Delete(int id)
|
public async Task Delete(int id)
|
||||||
{
|
{
|
||||||
var site = _sites.GetSite(id);
|
await _siteService.DeleteSiteAsync(id);
|
||||||
if (site != null && site.SiteId == _alias.SiteId)
|
|
||||||
{
|
|
||||||
_sites.DeleteSite(id);
|
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Delete);
|
|
||||||
_logger.Log(id, LogLevel.Information, this, LogFunction.Delete, "Site Deleted {SiteId}", id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Delete Attempt {SiteId}", id);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Page> GetPagesHierarchy(List<Page> pages)
|
|
||||||
{
|
|
||||||
List<Page> hierarchy = new List<Page>();
|
|
||||||
Action<List<Page>, Page> getPath = null;
|
|
||||||
getPath = (pageList, page) =>
|
|
||||||
{
|
|
||||||
IEnumerable<Page> children;
|
|
||||||
int level;
|
|
||||||
if (page == null)
|
|
||||||
{
|
|
||||||
level = -1;
|
|
||||||
children = pages.Where(item => item.ParentId == null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
level = page.Level;
|
|
||||||
children = pages.Where(item => item.ParentId == page.PageId);
|
|
||||||
}
|
|
||||||
foreach (Page child in children)
|
|
||||||
{
|
|
||||||
child.Level = level + 1;
|
|
||||||
child.HasChildren = pages.Any(item => item.ParentId == child.PageId && !item.IsDeleted && item.IsNavigation);
|
|
||||||
hierarchy.Add(child);
|
|
||||||
getPath(pageList, child);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
pages = pages.OrderBy(item => item.Order).ToList();
|
|
||||||
getPath(pages, null);
|
|
||||||
|
|
||||||
// add any non-hierarchical items to the end of the list
|
|
||||||
foreach (Page page in pages)
|
|
||||||
{
|
|
||||||
if (hierarchy.Find(item => item.PageId == page.PageId) == null)
|
|
||||||
{
|
|
||||||
hierarchy.Add(page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hierarchy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,41 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
|
||||||
internal static IServiceCollection AddOqtaneServerScopedServices(this IServiceCollection services)
|
internal static IServiceCollection AddOqtaneServerScopedServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
services.AddScoped<Oqtane.Shared.SiteState>();
|
||||||
|
services.AddScoped<IInstallationService, InstallationService>();
|
||||||
|
services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
|
||||||
|
services.AddScoped<IThemeService, ThemeService>();
|
||||||
|
services.AddScoped<IAliasService, AliasService>();
|
||||||
|
services.AddScoped<ITenantService, TenantService>();
|
||||||
|
services.AddScoped<ISiteService, ServerSiteService>();
|
||||||
|
services.AddScoped<IPageService, PageService>();
|
||||||
|
services.AddScoped<IModuleService, ModuleService>();
|
||||||
|
services.AddScoped<IPageModuleService, PageModuleService>();
|
||||||
|
services.AddScoped<IUserService, UserService>();
|
||||||
|
services.AddScoped<IProfileService, ProfileService>();
|
||||||
|
services.AddScoped<IRoleService, RoleService>();
|
||||||
|
services.AddScoped<IUserRoleService, UserRoleService>();
|
||||||
|
services.AddScoped<ISettingService, SettingService>();
|
||||||
|
services.AddScoped<IPackageService, PackageService>();
|
||||||
|
services.AddScoped<ILogService, LogService>();
|
||||||
|
services.AddScoped<IJobService, JobService>();
|
||||||
|
services.AddScoped<IJobLogService, JobLogService>();
|
||||||
|
services.AddScoped<INotificationService, NotificationService>();
|
||||||
|
services.AddScoped<IFolderService, FolderService>();
|
||||||
|
services.AddScoped<IFileService, FileService>();
|
||||||
|
services.AddScoped<ISiteTemplateService, SiteTemplateService>();
|
||||||
|
services.AddScoped<ISqlService, SqlService>();
|
||||||
|
services.AddScoped<ISystemService, SystemService>();
|
||||||
|
services.AddScoped<ILocalizationService, LocalizationService>();
|
||||||
|
services.AddScoped<ILanguageService, LanguageService>();
|
||||||
|
services.AddScoped<IDatabaseService, DatabaseService>();
|
||||||
|
services.AddScoped<IUrlMappingService, UrlMappingService>();
|
||||||
|
services.AddScoped<IVisitorService, VisitorService>();
|
||||||
|
services.AddScoped<ISyncService, SyncService>();
|
||||||
|
|
||||||
|
// alternative used within infrastructure classes
|
||||||
services.AddScoped<Oqtane.Infrastructure.SiteState>();
|
services.AddScoped<Oqtane.Infrastructure.SiteState>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,11 @@ namespace Oqtane.Infrastructure
|
||||||
var config = context.RequestServices.GetService(typeof(IConfigManager)) as IConfigManager;
|
var config = context.RequestServices.GetService(typeof(IConfigManager)) as IConfigManager;
|
||||||
string path = context.Request.Path.ToString();
|
string path = context.Request.Path.ToString();
|
||||||
|
|
||||||
if (config.IsInstalled() && !path.StartsWith("/_")) // ignore Blazor framework requests
|
// note that in order to support Alias subfolders we used to ignore Blazor framework requests...
|
||||||
|
// but this does not work in static rendering as the web UI request originates from /_blazor
|
||||||
|
//if (config.IsInstalled() && !path.StartsWith("/_"))
|
||||||
|
|
||||||
|
if (config.IsInstalled())
|
||||||
{
|
{
|
||||||
// get alias (note that this also sets SiteState.Alias)
|
// get alias (note that this also sets SiteState.Alias)
|
||||||
var tenantManager = context.RequestServices.GetService(typeof(ITenantManager)) as ITenantManager;
|
var tenantManager = context.RequestServices.GetService(typeof(ITenantManager)) as ITenantManager;
|
||||||
|
|
288
Oqtane.Server/Services/SiteService.cs
Normal file
288
Oqtane.Server/Services/SiteService.cs
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
using Oqtane.Models;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using Oqtane.Documentation;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Oqtane.Infrastructure;
|
||||||
|
using Oqtane.Repository;
|
||||||
|
using Oqtane.Security;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Oqtane.Enums;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Net;
|
||||||
|
using Oqtane.Extensions;
|
||||||
|
|
||||||
|
namespace Oqtane.Services
|
||||||
|
{
|
||||||
|
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
|
||||||
|
public class ServerSiteService : ISiteService
|
||||||
|
{
|
||||||
|
private readonly ISiteRepository _sites;
|
||||||
|
private readonly IPageRepository _pages;
|
||||||
|
private readonly IThemeRepository _themes;
|
||||||
|
private readonly IPageModuleRepository _pageModules;
|
||||||
|
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||||
|
private readonly ILanguageRepository _languages;
|
||||||
|
private readonly IUserPermissions _userPermissions;
|
||||||
|
private readonly ISettingRepository _settings;
|
||||||
|
private readonly ISyncManager _syncManager;
|
||||||
|
private readonly ILogManager _logger;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
|
private readonly IHttpContextAccessor _accessor;
|
||||||
|
private readonly Alias _alias;
|
||||||
|
|
||||||
|
public ServerSiteService(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache, IHttpContextAccessor accessor)
|
||||||
|
{
|
||||||
|
_sites = sites;
|
||||||
|
_pages = pages;
|
||||||
|
_themes = themes;
|
||||||
|
_pageModules = pageModules;
|
||||||
|
_moduleDefinitions = moduleDefinitions;
|
||||||
|
_languages = languages;
|
||||||
|
_userPermissions = userPermissions;
|
||||||
|
_settings = settings;
|
||||||
|
_syncManager = syncManager;
|
||||||
|
_logger = logger;
|
||||||
|
_cache = cache;
|
||||||
|
_accessor = accessor;
|
||||||
|
_alias = tenantManager.GetAlias();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Site>> GetSitesAsync()
|
||||||
|
{
|
||||||
|
List<Site> sites = new List<Site>();
|
||||||
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
||||||
|
{
|
||||||
|
sites = _sites.GetSites().OrderBy(item => item.Name).ToList();
|
||||||
|
}
|
||||||
|
return await Task.Run(() => sites);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Site> GetSiteAsync(int siteId)
|
||||||
|
{
|
||||||
|
Site site = null;
|
||||||
|
if (!_accessor.HttpContext.User.Identity.IsAuthenticated)
|
||||||
|
{
|
||||||
|
site = _cache.GetOrCreate($"site:{_accessor.HttpContext.GetAlias().SiteKey}", entry =>
|
||||||
|
{
|
||||||
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
|
return GetSite(siteId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
site = GetSite(siteId);
|
||||||
|
}
|
||||||
|
return await Task.Run(() => site);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Site GetSite(int siteid)
|
||||||
|
{
|
||||||
|
var site = _sites.GetSite(siteid);
|
||||||
|
if (site != null && site.SiteId == _alias.SiteId)
|
||||||
|
{
|
||||||
|
// site settings
|
||||||
|
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
||||||
|
.Where(item => !item.IsPrivate || _accessor.HttpContext.User.IsInRole(RoleNames.Admin))
|
||||||
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
|
// populate File Extensions
|
||||||
|
site.ImageFiles = site.Settings.ContainsKey("ImageFiles") && !string.IsNullOrEmpty(site.Settings["ImageFiles"])
|
||||||
|
? site.Settings["ImageFiles"] : Constants.ImageFiles;
|
||||||
|
site.UploadableFiles = site.Settings.ContainsKey("UploadableFiles") && !string.IsNullOrEmpty(site.Settings["UploadableFiles"])
|
||||||
|
? site.Settings["UploadableFiles"] : Constants.UploadableFiles;
|
||||||
|
|
||||||
|
// pages
|
||||||
|
List<Setting> settings = _settings.GetSettings(EntityNames.Page).ToList();
|
||||||
|
site.Pages = new List<Page>();
|
||||||
|
foreach (Page page in _pages.GetPages(site.SiteId))
|
||||||
|
{
|
||||||
|
if (!page.IsDeleted && _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.View, page.PermissionList) && (Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate) || _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.Edit, page.PermissionList)))
|
||||||
|
{
|
||||||
|
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.Edit, page.PermissionList))
|
||||||
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
site.Pages.Add(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
site.Pages = GetPagesHierarchy(site.Pages);
|
||||||
|
|
||||||
|
// modules
|
||||||
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(site.SiteId).ToList();
|
||||||
|
settings = _settings.GetSettings(EntityNames.Module).ToList();
|
||||||
|
site.Modules = new List<Module>();
|
||||||
|
foreach (PageModule pagemodule in _pageModules.GetPageModules(site.SiteId).Where(pm => !pm.IsDeleted && _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.View, pm.Module.PermissionList)))
|
||||||
|
{
|
||||||
|
if (Utilities.IsPageModuleVisible(pagemodule.EffectiveDate, pagemodule.ExpiryDate) || _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||||
|
{
|
||||||
|
Module module = new Module
|
||||||
|
{
|
||||||
|
SiteId = pagemodule.Module.SiteId,
|
||||||
|
ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName,
|
||||||
|
AllPages = pagemodule.Module.AllPages,
|
||||||
|
PermissionList = pagemodule.Module.PermissionList,
|
||||||
|
CreatedBy = pagemodule.Module.CreatedBy,
|
||||||
|
CreatedOn = pagemodule.Module.CreatedOn,
|
||||||
|
ModifiedBy = pagemodule.Module.ModifiedBy,
|
||||||
|
ModifiedOn = pagemodule.Module.ModifiedOn,
|
||||||
|
DeletedBy = pagemodule.DeletedBy,
|
||||||
|
DeletedOn = pagemodule.DeletedOn,
|
||||||
|
IsDeleted = pagemodule.IsDeleted,
|
||||||
|
|
||||||
|
PageModuleId = pagemodule.PageModuleId,
|
||||||
|
ModuleId = pagemodule.ModuleId,
|
||||||
|
PageId = pagemodule.PageId,
|
||||||
|
Title = pagemodule.Title,
|
||||||
|
Pane = pagemodule.Pane,
|
||||||
|
Order = pagemodule.Order,
|
||||||
|
ContainerType = pagemodule.ContainerType,
|
||||||
|
EffectiveDate = pagemodule.EffectiveDate,
|
||||||
|
ExpiryDate = pagemodule.ExpiryDate,
|
||||||
|
|
||||||
|
ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == pagemodule.Module.ModuleDefinitionName)),
|
||||||
|
|
||||||
|
Settings = settings
|
||||||
|
.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(_accessor.HttpContext.User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||||
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue)
|
||||||
|
};
|
||||||
|
|
||||||
|
site.Modules.Add(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
site.Modules = site.Modules.OrderBy(item => item.PageId).ThenBy(item => item.Pane).ThenBy(item => item.Order).ToList();
|
||||||
|
|
||||||
|
// languages
|
||||||
|
site.Languages = _languages.GetLanguages(site.SiteId).ToList();
|
||||||
|
var defaultCulture = CultureInfo.GetCultureInfo(Constants.DefaultCulture);
|
||||||
|
site.Languages.Add(new Language { Code = defaultCulture.Name, Name = defaultCulture.DisplayName, Version = Constants.Version, IsDefault = !site.Languages.Any(l => l.IsDefault) });
|
||||||
|
|
||||||
|
// themes
|
||||||
|
site.Themes = _themes.FilterThemes(_themes.GetThemes().ToList());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (site != null)
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Get Attempt {SiteId}", siteid);
|
||||||
|
site = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return site;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Site> AddSiteAsync(Site site)
|
||||||
|
{
|
||||||
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
||||||
|
{
|
||||||
|
site = _sites.AddSite(site);
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Create);
|
||||||
|
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Create, "Site Added {Site}", site);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
site = null;
|
||||||
|
}
|
||||||
|
return await Task.Run(() => site);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Site> UpdateSiteAsync(Site site)
|
||||||
|
{
|
||||||
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Admin))
|
||||||
|
{
|
||||||
|
var current = _sites.GetSite(site.SiteId, false);
|
||||||
|
if (site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && current != null)
|
||||||
|
{
|
||||||
|
site = _sites.UpdateSite(site);
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Update);
|
||||||
|
string action = SyncEventActions.Refresh;
|
||||||
|
if (current.RenderMode != site.RenderMode || current.Runtime != site.Runtime)
|
||||||
|
{
|
||||||
|
action = SyncEventActions.Reload;
|
||||||
|
}
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, action);
|
||||||
|
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Put Attempt {Site}", site);
|
||||||
|
site = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
site = null;
|
||||||
|
}
|
||||||
|
return await Task.Run(() => site);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteSiteAsync(int siteId)
|
||||||
|
{
|
||||||
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
||||||
|
{
|
||||||
|
var site = _sites.GetSite(siteId);
|
||||||
|
if (site != null && site.SiteId == _alias.SiteId)
|
||||||
|
{
|
||||||
|
_sites.DeleteSite(siteId);
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Delete);
|
||||||
|
_logger.Log(siteId, LogLevel.Information, this, LogFunction.Delete, "Site Deleted {SiteId}", siteId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Delete Attempt {SiteId}", siteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Page> GetPagesHierarchy(List<Page> pages)
|
||||||
|
{
|
||||||
|
List<Page> hierarchy = new List<Page>();
|
||||||
|
Action<List<Page>, Page> getPath = null;
|
||||||
|
getPath = (pageList, page) =>
|
||||||
|
{
|
||||||
|
IEnumerable<Page> children;
|
||||||
|
int level;
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
|
level = -1;
|
||||||
|
children = pages.Where(item => item.ParentId == null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level = page.Level;
|
||||||
|
children = pages.Where(item => item.ParentId == page.PageId);
|
||||||
|
}
|
||||||
|
foreach (Page child in children)
|
||||||
|
{
|
||||||
|
child.Level = level + 1;
|
||||||
|
child.HasChildren = pages.Any(item => item.ParentId == child.PageId && !item.IsDeleted && item.IsNavigation);
|
||||||
|
hierarchy.Add(child);
|
||||||
|
getPath(pageList, child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pages = pages.OrderBy(item => item.Order).ToList();
|
||||||
|
getPath(pages, null);
|
||||||
|
|
||||||
|
// add any non-hierarchical items to the end of the list
|
||||||
|
foreach (Page page in pages)
|
||||||
|
{
|
||||||
|
if (hierarchy.Find(item => item.PageId == page.PageId) == null)
|
||||||
|
{
|
||||||
|
hierarchy.Add(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hierarchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Obsolete("This method is deprecated.", false)]
|
||||||
|
public void SetAlias(Alias alias)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,7 +70,6 @@ namespace Oqtane
|
||||||
|
|
||||||
// register scoped core services
|
// register scoped core services
|
||||||
services.AddScoped<IAuthorizationHandler, PermissionHandler>()
|
services.AddScoped<IAuthorizationHandler, PermissionHandler>()
|
||||||
.AddOqtaneScopedServices()
|
|
||||||
.AddOqtaneServerScopedServices();
|
.AddOqtaneServerScopedServices();
|
||||||
|
|
||||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user