From 066c616eca4456299c3eecceeab277358951ebed Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 17 Feb 2020 19:48:26 -0500 Subject: [PATCH] authorization changes --- Oqtane.Client/Modules/Admin/Logs/Index.razor | 101 +++++----- .../Admin/ModuleDefinitions/Edit.razor | 4 +- .../Modules/Admin/Modules/Settings.razor | 2 +- Oqtane.Client/Modules/Admin/Pages/Add.razor | 8 +- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 8 +- Oqtane.Client/Modules/Admin/Sites/Add.razor | 8 +- Oqtane.Client/Modules/Admin/Sites/Edit.razor | 16 +- Oqtane.Client/Modules/Admin/Sites/Index.razor | 5 +- Oqtane.Client/Modules/ModuleBase.cs | 7 - Oqtane.Client/Services/AliasService.cs | 17 ++ Oqtane.Client/Services/FolderService.cs | 9 + .../Services/Interfaces/IAliasService.cs | 2 + .../Interfaces/IModuleDefinitionService.cs | 2 + .../Services/Interfaces/IPageService.cs | 1 + .../Services/Interfaces/ISettingService.cs | 4 + .../Services/ModuleDefinitionService.cs | 45 +++-- Oqtane.Client/Services/PageService.cs | 14 ++ Oqtane.Client/Services/SettingService.cs | 10 + Oqtane.Client/Shared/PageState.cs | 3 - Oqtane.Client/Shared/SiteRouter.razor | 129 +++++-------- Oqtane.Client/Themes/ContainerBase.cs | 8 - .../Themes/Controls/ControlPanel.razor | 83 ++------ .../Themes/Controls/ModuleActions.razor | 2 +- Oqtane.Server/Controllers/AliasController.cs | 24 +++ Oqtane.Server/Controllers/FileController.cs | 38 +++- Oqtane.Server/Controllers/FolderController.cs | 73 +++++-- .../Controllers/InstallationController.cs | 2 +- Oqtane.Server/Controllers/JobController.cs | 2 + Oqtane.Server/Controllers/ModuleController.cs | 179 +++++++----------- .../Controllers/ModuleDefinitionController.cs | 34 +++- Oqtane.Server/Controllers/PageController.cs | 137 ++++++++++++-- .../Controllers/PageModuleController.cs | 52 ++++- .../Controllers/PermissionController.cs | 72 ------- Oqtane.Server/Controllers/RoleController.cs | 2 + .../Controllers/SettingController.cs | 91 +++++++-- Oqtane.Server/Controllers/SiteController.cs | 1 + Oqtane.Server/Controllers/ThemeController.cs | 1 + Oqtane.Server/Controllers/UserController.cs | 26 ++- .../Controllers/UserRoleController.cs | 2 + .../Interfaces/IModuleDefinitionRepository.cs | 2 +- .../Interfaces/IModuleRepository.cs | 2 + .../Repository/ModuleDefinitionRepository.cs | 64 ++++--- Oqtane.Server/Repository/ModuleRepository.cs | 113 ++++++++++- Oqtane.Shared/Models/Module.cs | 4 + 44 files changed, 880 insertions(+), 529 deletions(-) delete mode 100644 Oqtane.Server/Controllers/PermissionController.cs diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 6bb72e99..4b89cafb 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -8,56 +8,65 @@ } else { -
- - - - - - -
+ + + + + + +
+ + + + + + + + +
+ @if (Logs.Any()) { - -
-   - Date - Level - Feature - Function -
- - - @context.LogDate - @context.Level - @context.Feature - @context.Function - -
+ +
+   + Date + Level + Feature + Function +
+ + + @context.LogDate + @context.Level + @context.Feature + @context.Function + +
} else { -

No Logs Match The Criteria Specified

+

No Logs Match The Criteria Specified

} } @@ -159,4 +168,4 @@ else } return classname; } -} \ No newline at end of file +} diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index 21d90d91..68d535cd 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -45,7 +45,7 @@ try { ModuleDefinitionId = Int32.Parse(PageState.QueryString["id"]); - ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault(); + ModuleDefinition moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(ModuleDefinitionId, ModuleState.SiteId); if (moduledefinition != null) { name = moduledefinition.Name; @@ -67,7 +67,7 @@ { try { - ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault(); + ModuleDefinition moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(ModuleDefinitionId, ModuleState.SiteId); moduledefinition.Permissions = permissiongrid.GetPermissions(); await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition); await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition); diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index 3c81ef2a..14d8f9eb 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -81,7 +81,7 @@ containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync()); containertype = ModuleState.ContainerType; permissions = ModuleState.Permissions; - permissionnames = PageState.ModuleDefinitions.Find(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).PermissionNames; + permissionnames = ModuleState.ModuleDefinition.PermissionNames; pageid = ModuleState.PageId.ToString(); DynamicComponent = builder => diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 9b642b02..538f94af 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -148,6 +148,7 @@ Dictionary themes = new Dictionary(); Dictionary panelayouts = new Dictionary(); + List Themes; List pages; string name; string path = ""; @@ -169,13 +170,14 @@ { try { + Themes = await ThemeService.GetThemesAsync(); pages = PageState.Pages; children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - themes = ThemeService.GetThemeTypes(PageState.Themes); + themes = ThemeService.GetThemeTypes(Themes); themetype = PageState.Site.DefaultThemeType; - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); layouttype = PageState.Site.DefaultLayoutType; List permissionstrings = new List(); @@ -219,7 +221,7 @@ themetype = (string)e.Value; if (themetype != "") { - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); } else { diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 520aecfe..10cff51b 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -169,6 +169,7 @@ Dictionary themes = new Dictionary(); Dictionary panelayouts = new Dictionary(); + List Themes; List pages; int PageId; string name; @@ -198,10 +199,11 @@ { try { + Themes = await ThemeService.GetThemesAsync(); pages = PageState.Pages; children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - themes = ThemeService.GetThemeTypes(PageState.Themes); + themes = ThemeService.GetThemeTypes(Themes); PageId = Int32.Parse(PageState.QueryString["id"]); Page page = PageState.Pages.Where(item => item.PageId == PageId).FirstOrDefault(); @@ -226,7 +228,7 @@ ispersonalizable = page.IsPersonalizable.ToString(); mode = (page.EditMode) ? "edit" : "view"; themetype = page.ThemeType; - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); layouttype = page.LayoutType; icon = page.Icon; permissions = page.Permissions; @@ -282,7 +284,7 @@ themetype = (string)e.Value; if (themetype != "") { - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); } else { diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index 94face09..b1e6820f 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -125,6 +125,7 @@ else Dictionary panelayouts = new Dictionary(); Dictionary containers = new Dictionary(); + List Themes; List tenants; string tenantid = "-1"; string name = ""; @@ -139,10 +140,11 @@ else protected override async Task OnInitializedAsync() { + Themes = await ThemeService.GetThemesAsync(); tenants = await TenantService.GetTenantsAsync(); urls = PageState.Alias.Name; - themes = ThemeService.GetThemeTypes(PageState.Themes); - containers = ThemeService.GetContainerTypes(PageState.Themes); + themes = ThemeService.GetThemeTypes(Themes); + containers = ThemeService.GetContainerTypes(Themes); username = Constants.HostUser; } @@ -175,7 +177,7 @@ else themetype = (string)e.Value; if (themetype != "") { - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); } else { diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index da99c044..5a07fce7 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -157,6 +157,7 @@ Dictionary panelayouts; Dictionary containers; + List Themes; Alias Alias; int siteid; string name = ""; @@ -186,14 +187,15 @@ { try { - Alias = PageState.Aliases.Where(item => item.AliasId == Int32.Parse(PageState.QueryString["id"])).FirstOrDefault(); + Themes = await ThemeService.GetThemesAsync(); + aliases = await AliasService.GetAliasesAsync(); + Alias = aliases.Where(item => item.AliasId == int.Parse(PageState.QueryString["id"])).FirstOrDefault(); siteid = Alias.SiteId; Site site = await SiteService.GetSiteAsync(siteid, Alias); if (site != null) { name = site.Name; - aliases = PageState.Aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList(); - foreach (Alias alias in aliases) + foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) { urls += alias.Name + "\n"; } @@ -202,7 +204,7 @@ logofileid = site.LogoFileId.Value; } themetype = site.DefaultThemeType; - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); layouttype = site.DefaultLayoutType; containertype = site.DefaultContainerType; @@ -222,8 +224,8 @@ isdeleted = site.IsDeleted.ToString(); } - themes = ThemeService.GetThemeTypes(PageState.Themes); - containers = ThemeService.GetContainerTypes(PageState.Themes); + themes = ThemeService.GetThemeTypes(Themes); + containers = ThemeService.GetContainerTypes(Themes); } catch (Exception ex) { @@ -239,7 +241,7 @@ themetype = (string)e.Value; if (themetype != "") { - panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype); + panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); } else { diff --git a/Oqtane.Client/Modules/Admin/Sites/Index.razor b/Oqtane.Client/Modules/Admin/Sites/Index.razor index 46152dee..7133f8b5 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Index.razor @@ -32,13 +32,14 @@ else List sites; string scheme; - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { Uri uri = new Uri(NavigationManager.Uri); scheme = uri.Scheme + "://"; + List aliases = await AliasService.GetAliasesAsync(); sites = new List(); - foreach (Alias alias in PageState.Aliases.OrderBy(item => item.Name)) + foreach (Alias alias in aliases) { if (!sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId)) { diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index c2ae550e..778c9633 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -29,13 +29,6 @@ namespace Oqtane.Modules [CascadingParameter] protected ModuleInstance ModuleInstance { get; set; } - protected ModuleDefinition ModuleDefinition - { - get - { - return PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).FirstOrDefault(); - } - } // optional interface properties public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security diff --git a/Oqtane.Client/Services/AliasService.cs b/Oqtane.Client/Services/AliasService.cs index 6fa109b5..c60fed12 100644 --- a/Oqtane.Client/Services/AliasService.cs +++ b/Oqtane.Client/Services/AliasService.cs @@ -5,6 +5,8 @@ using System.Linq; using Microsoft.AspNetCore.Components; using System.Collections.Generic; using Oqtane.Shared; +using System.Net; +using System; namespace Oqtane.Services { @@ -37,6 +39,21 @@ namespace Oqtane.Services return await http.GetJsonAsync(apiurl + "/" + AliasId.ToString()); } + public async Task GetAliasAsync(string Url) + { + Uri uri = new Uri(Url); + string name = uri.Authority; + if (uri.Segments.Count() > 1) + { + name += "/" + uri.Segments[1]; + } + if (name.EndsWith("/")) + { + name = name.Substring(0, name.Length - 1); + } + return await http.GetJsonAsync(apiurl + "/name/" + WebUtility.UrlEncode(name)); + } + public async Task AddAliasAsync(Alias alias) { return await http.PostJsonAsync(apiurl, alias); diff --git a/Oqtane.Client/Services/FolderService.cs b/Oqtane.Client/Services/FolderService.cs index 4ece5538..73ab4d74 100644 --- a/Oqtane.Client/Services/FolderService.cs +++ b/Oqtane.Client/Services/FolderService.cs @@ -87,6 +87,15 @@ namespace Oqtane.Services }; Folders = Folders.OrderBy(item => item.Order).ToList(); GetPath(Folders, null); + + // add any non-hierarchical items to the end of the list + foreach(Folder folder in Folders) + { + if (hierarchy.Find(item => item.FolderId == folder.FolderId) == null) + { + hierarchy.Add(folder); + } + } return hierarchy; } } diff --git a/Oqtane.Client/Services/Interfaces/IAliasService.cs b/Oqtane.Client/Services/Interfaces/IAliasService.cs index b9b515ac..9ecfa221 100644 --- a/Oqtane.Client/Services/Interfaces/IAliasService.cs +++ b/Oqtane.Client/Services/Interfaces/IAliasService.cs @@ -10,6 +10,8 @@ namespace Oqtane.Services Task GetAliasAsync(int AliasId); + Task GetAliasAsync(string Url); + Task AddAliasAsync(Alias Alias); Task UpdateAliasAsync(Alias Alias); diff --git a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs index b7341249..aad9b193 100644 --- a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs +++ b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs @@ -7,8 +7,10 @@ namespace Oqtane.Services public interface IModuleDefinitionService { Task> GetModuleDefinitionsAsync(int SiteId); + Task GetModuleDefinitionAsync(int ModuleDefinitionId, int SiteId); Task UpdateModuleDefinitionAsync(ModuleDefinition ModuleDefinition); Task InstallModuleDefinitionsAsync(); Task DeleteModuleDefinitionAsync(int ModuleDefinitionId, int SiteId); + Task LoadModuleDefinitionsAsync(int SiteId); } } diff --git a/Oqtane.Client/Services/Interfaces/IPageService.cs b/Oqtane.Client/Services/Interfaces/IPageService.cs index d3ab967b..35ae6a2f 100644 --- a/Oqtane.Client/Services/Interfaces/IPageService.cs +++ b/Oqtane.Client/Services/Interfaces/IPageService.cs @@ -10,6 +10,7 @@ namespace Oqtane.Services Task GetPageAsync(int PageId); Task GetPageAsync(int PageId, int UserId); Task AddPageAsync(Page Page); + Task AddPageAsync(int PageId, int UserId); Task UpdatePageAsync(Page Page); Task UpdatePageOrderAsync(int SiteId, int PageId, int? ParentId); Task DeletePageAsync(int PageId); diff --git a/Oqtane.Client/Services/Interfaces/ISettingService.cs b/Oqtane.Client/Services/Interfaces/ISettingService.cs index 66647129..6f99912e 100644 --- a/Oqtane.Client/Services/Interfaces/ISettingService.cs +++ b/Oqtane.Client/Services/Interfaces/ISettingService.cs @@ -30,6 +30,10 @@ namespace Oqtane.Services Task UpdateUserSettingsAsync(Dictionary UserSettings, int UserId); + Task> GetFolderSettingsAsync(int FolderId); + + Task UpdateFolderSettingsAsync(Dictionary FolderSettings, int FolderId); + Task> GetSettingsAsync(string EntityName, int EntityId); Task UpdateSettingsAsync(Dictionary Settings, string EntityName, int EntityId); diff --git a/Oqtane.Client/Services/ModuleDefinitionService.cs b/Oqtane.Client/Services/ModuleDefinitionService.cs index 19791a9d..aadb2dcb 100644 --- a/Oqtane.Client/Services/ModuleDefinitionService.cs +++ b/Oqtane.Client/Services/ModuleDefinitionService.cs @@ -30,8 +30,34 @@ namespace Oqtane.Services public async Task> GetModuleDefinitionsAsync(int SiteId) { - // get list of modules from the server List moduledefinitions = await http.GetJsonAsync>(apiurl + "?siteid=" + SiteId.ToString()); + return moduledefinitions.OrderBy(item => item.Name).ToList(); + } + + public async Task GetModuleDefinitionAsync(int ModuleDefinitionId, int SiteId) + { + return await http.GetJsonAsync(apiurl + "/" + ModuleDefinitionId.ToString() + "?siteid=" + SiteId.ToString()); + } + + public async Task UpdateModuleDefinitionAsync(ModuleDefinition ModuleDefinition) + { + await http.PutJsonAsync(apiurl + "/" + ModuleDefinition.ModuleDefinitionId.ToString(), ModuleDefinition); + } + + public async Task InstallModuleDefinitionsAsync() + { + await http.GetJsonAsync>(apiurl + "/install"); + } + + public async Task DeleteModuleDefinitionAsync(int ModuleDefinitionId, int SiteId) + { + await http.DeleteAsync(apiurl + "/" + ModuleDefinitionId.ToString() + "?siteid=" + SiteId.ToString()); + } + + public async Task LoadModuleDefinitionsAsync(int SiteId) + { + // get list of modules from the server + List moduledefinitions = await GetModuleDefinitionsAsync(SiteId); // get list of loaded assemblies on the client ( in the client-side hosting module the browser client has its own app domain ) Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); @@ -60,23 +86,6 @@ namespace Oqtane.Services Assembly.Load(bytes); } } - - return moduledefinitions.OrderBy(item => item.Name).ToList(); - } - - public async Task UpdateModuleDefinitionAsync(ModuleDefinition ModuleDefinition) - { - await http.PutJsonAsync(apiurl + "/" + ModuleDefinition.ModuleDefinitionId.ToString(), ModuleDefinition); - } - - public async Task InstallModuleDefinitionsAsync() - { - await http.GetJsonAsync>(apiurl + "/install"); - } - - public async Task DeleteModuleDefinitionAsync(int ModuleDefinitionId, int SiteId) - { - await http.DeleteAsync(apiurl + "/" + ModuleDefinitionId.ToString() + "?siteid=" + SiteId.ToString()); } } } diff --git a/Oqtane.Client/Services/PageService.cs b/Oqtane.Client/Services/PageService.cs index ddcd3324..92607162 100644 --- a/Oqtane.Client/Services/PageService.cs +++ b/Oqtane.Client/Services/PageService.cs @@ -49,6 +49,11 @@ namespace Oqtane.Services return await http.PostJsonAsync(apiurl, Page); } + public async Task AddPageAsync(int PageId, int UserId) + { + return await http.PostJsonAsync(apiurl + "/" + PageId.ToString() + "?userid=" + UserId.ToString(), null); + } + public async Task UpdatePageAsync(Page Page) { return await http.PutJsonAsync(apiurl + "/" + Page.PageId.ToString(), Page); @@ -92,6 +97,15 @@ namespace Oqtane.Services }; 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; } } diff --git a/Oqtane.Client/Services/SettingService.cs b/Oqtane.Client/Services/SettingService.cs index e92de5da..06c6534c 100644 --- a/Oqtane.Client/Services/SettingService.cs +++ b/Oqtane.Client/Services/SettingService.cs @@ -86,6 +86,16 @@ namespace Oqtane.Services await UpdateSettingsAsync(UserSettings, "User", UserId); } + public async Task> GetFolderSettingsAsync(int FolderId) + { + return await GetSettingsAsync("Folder", FolderId); + } + + public async Task UpdateFolderSettingsAsync(Dictionary FolderSettings, int FolderId) + { + await UpdateSettingsAsync(FolderSettings, "Folder", FolderId); + } + public async Task> GetSettingsAsync(string EntityName, int EntityId) { Dictionary dictionary = new Dictionary(); diff --git a/Oqtane.Client/Shared/PageState.cs b/Oqtane.Client/Shared/PageState.cs index 37beb6f2..c8003159 100644 --- a/Oqtane.Client/Shared/PageState.cs +++ b/Oqtane.Client/Shared/PageState.cs @@ -6,9 +6,6 @@ namespace Oqtane.Shared { public class PageState { - public List ModuleDefinitions { get; set; } - public List Themes { get; set; } - public List Aliases { get; set; } public Alias Alias { get; set; } public Site Site { get; set; } public List Pages { get; set; } diff --git a/Oqtane.Client/Shared/SiteRouter.razor b/Oqtane.Client/Shared/SiteRouter.razor index a04c759f..2438ed57 100644 --- a/Oqtane.Client/Shared/SiteRouter.razor +++ b/Oqtane.Client/Shared/SiteRouter.razor @@ -10,7 +10,6 @@ @inject IUserService UserService @inject IModuleService ModuleService @inject IModuleDefinitionService ModuleDefinitionService -@inject IThemeService ThemeService @implements IHandleAfterRender @DynamicComponent @@ -67,9 +66,6 @@ private async Task Refresh() { - List moduledefinitions; - List themes; - List aliases; Alias alias; Site site; List pages; @@ -107,21 +103,18 @@ if (PageState == null || reload == Reload.Application) { - themes = await ThemeService.GetThemesAsync(); - aliases = await AliasService.GetAliasesAsync(); alias = null; } else { - themes = PageState.Themes; - aliases = PageState.Aliases; alias = PageState.Alias; } // check if site has changed - if (alias == null || GetAlias(_absoluteUri, aliases).Name != alias.Name) + Alias current = await AliasService.GetAliasAsync(_absoluteUri); + if (alias == null || current.Name != alias.Name) { - alias = GetAlias(_absoluteUri, aliases); + alias = current; SiteState.Alias = alias; // set state for services reload = Reload.Site; } @@ -137,12 +130,13 @@ { if (PageState == null || reload >= Reload.Site) { - moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(site.SiteId); +#if WASM + ModuleDefinitionService.LoadModuleDefinitionsAsync(site.SiteId); // download assemblies to browser when running client-side +#endif pages = await PageService.GetPagesAsync(site.SiteId); } else { - moduledefinitions = PageState.ModuleDefinitions; pages = PageState.Pages; } @@ -192,7 +186,7 @@ } // check if page has changed - if (page.Path != path) + if (page != null && page.Path != path) { page = pages.Where(item => item.Path == path).FirstOrDefault(); reload = Reload.Page; @@ -226,9 +220,6 @@ page = await ProcessPage(page, site, user); pagestate = new PageState(); - pagestate.ModuleDefinitions = moduledefinitions; - pagestate.Themes = themes; - pagestate.Aliases = aliases; pagestate.Alias = alias; pagestate.Site = site; pagestate.Pages = pages; @@ -247,7 +238,7 @@ if (PageState == null || reload >= Reload.Page) { modules = await ModuleService.GetModulesAsync(site.SiteId); - modules = ProcessModules(modules, moduledefinitions, page.PageId, pagestate.ModuleId, pagestate.Action, page.Panes, site.DefaultContainerType); + modules = ProcessModules(modules, page.PageId, pagestate.ModuleId, pagestate.Action, page.Panes, site.DefaultContainerType); } else { @@ -270,7 +261,10 @@ else { // page does not exist - NavigationManager.NavigateTo(""); + if (path != "") + { + NavigationManager.NavigateTo(""); + } } } else @@ -353,58 +347,52 @@ return page; } - private List ProcessModules(List modules, List moduledefinitions, int pageid, int moduleid, string control, string panes, string defaultcontainertype) + private List ProcessModules(List modules, int pageid, int moduleid, string control, string panes, string defaultcontainertype) { - ModuleDefinition moduledefinition; Dictionary paneindex = new Dictionary(); foreach (Module module in modules) { - // set the type based on the template and action - moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); - if (moduledefinition != null) + string typename = module.ModuleDefinition.ControlTypeTemplate; + if (module.ModuleId == moduleid && control != "") { - string typename = moduledefinition.ControlTypeTemplate; - if (module.ModuleId == moduleid && control != "") + // check if the module defines custom routes + if (module.ModuleDefinition.ControlTypeRoutes != "") { - // check if the module defines custom routes - if (moduledefinition.ControlTypeRoutes != "") + foreach (string route in module.ModuleDefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { - foreach (string route in moduledefinition.ControlTypeRoutes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + if (route.StartsWith(control + "=")) { - if (route.StartsWith(control + "=")) - { - typename = route.Replace(control + "=", ""); - } - } - } - module.ModuleType = typename.Replace(Constants.ActionToken, control); - - // admin controls need to load additional metadata from the IModuleControl interface - if (moduleid == module.ModuleId) - { - typename = module.ModuleType; - // check for core module actions component - if (Constants.DefaultModuleActions.Contains(control)) - { - typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, control); - } - Type moduletype = Type.GetType(typename); - if (moduletype != null) - { - var moduleobject = Activator.CreateInstance(moduletype); - module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null); - module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject); - module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject); - module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject); + typename = route.Replace(control + "=", ""); } } } - else - { - module.ModuleType = typename.Replace(Constants.ActionToken, Constants.DefaultAction); - } + module.ModuleType = typename.Replace(Constants.ActionToken, control); + // admin controls need to load additional metadata from the IModuleControl interface + if (moduleid == module.ModuleId) + { + typename = module.ModuleType; + // check for core module actions component + if (Constants.DefaultModuleActions.Contains(control)) + { + typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, control); + } + Type moduletype = Type.GetType(typename); + if (moduletype != null) + { + var moduleobject = Activator.CreateInstance(moduletype); + module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null); + module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject); + module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject); + module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject); + } + } } + else + { + module.ModuleType = typename.Replace(Constants.ActionToken, Constants.DefaultAction); + } + if (module.PageId == pageid) { @@ -442,31 +430,4 @@ return modules; } - private Alias GetAlias(string absoluteUri, List aliases) - { - - string aliasname; - Alias alias = null; - Uri uri = new Uri(absoluteUri); - - if (uri.Segments.Count() > 1) - { - // check if first path segment is an alias ( ie. a subfolder - www.domain.com/subfolder ) - aliasname = uri.Authority + "/" + uri.Segments[1]; - if (aliasname.EndsWith("/")) { aliasname = aliasname.Substring(0, aliasname.Length - 1); } - alias = aliases.Where(item => item.Name == aliasname).FirstOrDefault(); - } - if (alias == null) - { - aliasname = uri.Authority; - alias = aliases.Where(item => item.Name == aliasname).FirstOrDefault(); - } - if (alias == null && aliases.Count > 0) - { - // use first alias if Uri does not exist - alias = aliases.FirstOrDefault(); - } - return alias; - } - } \ No newline at end of file diff --git a/Oqtane.Client/Themes/ContainerBase.cs b/Oqtane.Client/Themes/ContainerBase.cs index cae6f771..867722f7 100644 --- a/Oqtane.Client/Themes/ContainerBase.cs +++ b/Oqtane.Client/Themes/ContainerBase.cs @@ -18,14 +18,6 @@ namespace Oqtane.Themes [CascadingParameter] protected Module ModuleState { get; set; } - protected ModuleDefinition ModuleDefinition - { - get - { - return PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).FirstOrDefault(); - } - } - public virtual string Name { get; set; } public string ThemePath() diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index e8b526d4..68a80cfe 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -80,7 +80,7 @@ @foreach (var moduledefinition in moduledefinitions) { - if (moduledefinition.Permissions == "[]" || UserSecurity.IsAuthorized(PageState.User, "Utilize", moduledefinition.Permissions)) + if (UserSecurity.IsAuthorized(PageState.User, "Utilize", moduledefinition.Permissions)) { } @@ -199,6 +199,7 @@ bool deleteconfirmation = false; string moduletype = "new"; List categories = new List(); + List ModuleDefinitions; List moduledefinitions; List pages = new List(); string pageid = ""; @@ -212,7 +213,7 @@ string display = "display: none;"; string message = ""; - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { if (string.IsNullOrEmpty(ButtonClass)) { @@ -235,7 +236,8 @@ { pages?.Clear(); - foreach (ModuleDefinition moduledefinition in PageState.ModuleDefinitions) + ModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); + foreach (ModuleDefinition moduledefinition in ModuleDefinitions) { if (moduledefinition.Categories != "") { @@ -248,7 +250,7 @@ } } } - moduledefinitions = PageState.ModuleDefinitions.Where(item => item.Categories == "").ToList(); + moduledefinitions = ModuleDefinitions.Where(item => item.Categories == "").ToList(); foreach (Page p in PageState.Pages) { if (UserSecurity.IsAuthorized(PageState.User, "View", p.Permissions)) @@ -258,7 +260,8 @@ } var panes = PageState.Page.Panes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); pane = panes.Count() == 1 ? panes.SingleOrDefault() : ""; - containers = ThemeService.GetContainerTypes(PageState.Themes); + List themes = await ThemeService.GetThemesAsync(); + containers = ThemeService.GetContainerTypes(themes); containertype = PageState.Site.DefaultContainerType; } } @@ -268,11 +271,11 @@ string category = (string)e.Value; if (category == "-") { - moduledefinitions = PageState.ModuleDefinitions.Where(item => item.Categories == "").ToList(); + moduledefinitions = ModuleDefinitions.Where(item => item.Categories == "").ToList(); } else { - moduledefinitions = PageState.ModuleDefinitions.Where(item => item.Categories.Contains(category)).ToList(); + moduledefinitions = ModuleDefinitions.Where(item => item.Categories.Contains(category)).ToList(); } moduledefinitionname = "-"; StateHasChanged(); @@ -304,6 +307,7 @@ { Module module = new Module(); module.SiteId = PageState.Site.SiteId; + module.PageId = PageState.Page.PageId; module.ModuleDefinitionName = moduledefinitionname; module.Permissions = PageState.Page.Permissions; module = await ModuleService.AddModuleAsync(module); @@ -367,7 +371,7 @@ { if (PageState.Page.IsPersonalizable && PageState.User != null) { - await CreatePersonalizedPage(); + await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId); PageState.EditMode = true; NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0"), Reload.Page)); } @@ -458,67 +462,4 @@ await logger.Log(page.PageId, null, PageState.User.UserId, this.GetType().AssemblyQualifiedName, "ControlPanel", LogFunction.Delete, LogLevel.Information, ex, "Page Deleted {Page} {Error}", page, ex.Message); } } - - private async Task CreatePersonalizedPage() - { - Page page = new Page(); - page.SiteId = PageState.Page.SiteId; - page.Name = PageState.Page.Name; - page.Path = PageState.Page.Path; - page.ParentId = PageState.Page.ParentId; - page.Order = 0; - page.IsNavigation = false; - page.EditMode = false; - page.ThemeType = PageState.Page.ThemeType; - if (page.ThemeType == PageState.Site.DefaultThemeType) - { - page.ThemeType = ""; - } - page.LayoutType = PageState.Page.LayoutType; - if (page.LayoutType == PageState.Site.DefaultLayoutType) - { - page.LayoutType = ""; - } - page.Icon = PageState.Page.Icon; - List permissions = new List(); - permissions.Add(new PermissionString { PermissionName = "View", Permissions = "[" + PageState.User.UserId.ToString() + "]" }); - permissions.Add(new PermissionString { PermissionName = "Edit", Permissions = "[" + PageState.User.UserId.ToString() + "]" }); - page.Permissions = UserSecurity.SetPermissionStrings(permissions); - page.IsPersonalizable = false; - page.UserId = PageState.User.UserId; - page = await PageService.AddPageAsync(page); - - // copy modules - foreach (Module m in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId && !item.IsDeleted)) - { - Module module = new Module(); - module.SiteId = m.SiteId; - module.ModuleDefinitionName = m.ModuleDefinitionName; - permissions = new List(); - permissions.Add(new PermissionString { PermissionName = "View", Permissions = "[" + PageState.User.UserId.ToString() + "]" }); - permissions.Add(new PermissionString { PermissionName = "Edit", Permissions = "[" + PageState.User.UserId.ToString() + "]" }); - module.Permissions = UserSecurity.SetPermissionStrings(permissions); - module = await ModuleService.AddModuleAsync(module); - - string content = await ModuleService.ExportModuleAsync(m.ModuleId); - if (content != "") - { - await ModuleService.ImportModuleAsync(module.ModuleId, content); - } - - PageModule pagemodule = new PageModule(); - pagemodule.PageId = page.PageId; - pagemodule.ModuleId = module.ModuleId; - pagemodule.Title = m.Title; - pagemodule.Pane = m.Pane; - pagemodule.Order = m.Order; - pagemodule.ContainerType = m.ContainerType; - if (pagemodule.ContainerType == PageState.Site.DefaultContainerType) - { - pagemodule.ContainerType = ""; - } - - await PageModuleService.AddPageModuleAsync(pagemodule); - } - } } diff --git a/Oqtane.Client/Themes/Controls/ModuleActions.razor b/Oqtane.Client/Themes/Controls/ModuleActions.razor index 2c539166..d410808f 100644 --- a/Oqtane.Client/Themes/Controls/ModuleActions.razor +++ b/Oqtane.Client/Themes/Controls/ModuleActions.razor @@ -31,7 +31,7 @@ { actions = new List(); actions.Add(new ActionViewModel { Action = "settings", Name = "Manage Settings" }); - if (ModuleDefinition.ServerAssemblyName != "") + if (ModuleState.ModuleDefinition.ServerAssemblyName != "") { actions.Add(new ActionViewModel { Action = "import", Name = "Import Content" }); actions.Add(new ActionViewModel { Action = "export", Name = "Export Content" }); diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index bfd2f4c5..e07db160 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -5,6 +5,8 @@ using Oqtane.Repository; using Oqtane.Models; using Oqtane.Shared; using Oqtane.Infrastructure; +using System.Linq; +using System; namespace Oqtane.Controllers { @@ -22,6 +24,7 @@ namespace Oqtane.Controllers // GET: api/ [HttpGet] + [Authorize(Roles = Constants.AdminRole)] public IEnumerable Get() { return Aliases.GetAliases(); @@ -29,11 +32,32 @@ namespace Oqtane.Controllers // GET api//5 [HttpGet("{id}")] + [Authorize(Roles = Constants.AdminRole)] public Alias Get(int id) { return Aliases.GetAlias(id); } + // GET api//name/localhost:12345 + [HttpGet("name/{name}")] + public Alias Get(string name) + { + List aliases = Aliases.GetAliases().ToList(); + Alias alias = null; + alias = aliases.Where(item => item.Name == name).FirstOrDefault(); + if (alias == null && name.Contains("/")) + { + // lookup alias without folder name + alias = aliases.Where(item => item.Name == name.Substring(name.IndexOf("/") + 1)).FirstOrDefault(); + } + if (alias == null && aliases.Count > 0) + { + // use first alias if name does not exist + alias = aliases.FirstOrDefault(); + } + return alias; + } + // POST api/ [HttpPost] [Authorize(Roles = Constants.AdminRole)] diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index eeea4998..cf99306d 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -72,7 +72,17 @@ namespace Oqtane.Controllers [HttpGet("{id}")] public Models.File Get(int id) { - return Files.GetFile(id); + Models.File file = Files.GetFile(id); + if (UserPermissions.IsAuthorized(User, "View", file.Folder.Permissions)) + { + return file; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {File}", file); + HttpContext.Response.StatusCode = 401; + return null; + } } // PUT api//5 @@ -85,6 +95,12 @@ namespace Oqtane.Controllers File = Files.UpdateFile(File); logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", File); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update File {File}", File); + HttpContext.Response.StatusCode = 401; + File = null; + } return File; } @@ -105,6 +121,11 @@ namespace Oqtane.Controllers } logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", File); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete File {FileId}", id); + HttpContext.Response.StatusCode = 401; + } } // GET api//upload?url=x&folderid=y @@ -130,6 +151,12 @@ namespace Oqtane.Controllers logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url {Url}", url); } } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Download File {Url} {FolderId}", url, folderid); + HttpContext.Response.StatusCode = 401; + file = null; + } return file; } @@ -170,6 +197,11 @@ namespace Oqtane.Controllers Files.AddFile(new Models.File { Name = upload, FolderId = folderid, Extension = fileinfo.Extension.Replace(".", ""), Size = (int)fileinfo.Length }); } } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Upload File {Folder} {File}", folder, file); + HttpContext.Response.StatusCode = 401; + } } } @@ -293,7 +325,9 @@ namespace Oqtane.Controllers } else { - return NotFound(); + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id); + HttpContext.Response.StatusCode = 401; + return null; } } diff --git a/Oqtane.Server/Controllers/FolderController.cs b/Oqtane.Server/Controllers/FolderController.cs index 2bc4bc90..5f1da3ba 100644 --- a/Oqtane.Server/Controllers/FolderController.cs +++ b/Oqtane.Server/Controllers/FolderController.cs @@ -28,21 +28,32 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(string siteid) { - if (siteid == "") + List folders = new List(); + foreach(Folder folder in Folders.GetFolders(int.Parse(siteid))) { - return Folders.GetFolders(); - } - else - { - return Folders.GetFolders(int.Parse(siteid)); + if (UserPermissions.IsAuthorized(User, "Browse", folder.Permissions)) + { + folders.Add(folder); + } } + return folders; } // GET api//5 [HttpGet("{id}")] public Folder Get(int id) { - return Folders.GetFolder(id); + Folder folder = Folders.GetFolder(id); + if (UserPermissions.IsAuthorized(User, "Browse", folder.Permissions)) + { + return folder; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Folder {Folder}", folder); + HttpContext.Response.StatusCode = 401; + return null; + } } // POST api/ @@ -50,16 +61,33 @@ namespace Oqtane.Controllers [Authorize(Roles = Constants.RegisteredRole)] public Folder Post([FromBody] Folder Folder) { - if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Edit", Folder.Permissions)) + if (ModelState.IsValid) { - Folder.Path = ""; - if (string.IsNullOrEmpty(Folder.Path) && Folder.ParentId != null) + string permissions; + if (Folder.ParentId != null) { - Folder parent = Folders.GetFolder(Folder.ParentId.Value); - Folder.Path = parent.Path + Folder.Name + "\\"; + permissions = Folders.GetFolder(Folder.ParentId.Value).Permissions; + } + else + { + permissions = UserSecurity.SetPermissionStrings(new List { new PermissionString { PermissionName = "Edit", Permissions = Constants.AdminRole } }); + } + if (UserPermissions.IsAuthorized(User, "Edit", permissions)) + { + if (string.IsNullOrEmpty(Folder.Path) && Folder.ParentId != null) + { + Folder parent = Folders.GetFolder(Folder.ParentId.Value); + Folder.Path = parent.Path + Folder.Name + "\\"; + } + Folder = Folders.AddFolder(Folder); + logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", Folder); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Folder {Folder}", Folder); + HttpContext.Response.StatusCode = 401; + Folder = null; } - Folder = Folders.AddFolder(Folder); - logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", Folder); } return Folder; } @@ -71,7 +99,6 @@ namespace Oqtane.Controllers { if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Folder", Folder.FolderId, "Edit")) { - Folder.Path = ""; if (string.IsNullOrEmpty(Folder.Path) && Folder.ParentId != null) { Folder parent = Folders.GetFolder(Folder.ParentId.Value); @@ -80,6 +107,12 @@ namespace Oqtane.Controllers Folder = Folders.UpdateFolder(Folder); logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", Folder); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Folder {Folder}", Folder); + HttpContext.Response.StatusCode = 401; + Folder = null; + } return Folder; } @@ -103,6 +136,11 @@ namespace Oqtane.Controllers } logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Order Updated {SiteId} {FolderId} {ParentId}", siteid, folderid, parentid); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Folder Order {SiteId} {FolderId} {ParentId}", siteid, folderid, parentid); + HttpContext.Response.StatusCode = 401; + } } // DELETE api//5 @@ -115,6 +153,11 @@ namespace Oqtane.Controllers Folders.DeleteFolder(id); logger.Log(LogLevel.Information, this, LogFunction.Delete, "Folder Deleted {FolderId}", id); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Folder {FolderId}", id); + HttpContext.Response.StatusCode = 401; + } } } } diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 46966d70..fbfcaf51 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -269,7 +269,7 @@ namespace Oqtane.Controllers var result = dbUpgrade.PerformUpgrade(); if (!result.Successful) { - // TODO: log result.Error.Message; + // TODO: log result.Error.Message - problem is logger is not available here } } } diff --git a/Oqtane.Server/Controllers/JobController.cs b/Oqtane.Server/Controllers/JobController.cs index 4dade1d9..e5647351 100644 --- a/Oqtane.Server/Controllers/JobController.cs +++ b/Oqtane.Server/Controllers/JobController.cs @@ -27,6 +27,7 @@ namespace Oqtane.Controllers // GET: api/ [HttpGet] + [Authorize(Roles = Constants.HostRole)] public IEnumerable Get() { return Jobs.GetJobs(); @@ -34,6 +35,7 @@ namespace Oqtane.Controllers // GET api//5 [HttpGet("{id}")] + [Authorize(Roles = Constants.HostRole)] public Job Get(int id) { return Jobs.GetJob(id); diff --git a/Oqtane.Server/Controllers/ModuleController.cs b/Oqtane.Server/Controllers/ModuleController.cs index 46a6f2fd..e61f1350 100644 --- a/Oqtane.Server/Controllers/ModuleController.cs +++ b/Oqtane.Server/Controllers/ModuleController.cs @@ -6,10 +6,6 @@ using Oqtane.Models; using Oqtane.Shared; using System.Linq; using System.Reflection; -using System; -using Oqtane.Modules; -using Microsoft.Extensions.DependencyInjection; -using System.Text.Json; using Oqtane.Infrastructure; using Oqtane.Security; @@ -21,16 +17,14 @@ namespace Oqtane.Controllers private readonly IModuleRepository Modules; private readonly IPageModuleRepository PageModules; private readonly IModuleDefinitionRepository ModuleDefinitions; - private readonly IServiceProvider ServiceProvider; private readonly IUserPermissions UserPermissions; private readonly ILogManager logger; - public ModuleController(IModuleRepository Modules, IPageModuleRepository PageModules, IModuleDefinitionRepository ModuleDefinitions, IServiceProvider ServiceProvider, IUserPermissions UserPermissions, ILogManager logger) + public ModuleController(IModuleRepository Modules, IPageModuleRepository PageModules, IModuleDefinitionRepository ModuleDefinitions, IUserPermissions UserPermissions, ILogManager logger) { this.Modules = Modules; this.PageModules = PageModules; this.ModuleDefinitions = ModuleDefinitions; - this.ServiceProvider = ServiceProvider; this.UserPermissions = UserPermissions; this.logger = logger; } @@ -39,36 +33,55 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(string siteid) { - List modulelist = new List(); + List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(int.Parse(siteid)).ToList(); + List modules = new List(); foreach (PageModule pagemodule in PageModules.GetPageModules(int.Parse(siteid))) { - Models.Module module = new Models.Module(); - module.SiteId = pagemodule.Module.SiteId; - module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName; - module.Permissions = pagemodule.Module.Permissions; - module.CreatedBy = pagemodule.Module.CreatedBy; - module.CreatedOn = pagemodule.Module.CreatedOn; - module.ModifiedBy = pagemodule.Module.ModifiedBy; - module.ModifiedOn = pagemodule.Module.ModifiedOn; - module.IsDeleted = pagemodule.IsDeleted; + if (UserPermissions.IsAuthorized(User, "View", pagemodule.Module.Permissions)) + { + Models.Module module = new Models.Module(); + module.SiteId = pagemodule.Module.SiteId; + module.ModuleDefinitionName = pagemodule.Module.ModuleDefinitionName; + module.Permissions = pagemodule.Module.Permissions; + module.CreatedBy = pagemodule.Module.CreatedBy; + module.CreatedOn = pagemodule.Module.CreatedOn; + module.ModifiedBy = pagemodule.Module.ModifiedBy; + module.ModifiedOn = pagemodule.Module.ModifiedOn; + module.IsDeleted = pagemodule.IsDeleted; - module.PageModuleId = pagemodule.PageModuleId; - module.ModuleId = pagemodule.ModuleId; - module.PageId = pagemodule.PageId; - module.Title = pagemodule.Title; - module.Pane = pagemodule.Pane; - module.Order = pagemodule.Order; - module.ContainerType = pagemodule.ContainerType; - modulelist.Add(module); + module.PageModuleId = pagemodule.PageModuleId; + module.ModuleId = pagemodule.ModuleId; + module.PageId = pagemodule.PageId; + module.Title = pagemodule.Title; + module.Pane = pagemodule.Pane; + module.Order = pagemodule.Order; + module.ContainerType = pagemodule.ContainerType; + + module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName); + + modules.Add(module); + } } - return modulelist; + return modules; } // GET api//5 [HttpGet("{id}")] public Models.Module Get(int id) { - return Modules.GetModule(id); + Models.Module module = Modules.GetModule(id); + if (UserPermissions.IsAuthorized(User, "View", module.Permissions)) + { + List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); + module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName); + return module; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Module {Module}", module); + HttpContext.Response.StatusCode = 401; + return null; + } } // POST api/ @@ -76,11 +89,17 @@ namespace Oqtane.Controllers [Authorize(Roles = Constants.RegisteredRole)] public Models.Module Post([FromBody] Models.Module Module) { - if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Edit", Module.Permissions)) + if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Page", Module.PageId, "Edit")) { Module = Modules.AddModule(Module); logger.Log(LogLevel.Information, this, LogFunction.Create, "Module Added {Module}", Module); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Module {Module}", Module); + HttpContext.Response.StatusCode = 401; + Module = null; + } return Module; } @@ -94,6 +113,12 @@ namespace Oqtane.Controllers Module = Modules.UpdateModule(Module); logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Updated {Module}", Module); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Module {Module}", Module); + HttpContext.Response.StatusCode = 401; + Module = null; + } return Module; } @@ -107,6 +132,11 @@ namespace Oqtane.Controllers Modules.DeleteModule(id); logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Deleted {ModuleId}", id); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Module {ModuleId}", id); + HttpContext.Response.StatusCode = 401; + } } // GET api//export?moduleid=x @@ -115,48 +145,14 @@ namespace Oqtane.Controllers public string Export(int moduleid) { string content = ""; - if (UserPermissions.IsAuthorized(User, "Module", moduleid, "View")) + if (UserPermissions.IsAuthorized(User, "Module", moduleid, "Edit")) { - try - { - Models.Module module = Modules.GetModule(moduleid); - if (module != null) - { - List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); - ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); - if (moduledefinition != null) - { - ModuleContent modulecontent = new ModuleContent(); - modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName; - modulecontent.Version = moduledefinition.Version; - modulecontent.Content = ""; - - if (moduledefinition.ServerAssemblyName != "") - { - Assembly assembly = AppDomain.CurrentDomain.GetAssemblies() - .Where(item => item.FullName.StartsWith(moduledefinition.ServerAssemblyName)).FirstOrDefault(); - if (assembly != null) - { - Type moduletype = assembly.GetTypes() - .Where(item => item.Namespace != null) - .Where(item => item.Namespace.StartsWith(moduledefinition.ModuleDefinitionName.Substring(0, moduledefinition.ModuleDefinitionName.IndexOf(",")))) - .Where(item => item.GetInterfaces().Contains(typeof(IPortable))).FirstOrDefault(); - if (moduletype != null) - { - var moduleobject = ActivatorUtilities.CreateInstance(ServiceProvider, moduletype); - modulecontent.Content = ((IPortable)moduleobject).ExportModule(module); - } - } - } - content = JsonSerializer.Serialize(modulecontent); - logger.Log(LogLevel.Information, this, LogFunction.Read, "Module Content Exported {ModuleId}", moduleid); - } - } - } - catch - { - // error occurred during export - } + content = Modules.ExportModule(moduleid); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Other, "User Not Authorized To Export Module {ModuleId}", moduleid); + HttpContext.Response.StatusCode = 401; } return content; } @@ -169,45 +165,12 @@ namespace Oqtane.Controllers bool success = false; if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Module", moduleid, "Edit")) { - try - { - Models.Module module = Modules.GetModule(moduleid); - if (module != null) - { - List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); - ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); - if (moduledefinition != null) - { - ModuleContent modulecontent = JsonSerializer.Deserialize(Content); - if (modulecontent.ModuleDefinitionName == moduledefinition.ModuleDefinitionName) - { - if (moduledefinition.ServerAssemblyName != "") - { - Assembly assembly = AppDomain.CurrentDomain.GetAssemblies() - .Where(item => item.FullName.StartsWith(moduledefinition.ServerAssemblyName)).FirstOrDefault(); - if (assembly != null) - { - Type moduletype = assembly.GetTypes() - .Where(item => item.Namespace != null) - .Where(item => item.Namespace.StartsWith(moduledefinition.ModuleDefinitionName.Substring(0, moduledefinition.ModuleDefinitionName.IndexOf(",")))) - .Where(item => item.GetInterfaces().Contains(typeof(IPortable))).FirstOrDefault(); - if (moduletype != null) - { - var moduleobject = ActivatorUtilities.CreateInstance(ServiceProvider, moduletype); - ((IPortable)moduleobject).ImportModule(module, modulecontent.Content, modulecontent.Version); - success = true; - logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Content Imported {ModuleId}", moduleid); - } - } - } - } - } - } - } - catch - { - // error occurred during import - } + success = Modules.ImportModule(moduleid, Content); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Other, "User Not Authorized To Import Module {ModuleId}", moduleid); + HttpContext.Response.StatusCode = 401; } return success; } diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index 7845890f..1a41edb1 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -9,6 +9,7 @@ using System.IO; using System.Reflection; using System.Linq; using Microsoft.AspNetCore.Hosting; +using Oqtane.Security; namespace Oqtane.Controllers { @@ -16,13 +17,15 @@ namespace Oqtane.Controllers public class ModuleDefinitionController : Controller { private readonly IModuleDefinitionRepository ModuleDefinitions; + private readonly IUserPermissions UserPermissions; private readonly IInstallationManager InstallationManager; private readonly IWebHostEnvironment environment; private readonly ILogManager logger; - public ModuleDefinitionController(IModuleDefinitionRepository ModuleDefinitions, IInstallationManager InstallationManager, IWebHostEnvironment environment, ILogManager logger) + public ModuleDefinitionController(IModuleDefinitionRepository ModuleDefinitions, IUserPermissions UserPermissions, IInstallationManager InstallationManager, IWebHostEnvironment environment, ILogManager logger) { this.ModuleDefinitions = ModuleDefinitions; + this.UserPermissions = UserPermissions; this.InstallationManager = InstallationManager; this.environment = environment; this.logger = logger; @@ -32,9 +35,35 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(int siteid) { - return ModuleDefinitions.GetModuleDefinitions(siteid); + List moduledefinitions = new List(); + foreach(ModuleDefinition moduledefinition in ModuleDefinitions.GetModuleDefinitions(siteid)) + { + if (UserPermissions.IsAuthorized(User, "Utilize", moduledefinition.Permissions)) + { + moduledefinitions.Add(moduledefinition); + } + } + return moduledefinitions; } + // GET api//5?siteid=x + [HttpGet("{id}")] + public ModuleDefinition Get(int id, string siteid) + { + ModuleDefinition moduledefinition = ModuleDefinitions.GetModuleDefinition(id, int.Parse(siteid)); + if (UserPermissions.IsAuthorized(User, "Utilize", moduledefinition.Permissions)) + { + return moduledefinition; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access ModuleDefinition {ModuleDefinition}", moduledefinition); + HttpContext.Response.StatusCode = 401; + return null; + } + } + + // GET api//filename [HttpGet("{filename}")] public IActionResult Get(string assemblyname) @@ -93,5 +122,6 @@ namespace Oqtane.Controllers InstallationManager.RestartApplication(); } } + } } diff --git a/Oqtane.Server/Controllers/PageController.cs b/Oqtane.Server/Controllers/PageController.cs index 9109b257..ec5a7dbf 100644 --- a/Oqtane.Server/Controllers/PageController.cs +++ b/Oqtane.Server/Controllers/PageController.cs @@ -14,12 +14,16 @@ namespace Oqtane.Controllers public class PageController : Controller { private readonly IPageRepository Pages; + private readonly IModuleRepository Modules; + private readonly IPageModuleRepository PageModules; private readonly IUserPermissions UserPermissions; private readonly ILogManager logger; - public PageController(IPageRepository Pages, IUserPermissions UserPermissions, ILogManager logger) + public PageController(IPageRepository Pages, IModuleRepository Modules, IPageModuleRepository PageModules, IUserPermissions UserPermissions, ILogManager logger) { this.Pages = Pages; + this.Modules = Modules; + this.PageModules = PageModules; this.UserPermissions = UserPermissions; this.logger = logger; } @@ -28,27 +32,39 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(string siteid) { - if (siteid == "") + List pages = new List(); + foreach (Page page in Pages.GetPages(int.Parse(siteid))) { - return Pages.GetPages(); - } - else - { - return Pages.GetPages(int.Parse(siteid)); + if (UserPermissions.IsAuthorized(User, "View", page.Permissions)) + { + pages.Add(page); + } } + return pages; } // GET api//5?userid=x [HttpGet("{id}")] public Page Get(int id, string userid) { + Page page; if (string.IsNullOrEmpty(userid)) { - return Pages.GetPage(id); + page = Pages.GetPage(id); } else { - return Pages.GetPage(id, int.Parse(userid)); + page = Pages.GetPage(id, int.Parse(userid)); + } + if (UserPermissions.IsAuthorized(User, "View", page.Permissions)) + { + return page; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Page {Page}", page); + HttpContext.Response.StatusCode = 401; + return null; } } @@ -57,14 +73,95 @@ namespace Oqtane.Controllers [Authorize(Roles = Constants.RegisteredRole)] public Page Post([FromBody] Page Page) { - if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Edit", Page.Permissions)) + if (ModelState.IsValid) { - Page = Pages.AddPage(Page); - logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", Page); + string permissions; + if (Page.ParentId != null) + { + permissions = Pages.GetPage(Page.ParentId.Value).Permissions; + } + else + { + permissions = UserSecurity.SetPermissionStrings(new List { new PermissionString { PermissionName = "Edit", Permissions = Constants.AdminRole } }); + } + + if (UserPermissions.IsAuthorized(User, "Edit", permissions)) + { + Page = Pages.AddPage(Page); + logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", Page); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Page {Page}", Page); + HttpContext.Response.StatusCode = 401; + Page = null; + } } return Page; } + // POST api//5?userid=x + [HttpPost("{id}")] + [Authorize(Roles = Constants.RegisteredRole)] + public Page Post(int id, string userid) + { + Page page = null; + Page parent = Pages.GetPage(id); + if (parent != null && parent.IsPersonalizable && !string.IsNullOrEmpty(userid)) + { + page = new Page(); + page.SiteId = parent.SiteId; + page.Name = parent.Name; + page.Path = parent.Path; + page.ParentId = parent.PageId; + page.Order = 0; + page.IsNavigation = false; + page.EditMode = false; + page.ThemeType = parent.ThemeType; + page.LayoutType = parent.LayoutType; + page.Icon = parent.Icon; + List permissions = new List(); + permissions.Add(new PermissionString { PermissionName = "View", Permissions = "[" + userid + "]" }); + permissions.Add(new PermissionString { PermissionName = "Edit", Permissions = "[" + userid + "]" }); + page.Permissions = UserSecurity.SetPermissionStrings(permissions); + page.IsPersonalizable = false; + page.UserId = int.Parse(userid); + page = Pages.AddPage(page); + + // copy modules + List pagemodules = PageModules.GetPageModules(page.SiteId).ToList(); + foreach (PageModule pm in pagemodules.Where(item => item.PageId == parent.PageId && !item.IsDeleted)) + { + Module module = new Module(); + module.SiteId = page.SiteId; + module.PageId = page.PageId; + module.ModuleDefinitionName = pm.Module.ModuleDefinitionName; + permissions = new List(); + permissions.Add(new PermissionString { PermissionName = "View", Permissions = "[" + userid + "]" }); + permissions.Add(new PermissionString { PermissionName = "Edit", Permissions = "[" + userid + "]" }); + module.Permissions = UserSecurity.SetPermissionStrings(permissions); + module = Modules.AddModule(module); + + string content = Modules.ExportModule(pm.ModuleId); + if (content != "") + { + Modules.ImportModule(module.ModuleId, content); + } + + PageModule pagemodule = new PageModule(); + pagemodule.PageId = page.PageId; + pagemodule.ModuleId = module.ModuleId; + pagemodule.Title = pm.Title; + pagemodule.Pane = pm.Pane; + pagemodule.Order = pm.Order; + pagemodule.ContainerType = pm.ContainerType; + + PageModules.AddPageModule(pagemodule); + } + } + return page; + } + // PUT api//5 [HttpPut("{id}")] [Authorize(Roles = Constants.RegisteredRole)] @@ -75,6 +172,12 @@ namespace Oqtane.Controllers Page = Pages.UpdatePage(Page); logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Updated {Page}", Page); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Page {Page}", Page); + HttpContext.Response.StatusCode = 401; + Page = null; + } return Page; } @@ -98,6 +201,11 @@ namespace Oqtane.Controllers } logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Order Updated {SiteId} {PageId} {ParentId}", siteid, pageid, parentid); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Page Order {SiteId} {PageId} {ParentId}", siteid, pageid, parentid); + HttpContext.Response.StatusCode = 401; + } } // DELETE api//5 @@ -110,6 +218,11 @@ namespace Oqtane.Controllers Pages.DeletePage(id); logger.Log(LogLevel.Information, this, LogFunction.Delete, "Page Deleted {PageId}", id); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Page {PageId}", id); + HttpContext.Response.StatusCode = 401; + } } } } diff --git a/Oqtane.Server/Controllers/PageModuleController.cs b/Oqtane.Server/Controllers/PageModuleController.cs index 99ba628d..1f9ff8c8 100644 --- a/Oqtane.Server/Controllers/PageModuleController.cs +++ b/Oqtane.Server/Controllers/PageModuleController.cs @@ -14,12 +14,14 @@ namespace Oqtane.Controllers public class PageModuleController : Controller { private readonly IPageModuleRepository PageModules; + private readonly IModuleRepository Modules; private readonly IUserPermissions UserPermissions; private readonly ILogManager logger; - public PageModuleController(IPageModuleRepository PageModules, IUserPermissions UserPermissions, ILogManager logger) + public PageModuleController(IPageModuleRepository PageModules, IModuleRepository Modules, IUserPermissions UserPermissions, ILogManager logger) { this.PageModules = PageModules; + this.Modules = Modules; this.UserPermissions = UserPermissions; this.logger = logger; } @@ -28,14 +30,34 @@ namespace Oqtane.Controllers [HttpGet("{id}")] public PageModule Get(int id) { - return PageModules.GetPageModule(id); + PageModule pagemodule = PageModules.GetPageModule(id); + if (UserPermissions.IsAuthorized(User, "View", pagemodule.Module.Permissions)) + { + return pagemodule; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access PageModule {PageModule}", pagemodule); + HttpContext.Response.StatusCode = 401; + return null; + } } // GET: api//pageid/moduleid [HttpGet("{pageid}/{moduleid}")] public PageModule Get(int pageid, int moduleid) { - return PageModules.GetPageModule(pageid, moduleid); + PageModule pagemodule = PageModules.GetPageModule(pageid, moduleid); + if (UserPermissions.IsAuthorized(User, "View", pagemodule.Module.Permissions)) + { + return pagemodule; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access PageModule {PageModule}", pagemodule); + HttpContext.Response.StatusCode = 401; + return null; + } } // POST api/ @@ -48,6 +70,12 @@ namespace Oqtane.Controllers PageModule = PageModules.AddPageModule(PageModule); logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Module Added {PageModule}", PageModule); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add PageModule {PageModule}", PageModule); + HttpContext.Response.StatusCode = 401; + PageModule = null; + } return PageModule; } @@ -56,11 +84,17 @@ namespace Oqtane.Controllers [Authorize(Roles = Constants.RegisteredRole)] public PageModule Put(int id, [FromBody] PageModule PageModule) { - if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Page", PageModule.PageId, "Edit")) + if (ModelState.IsValid && UserPermissions.IsAuthorized(User, "Module", PageModule.ModuleId, "Edit")) { PageModule = PageModules.UpdatePageModule(PageModule); logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Module Updated {PageModule}", PageModule); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update PageModule {PageModule}", PageModule); + HttpContext.Response.StatusCode = 401; + PageModule = null; + } return PageModule; } @@ -84,6 +118,11 @@ namespace Oqtane.Controllers } logger.Log(LogLevel.Information, this, LogFunction.Update, "Page Module Order Updated {PageId} {Pane}", pageid, pane); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Page Module Order {PageId} {Pane}", pageid, pane); + HttpContext.Response.StatusCode = 401; + } } // DELETE api//5 @@ -97,6 +136,11 @@ namespace Oqtane.Controllers PageModules.DeletePageModule(id); logger.Log(LogLevel.Information, this, LogFunction.Delete, "Page Module Deleted {PageModuleId}", id); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete PageModule {PageModuleId}", id); + HttpContext.Response.StatusCode = 401; + } } } } diff --git a/Oqtane.Server/Controllers/PermissionController.cs b/Oqtane.Server/Controllers/PermissionController.cs deleted file mode 100644 index 8cd68430..00000000 --- a/Oqtane.Server/Controllers/PermissionController.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using Oqtane.Repository; -using Oqtane.Models; -using Oqtane.Shared; -using Oqtane.Infrastructure; - -namespace Oqtane.Controllers -{ - [Route("{site}/api/[controller]")] - public class PermissionController : Controller - { - private readonly IPermissionRepository Permissions; - private readonly ILogManager logger; - - public PermissionController(IPermissionRepository Permissions, ILogManager logger) - { - this.Permissions = Permissions; - this.logger = logger; - } - - // GET: api/ - [HttpGet] - public IEnumerable Get(string entityname, int entityid, string permissionname) - { - return Permissions.GetPermissions(entityname, entityid, permissionname); - } - - // GET api//5 - [HttpGet("{id}")] - public Permission Get(int id) - { - return Permissions.GetPermission(id); - } - - // POST api/ - [HttpPost] - [Authorize(Roles = Constants.AdminRole)] - public Permission Post([FromBody] Permission Permission) - { - if (ModelState.IsValid) - { - Permission = Permissions.AddPermission(Permission); - logger.Log(LogLevel.Information, this, LogFunction.Create, "Permission Added {Permission}", Permission); - } - return Permission; - } - - // PUT api//5 - [HttpPut("{id}")] - [Authorize(Roles = Constants.AdminRole)] - public Permission Put(int id, [FromBody] Permission Permission) - { - if (ModelState.IsValid) - { - Permission = Permissions.UpdatePermission(Permission); - logger.Log(LogLevel.Information, this, LogFunction.Update, "Permission Updated {Permission}", Permission); - } - return Permission; - } - - // DELETE api//5 - [HttpDelete("{id}")] - [Authorize(Roles = Constants.AdminRole)] - public void Delete(int id) - { - Permissions.DeletePermission(id); - logger.Log(LogLevel.Information, this, LogFunction.Delete, "Permission Deleted {PermissionId}", id); - } - } -} diff --git a/Oqtane.Server/Controllers/RoleController.cs b/Oqtane.Server/Controllers/RoleController.cs index c562a0f5..a2b978ad 100644 --- a/Oqtane.Server/Controllers/RoleController.cs +++ b/Oqtane.Server/Controllers/RoleController.cs @@ -22,6 +22,7 @@ namespace Oqtane.Controllers // GET: api/?siteid=x [HttpGet] + [Authorize(Roles = Constants.RegisteredRole)] public IEnumerable Get(string siteid) { return Roles.GetRoles(int.Parse(siteid)); @@ -29,6 +30,7 @@ namespace Oqtane.Controllers // GET api//5 [HttpGet("{id}")] + [Authorize(Roles = Constants.RegisteredRole)] public Role Get(int id) { return Roles.GetRole(id); diff --git a/Oqtane.Server/Controllers/SettingController.cs b/Oqtane.Server/Controllers/SettingController.cs index e55075d7..bad1ea83 100644 --- a/Oqtane.Server/Controllers/SettingController.cs +++ b/Oqtane.Server/Controllers/SettingController.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; using Oqtane.Repository; using Oqtane.Models; using Oqtane.Shared; using Oqtane.Security; using Oqtane.Infrastructure; +using System.Linq; +using System.Security.Claims; +using Microsoft.AspNetCore.Http; namespace Oqtane.Controllers { @@ -13,13 +15,17 @@ namespace Oqtane.Controllers public class SettingController : Controller { private readonly ISettingRepository Settings; + private readonly IPageModuleRepository PageModules; private readonly IUserPermissions UserPermissions; + private readonly IHttpContextAccessor Accessor; private readonly ILogManager logger; - public SettingController(ISettingRepository Settings, IUserPermissions UserPermissions, ILogManager logger) + public SettingController(ISettingRepository Settings, IPageModuleRepository PageModules, IUserPermissions UserPermissions, IHttpContextAccessor Accessor, ILogManager logger) { this.Settings = Settings; + this.PageModules = PageModules; this.UserPermissions = UserPermissions; + this.Accessor = Accessor; this.logger = logger; } @@ -27,62 +33,117 @@ namespace Oqtane.Controllers [HttpGet] public IEnumerable Get(string entityname, int entityid) { - return Settings.GetSettings(entityname, entityid); + List settings = new List(); + if (IsAuthorized(entityname, entityid, "View")) + { + settings = Settings.GetSettings(entityname, entityid).ToList(); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityname, entityid); + HttpContext.Response.StatusCode = 401; + } + return settings; } // GET api//5 [HttpGet("{id}")] public Setting Get(int id) { - return Settings.GetSetting(id); + Setting setting = Settings.GetSetting(id); + if (IsAuthorized(setting.EntityName, setting.EntityId, "View")) + { + return setting; + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {Setting}", setting); + HttpContext.Response.StatusCode = 401; + return null; + } } // POST api/ [HttpPost] - [Authorize] public Setting Post([FromBody] Setting Setting) { - if (ModelState.IsValid && IsAuthorized(Setting.EntityName, Setting.EntityId)) + if (ModelState.IsValid && IsAuthorized(Setting.EntityName, Setting.EntityId, "Edit")) { Setting = Settings.AddSetting(Setting); logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", Setting); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Setting {Setting}", Setting); + HttpContext.Response.StatusCode = 401; + Setting = null; + } return Setting; } // PUT api//5 [HttpPut("{id}")] - [Authorize] public Setting Put(int id, [FromBody] Setting Setting) { - if (ModelState.IsValid && IsAuthorized(Setting.EntityName, Setting.EntityId)) + if (ModelState.IsValid && IsAuthorized(Setting.EntityName, Setting.EntityId, "Edit")) { Setting = Settings.UpdateSetting(Setting); logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", Setting); } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Setting {Setting}", Setting); + HttpContext.Response.StatusCode = 401; + Setting = null; + } return Setting; } // DELETE api//5 [HttpDelete("{id}")] - [Authorize(Roles = Constants.AdminRole)] public void Delete(int id) { - Settings.DeleteSetting(id); - logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {SettingId}", id); + Setting setting = Settings.GetSetting(id); + if (IsAuthorized(setting.EntityName, setting.EntityId, "Edit")) + { + Settings.DeleteSetting(id); + logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Setting {Setting}", setting); + HttpContext.Response.StatusCode = 401; + } } - private bool IsAuthorized(string EntityName, int EntityId) + private bool IsAuthorized(string EntityName, int EntityId, string PermissionName) { bool authorized = false; + if (EntityName == "PageModule") + { + EntityName = "Module"; + EntityId = PageModules.GetPageModule(EntityId).ModuleId; + } switch (EntityName) { - case "Module": - authorized = UserPermissions.IsAuthorized(User, EntityName, EntityId, "Edit"); + case "Host": + authorized = User.IsInRole(Constants.HostRole); break; - default: + case "Site": authorized = User.IsInRole(Constants.AdminRole); break; + case "Page": + case "Module": + case "Folder": + authorized = UserPermissions.IsAuthorized(User, EntityName, EntityId, PermissionName); + break; + case "User": + authorized = true; + if (PermissionName == "Edit") + { + authorized = User.IsInRole(Constants.AdminRole) || (int.Parse(Accessor.HttpContext.User.FindFirst(ClaimTypes.PrimarySid).Value) == EntityId); + } + break; } return authorized; } diff --git a/Oqtane.Server/Controllers/SiteController.cs b/Oqtane.Server/Controllers/SiteController.cs index 316a7ba3..23b5c4d7 100644 --- a/Oqtane.Server/Controllers/SiteController.cs +++ b/Oqtane.Server/Controllers/SiteController.cs @@ -29,6 +29,7 @@ namespace Oqtane.Controllers // GET: api/ [HttpGet] + [Authorize(Roles = Constants.HostRole)] public IEnumerable Get() { return Sites.GetSites(); diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index ecb9ad36..0e4915f0 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -30,6 +30,7 @@ namespace Oqtane.Controllers // GET: api/ [HttpGet] + [Authorize(Roles = Constants.RegisteredRole)] public IEnumerable Get() { return Themes.GetThemes(); diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 0660b5ff..b01404af 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -44,6 +44,7 @@ namespace Oqtane.Controllers // GET api//5?siteid=x [HttpGet("{id}")] + [Authorize] public User Get(int id, string siteid) { User user = Users.GetUser(id); @@ -172,18 +173,27 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - if (User.Password != "") + if (base.User.IsInRole(Constants.AdminRole) || base.User.Identity.Name == User.Username) { - IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username); - if (identityuser != null) + if (User.Password != "") { - identityuser.PasswordHash = IdentityUserManager.PasswordHasher.HashPassword(identityuser, User.Password); - await IdentityUserManager.UpdateAsync(identityuser); + IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username); + if (identityuser != null) + { + identityuser.PasswordHash = IdentityUserManager.PasswordHasher.HashPassword(identityuser, User.Password); + await IdentityUserManager.UpdateAsync(identityuser); + } } + User = Users.UpdateUser(User); + User.Password = ""; // remove sensitive information + logger.Log(LogLevel.Information, this, LogFunction.Update, "User Updated {User}", User); + } + else + { + logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update User {User}", User); + HttpContext.Response.StatusCode = 401; + User = null; } - User = Users.UpdateUser(User); - User.Password = ""; // remove sensitive information - logger.Log(LogLevel.Information, this, LogFunction.Update, "User Updated {User}", User); } return User; } diff --git a/Oqtane.Server/Controllers/UserRoleController.cs b/Oqtane.Server/Controllers/UserRoleController.cs index 7601818e..136c019f 100644 --- a/Oqtane.Server/Controllers/UserRoleController.cs +++ b/Oqtane.Server/Controllers/UserRoleController.cs @@ -22,6 +22,7 @@ namespace Oqtane.Controllers // GET: api/?userid=x [HttpGet] + [Authorize] public IEnumerable Get(string siteid) { return UserRoles.GetUserRoles(int.Parse(siteid)); @@ -29,6 +30,7 @@ namespace Oqtane.Controllers // GET api//5 [HttpGet("{id}")] + [Authorize] public UserRole Get(int id) { return UserRoles.GetUserRole(id); diff --git a/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs b/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs index 383da311..c629d76f 100644 --- a/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs @@ -6,8 +6,8 @@ namespace Oqtane.Repository public interface IModuleDefinitionRepository { IEnumerable GetModuleDefinitions(int SideId); + ModuleDefinition GetModuleDefinition(int ModuleDefinitionId, int SideId); void UpdateModuleDefinition(ModuleDefinition ModuleDefinition); void DeleteModuleDefinition(int ModuleDefinitionId, int SiteId); - } } diff --git a/Oqtane.Server/Repository/Interfaces/IModuleRepository.cs b/Oqtane.Server/Repository/Interfaces/IModuleRepository.cs index d7ed6251..262bcc90 100644 --- a/Oqtane.Server/Repository/Interfaces/IModuleRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IModuleRepository.cs @@ -10,5 +10,7 @@ namespace Oqtane.Repository Module UpdateModule(Module Module); Module GetModule(int ModuleId); void DeleteModule(int ModuleId); + string ExportModule(int ModuleId); + bool ImportModule(int ModuleId, string Content); } } diff --git a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs index ea05c552..c1445046 100644 --- a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs +++ b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs @@ -23,7 +23,33 @@ namespace Oqtane.Repository this.Permissions = Permissions; } - private List LoadModuleDefinitions(int SiteId) + public IEnumerable GetModuleDefinitions(int SiteId) + { + return LoadModuleDefinitions(SiteId); + } + + public ModuleDefinition GetModuleDefinition(int ModuleDefinitionId, int SiteId) + { + List moduledefinitions = LoadModuleDefinitions(SiteId); + return moduledefinitions.Find(item => item.ModuleDefinitionId == ModuleDefinitionId); + } + + public void UpdateModuleDefinition(ModuleDefinition ModuleDefinition) + { + Permissions.UpdatePermissions(ModuleDefinition.SiteId, "ModuleDefinition", ModuleDefinition.ModuleDefinitionId, ModuleDefinition.Permissions); + _cache.Remove("moduledefinitions"); + } + + public void DeleteModuleDefinition(int ModuleDefinitionId, int SiteId) + { + ModuleDefinition ModuleDefinition = db.ModuleDefinition.Find(ModuleDefinitionId); + Permissions.DeletePermissions(SiteId, "ModuleDefinition", ModuleDefinitionId); + db.ModuleDefinition.Remove(ModuleDefinition); + db.SaveChanges(); + _cache.Remove("moduledefinitions"); + } + + public List LoadModuleDefinitions(int SiteId) { List ModuleDefinitions; @@ -35,9 +61,9 @@ namespace Oqtane.Repository // sync module definitions with database List moduledefs = db.ModuleDefinition.ToList(); + List permissions = Permissions.GetPermissions(SiteId, "ModuleDefinition").ToList(); foreach (ModuleDefinition moduledefinition in ModuleDefinitions) { - IEnumerable permissions = Permissions.GetPermissions(SiteId, "ModuleDefinition").ToList(); ModuleDefinition moduledef = moduledefs.Where(item => item.ModuleDefinitionName == moduledefinition.ModuleDefinitionName).FirstOrDefault(); if (moduledef == null) { @@ -47,6 +73,10 @@ namespace Oqtane.Repository if (moduledefinition.Permissions != "") { Permissions.UpdatePermissions(SiteId, "ModuleDefinition", moduledef.ModuleDefinitionId, moduledefinition.Permissions); + foreach(Permission permission in Permissions.GetPermissions("ModuleDefinition", moduledef.ModuleDefinitionId)) + { + permissions.Add(permission); + } } } else @@ -65,6 +95,7 @@ namespace Oqtane.Repository // any remaining module definitions are orphans foreach (ModuleDefinition moduledefinition in moduledefs) { + Permissions.DeletePermissions(SiteId, "ModuleDefinition", moduledefinition.ModuleDefinitionId); db.ModuleDefinition.Remove(moduledefinition); // delete } @@ -128,7 +159,7 @@ namespace Oqtane.Repository ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1], ControlTypeRoutes = "", AssemblyName = assembly.FullName.Split(",")[0], - Permissions = "" + Permissions = "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"Administrators\"}]" }; } else @@ -150,8 +181,13 @@ namespace Oqtane.Repository ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1], ControlTypeRoutes = "", AssemblyName = assembly.FullName.Split(",")[0], - Permissions = ((QualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"Administrators\"}]" : "") + Permissions = "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"" + Constants.AdminRole + "\"}]" }; + // make non-admin modules available by default to registered users on personalized pages + if (moduledefinition.Categories != "Admin") + { + moduledefinition.Permissions = "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"" + Constants.AdminRole + ";" + Constants.RegisteredRole + "\"}]"; + } } moduledefinitions.Add(moduledefinition); index = moduledefinitions.FindIndex(item => item.ModuleDefinitionName == QualifiedModuleType); @@ -162,7 +198,7 @@ namespace Oqtane.Repository string actions = (string)modulecontroltype.GetProperty("Actions").GetValue(modulecontrolobject); if (actions != "") { - foreach(string action in actions.Split(',')) + foreach (string action in actions.Split(',')) { moduledefinition.ControlTypeRoutes += (action + "=" + modulecontroltype.FullName + ", " + typename[1] + ";"); } @@ -183,23 +219,5 @@ namespace Oqtane.Repository } return Value; } - - public IEnumerable GetModuleDefinitions(int SiteId) - { - return LoadModuleDefinitions(SiteId); - } - - public void UpdateModuleDefinition(ModuleDefinition ModuleDefinition) - { - Permissions.UpdatePermissions(ModuleDefinition.SiteId, "ModuleDefinition", ModuleDefinition.ModuleDefinitionId, ModuleDefinition.Permissions); - } - - public void DeleteModuleDefinition(int ModuleDefinitionId, int SiteId) - { - ModuleDefinition ModuleDefinition = db.ModuleDefinition.Find(ModuleDefinitionId); - Permissions.DeletePermissions(SiteId, "ModuleDefinition", ModuleDefinitionId); - db.ModuleDefinition.Remove(ModuleDefinition); - db.SaveChanges(); - } } } diff --git a/Oqtane.Server/Repository/ModuleRepository.cs b/Oqtane.Server/Repository/ModuleRepository.cs index c800e790..6d978ba4 100644 --- a/Oqtane.Server/Repository/ModuleRepository.cs +++ b/Oqtane.Server/Repository/ModuleRepository.cs @@ -2,6 +2,11 @@ using System.Collections.Generic; using System.Linq; using Oqtane.Models; +using System.Reflection; +using System; +using Oqtane.Modules; +using Microsoft.Extensions.DependencyInjection; +using System.Text.Json; namespace Oqtane.Repository { @@ -9,19 +14,23 @@ namespace Oqtane.Repository { private TenantDBContext db; private readonly IPermissionRepository Permissions; + private readonly IModuleDefinitionRepository ModuleDefinitions; + private readonly IServiceProvider ServiceProvider; - public ModuleRepository(TenantDBContext context, IPermissionRepository Permissions) + public ModuleRepository(TenantDBContext context, IPermissionRepository Permissions, IModuleDefinitionRepository ModuleDefinitions, IServiceProvider ServiceProvider) { db = context; this.Permissions = Permissions; + this.ModuleDefinitions = ModuleDefinitions; + this.ServiceProvider = ServiceProvider; } - public IEnumerable GetModules() + public IEnumerable GetModules() { return db.Module; } - public Module AddModule(Module Module) + public Models.Module AddModule(Models.Module Module) { db.Module.Add(Module); db.SaveChanges(); @@ -29,7 +38,7 @@ namespace Oqtane.Repository return Module; } - public Module UpdateModule(Module Module) + public Models.Module UpdateModule(Models.Module Module) { db.Entry(Module).State = EntityState.Modified; db.SaveChanges(); @@ -37,9 +46,9 @@ namespace Oqtane.Repository return Module; } - public Module GetModule(int ModuleId) + public Models.Module GetModule(int ModuleId) { - Module module = db.Module.Find(ModuleId); + Models.Module module = db.Module.Find(ModuleId); if (module != null) { List permissions = Permissions.GetPermissions("Module", module.ModuleId).ToList(); @@ -50,10 +59,100 @@ namespace Oqtane.Repository public void DeleteModule(int ModuleId) { - Module Module = db.Module.Find(ModuleId); + Models.Module Module = db.Module.Find(ModuleId); Permissions.DeletePermissions(Module.SiteId, "Module", ModuleId); db.Module.Remove(Module); db.SaveChanges(); } + + public string ExportModule(int ModuleId) + { + string content = ""; + try + { + Models.Module module = GetModule(ModuleId); + if (module != null) + { + List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); + ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); + if (moduledefinition != null) + { + ModuleContent modulecontent = new ModuleContent(); + modulecontent.ModuleDefinitionName = moduledefinition.ModuleDefinitionName; + modulecontent.Version = moduledefinition.Version; + modulecontent.Content = ""; + + if (moduledefinition.ServerAssemblyName != "") + { + Assembly assembly = AppDomain.CurrentDomain.GetAssemblies() + .Where(item => item.FullName.StartsWith(moduledefinition.ServerAssemblyName)).FirstOrDefault(); + if (assembly != null) + { + Type moduletype = assembly.GetTypes() + .Where(item => item.Namespace != null) + .Where(item => item.Namespace.StartsWith(moduledefinition.ModuleDefinitionName.Substring(0, moduledefinition.ModuleDefinitionName.IndexOf(",")))) + .Where(item => item.GetInterfaces().Contains(typeof(IPortable))).FirstOrDefault(); + if (moduletype != null) + { + var moduleobject = ActivatorUtilities.CreateInstance(ServiceProvider, moduletype); + modulecontent.Content = ((IPortable)moduleobject).ExportModule(module); + } + } + } + content = JsonSerializer.Serialize(modulecontent); + } + } + } + catch + { + // error occurred during export + } + return content; + } + + public bool ImportModule(int ModuleId, string Content) + { + bool success = false; + try + { + Models.Module module = GetModule(ModuleId); + if (module != null) + { + List moduledefinitions = ModuleDefinitions.GetModuleDefinitions(module.SiteId).ToList(); + ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == module.ModuleDefinitionName).FirstOrDefault(); + if (moduledefinition != null) + { + ModuleContent modulecontent = JsonSerializer.Deserialize(Content); + if (modulecontent.ModuleDefinitionName == moduledefinition.ModuleDefinitionName) + { + if (moduledefinition.ServerAssemblyName != "") + { + Assembly assembly = AppDomain.CurrentDomain.GetAssemblies() + .Where(item => item.FullName.StartsWith(moduledefinition.ServerAssemblyName)).FirstOrDefault(); + if (assembly != null) + { + Type moduletype = assembly.GetTypes() + .Where(item => item.Namespace != null) + .Where(item => item.Namespace.StartsWith(moduledefinition.ModuleDefinitionName.Substring(0, moduledefinition.ModuleDefinitionName.IndexOf(",")))) + .Where(item => item.GetInterfaces().Contains(typeof(IPortable))).FirstOrDefault(); + if (moduletype != null) + { + var moduleobject = ActivatorUtilities.CreateInstance(ServiceProvider, moduletype); + ((IPortable)moduleobject).ImportModule(module, modulecontent.Content, modulecontent.Version); + success = true; + } + } + } + } + } + } + } + catch + { + // error occurred during import + } + return success; + } + } } diff --git a/Oqtane.Shared/Models/Module.cs b/Oqtane.Shared/Models/Module.cs index b7e19e84..0466c326 100644 --- a/Oqtane.Shared/Models/Module.cs +++ b/Oqtane.Shared/Models/Module.cs @@ -49,6 +49,10 @@ namespace Oqtane.Models [NotMapped] public int PaneModuleCount { get; set; } + // ModuleDefinition + [NotMapped] + public ModuleDefinition ModuleDefinition { get; set; } + // IModuleControl properties [NotMapped] public SecurityAccessLevel SecurityAccessLevel { get; set; }