diff --git a/Oqtane.Client/Modules/Admin/Modules/Export.razor b/Oqtane.Client/Modules/Admin/Modules/Export.razor index fb5938f4..6afb875b 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Export.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Export.razor @@ -19,7 +19,7 @@ @code { private string _content = string.Empty; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; public override string Title => "Export Content"; @@ -27,7 +27,7 @@ { try { - _content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId); + _content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId, PageState.Page.PageId); AddModuleMessage(Localizer["Success.Content.Export"], MessageType.Success); } catch (Exception ex) diff --git a/Oqtane.Client/Modules/Admin/Modules/Import.razor b/Oqtane.Client/Modules/Admin/Modules/Import.razor index 7241b294..961157eb 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Import.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Import.razor @@ -25,7 +25,7 @@ private ElementReference form; private bool validated = false; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; public override string Title => "Import Content"; private async Task ImportModule() @@ -38,7 +38,7 @@ { try { - bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content); + bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, PageState.Page.PageId, _content); if (success) { AddModuleMessage(Localizer["Success.Content.Import"], MessageType.Success); diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index b628abb1..ab1cb528 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -153,6 +153,22 @@ namespace Oqtane.Modules return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate); } + public string AddUrlParameters(params string[] parameters) + { + return AddUrlParameters(PageState.Page.Path, parameters); + } + + public string AddUrlParameters(string path, params string[] parameters) + { + var url = path + "/" + Constants.UrlParametersDelimiter; + for (var i = 0; i < parameters.Length; i++) + { + url += "/" + parameters[i]; + } + return url; + } + + // parameters template is in the form of a standard route template ie. "{id}/{name}" public virtual Dictionary GetUrlParameters(string parametersTemplate = "") { var urlParameters = new Dictionary(); diff --git a/Oqtane.Client/Services/Interfaces/IModuleService.cs b/Oqtane.Client/Services/Interfaces/IModuleService.cs index b8718a66..a25aa3f7 100644 --- a/Oqtane.Client/Services/Interfaces/IModuleService.cs +++ b/Oqtane.Client/Services/Interfaces/IModuleService.cs @@ -50,13 +50,13 @@ namespace Oqtane.Services /// /// module in JSON format /// - Task ImportModuleAsync(int moduleId, string content); + Task ImportModuleAsync(int moduleId, int pageId, string content); /// /// Exports a given module /// /// /// module in JSON - Task ExportModuleAsync(int moduleId); + Task ExportModuleAsync(int moduleId, int pageId); } } diff --git a/Oqtane.Client/Services/ModuleService.cs b/Oqtane.Client/Services/ModuleService.cs index 70d47d45..a87229f7 100644 --- a/Oqtane.Client/Services/ModuleService.cs +++ b/Oqtane.Client/Services/ModuleService.cs @@ -5,6 +5,7 @@ using System.Net.Http; using System.Threading.Tasks; using Oqtane.Documentation; using Oqtane.Shared; +using Oqtane.Modules.Controls; namespace Oqtane.Services { @@ -44,14 +45,14 @@ namespace Oqtane.Services await DeleteAsync($"{Apiurl}/{moduleId.ToString()}"); } - public async Task ImportModuleAsync(int moduleId, string content) + public async Task ImportModuleAsync(int moduleId, int pageId, string content) { - return await PostJsonAsync($"{Apiurl}/import?moduleid={moduleId}", content); + return await PostJsonAsync($"{Apiurl}/import?moduleid={moduleId}&pageid={pageId}", content); } - public async Task ExportModuleAsync(int moduleId) - { - return await GetStringAsync($"{Apiurl}/export?moduleid={moduleId}"); + public async Task ExportModuleAsync(int moduleId, int pageId) +{ + return await GetStringAsync($"{Apiurl}/export?moduleid={moduleId}&pageid={pageId}"); } } } diff --git a/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor b/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor index 79f44e8e..c8445e38 100644 --- a/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor +++ b/Oqtane.Client/Themes/Controls/Container/ModuleActions.razor @@ -2,44 +2,44 @@ @inherits ModuleActionsBase @attribute [OqtaneIgnore] -@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions) && PageState.Action == Constants.DefaultAction) +@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction) { -
- - -
+
+ + +
} diff --git a/Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs b/Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs index 63d9249e..8714b938 100644 --- a/Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs +++ b/Oqtane.Client/Themes/Controls/Container/ModuleActionsBase.cs @@ -29,54 +29,55 @@ namespace Oqtane.Themes.Controls protected virtual List GetActions() { var actionList = new List(); - if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions)) + + if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) { - actionList.Add(new ActionViewModel {Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)}); - + actionList.Add(new ActionViewModel { Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m) }); + if (UserSecurity.ContainsRole(ModuleState.Permissions, PermissionNames.View, RoleNames.Everyone)) { - actionList.Add(new ActionViewModel {Icon=Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) }); + actionList.Add(new ActionViewModel { Icon = Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) }); } else { - actionList.Add(new ActionViewModel {Icon=Icons.CircleCheck, Name = "Publish Module", Action = async (s, m) => await Publish(s, m) }); + actionList.Add(new ActionViewModel { Icon = Icons.CircleCheck, Name = "Publish Module", Action = async (s, m) => await Publish(s, m) }); } - actionList.Add(new ActionViewModel {Icon=Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) }); + actionList.Add(new ActionViewModel { Icon = Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) }); if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "") { actionList.Add(new ActionViewModel { Name = "" }); - actionList.Add(new ActionViewModel {Icon=Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import")}); - actionList.Add(new ActionViewModel {Icon = Icons.CloudDownload, Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")}); + actionList.Add(new ActionViewModel { Icon = Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import") }); + actionList.Add(new ActionViewModel { Icon = Icons.CloudDownload, Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export") }); } - actionList.Add(new ActionViewModel {Name = ""}); + actionList.Add(new ActionViewModel { Name = "" }); if (ModuleState.PaneModuleIndex > 0) { - actionList.Add(new ActionViewModel {Icon = Icons.DataTransferUpload ,Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)}); + actionList.Add(new ActionViewModel { Icon = Icons.DataTransferUpload, Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m) }); } if (ModuleState.PaneModuleIndex > 0) { - actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickTop, Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)}); + actionList.Add(new ActionViewModel { Icon = Icons.ArrowThickTop, Name = "Move Up", Action = async (s, m) => await MoveUp(s, m) }); } if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1)) { - actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickBottom, Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)}); + actionList.Add(new ActionViewModel { Icon = Icons.ArrowThickBottom, Name = "Move Down", Action = async (s, m) => await MoveDown(s, m) }); } if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1)) { - actionList.Add(new ActionViewModel {Icon = Icons.DataTransferDownload, Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)}); + actionList.Add(new ActionViewModel { Icon = Icons.DataTransferDownload, Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m) }); } foreach (string pane in PageState.Page.Panes) { if (pane != ModuleState.Pane) { - actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)}); + actionList.Add(new ActionViewModel { Icon = Icons.AccountLogin, Name = pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m) }); } } } diff --git a/Oqtane.Client/UI/Pane.razor b/Oqtane.Client/UI/Pane.razor index 357d9b26..5627c96e 100644 --- a/Oqtane.Client/UI/Pane.razor +++ b/Oqtane.Client/UI/Pane.razor @@ -17,46 +17,46 @@ else } @code { - private bool _useadminborder = false; - private string _panetitle = ""; + private bool _useadminborder = false; + private string _panetitle = ""; - [CascadingParameter] - protected PageState PageState { get; set; } + [CascadingParameter] + protected PageState PageState { get; set; } - [Parameter] - public string Name { get; set; } + [Parameter] + public string Name { get; set; } - RenderFragment DynamicComponent { get; set; } + RenderFragment DynamicComponent { get; set; } - protected override void OnParametersSet() - { - if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction) - { - _useadminborder = true; - _panetitle = "
" + Name + " Pane
"; - } - else - { - _useadminborder = false; - _panetitle = ""; - } + protected override void OnParametersSet() + { + if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && PageState.Action == Constants.DefaultAction) + { + _useadminborder = true; + _panetitle = "
" + Name + " Pane
"; + } + else + { + _useadminborder = false; + _panetitle = ""; + } - DynamicComponent = builder => - { - if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction) - { - if (Name.ToLower() == PaneNames.Admin.ToLower()) - { - Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId); - if (module != null) - { - var moduleType = Type.GetType(module.ModuleType); - if (moduleType != null) - { - bool authorized = false; - if (Constants.DefaultModuleActions.Contains(PageState.Action)) - { - authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions); + DynamicComponent = builder => + { + if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction) + { + if (Name.ToLower() == PaneNames.Admin.ToLower()) + { + Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId); + if (module != null) + { + var moduleType = Type.GetType(module.ModuleType); + if (moduleType != null) + { + bool authorized = false; + if (Constants.DefaultModuleActions.Contains(PageState.Action)) + { + authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions); } else { diff --git a/Oqtane.Server/Controllers/ModuleController.cs b/Oqtane.Server/Controllers/ModuleController.cs index 9337ec58..60d23951 100644 --- a/Oqtane.Server/Controllers/ModuleController.cs +++ b/Oqtane.Server/Controllers/ModuleController.cs @@ -205,14 +205,14 @@ namespace Oqtane.Controllers } } - // GET api//export?moduleid=x + // GET api//export?moduleid=x&pageid=y [HttpGet("export")] [Authorize(Roles = RoleNames.Registered)] - public string Export(int moduleid) + public string Export(int moduleid, int pageid) { string content = ""; var module = _modules.GetModule(moduleid); - if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit)) + if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Page, pageid, PermissionNames.Edit)) { content = _modules.ExportModule(moduleid); if (!string.IsNullOrEmpty(content)) @@ -232,14 +232,14 @@ namespace Oqtane.Controllers return content; } - // POST api//import?moduleid=x + // POST api//import?moduleid=x&pageid=y [HttpPost("import")] [Authorize(Roles = RoleNames.Registered)] - public bool Import(int moduleid, [FromBody] string content) + public bool Import(int moduleid, int pageid, [FromBody] string content) { bool success = false; var module = _modules.GetModule(moduleid); - if (ModelState.IsValid && module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit)) + if (ModelState.IsValid && module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Page, pageid, PermissionNames.Edit)) { success = _modules.ImportModule(moduleid, content); if (success) diff --git a/Oqtane.Server/Controllers/PageModuleController.cs b/Oqtane.Server/Controllers/PageModuleController.cs index d7015e09..9b396d0d 100644 --- a/Oqtane.Server/Controllers/PageModuleController.cs +++ b/Oqtane.Server/Controllers/PageModuleController.cs @@ -54,7 +54,7 @@ namespace Oqtane.Controllers public PageModule Get(int pageid, int moduleid) { PageModule pagemodule = _pageModules.GetPageModule(pageid, moduleid); - if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, pagemodule.Module.Permissions)) + if (pagemodule != null && pagemodule.Module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, pagemodule.Module.Permissions)) { return pagemodule; } @@ -93,7 +93,7 @@ namespace Oqtane.Controllers public PageModule Put(int id, [FromBody] PageModule pageModule) { var page = _pages.GetPage(pageModule.PageId); - if (ModelState.IsValid && page != null && page.SiteId == _alias.SiteId && _pageModules.GetPageModule(pageModule.PageModuleId, false) != null && _userPermissions.IsAuthorized(User, EntityNames.Module, pageModule.ModuleId, PermissionNames.Edit)) + if (ModelState.IsValid && page != null && page.SiteId == _alias.SiteId && _pageModules.GetPageModule(pageModule.PageModuleId, false) != null && _userPermissions.IsAuthorized(User, EntityNames.Page, pageModule.PageId, PermissionNames.Edit)) { pageModule = _pageModules.UpdatePageModule(pageModule); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);