Merge pull request #651 from sbwalker/master

Html encode job log messages, add new IModule property to allow modules to specify Runtime support, provide feedback during module content import, remove default EditMode option at the Page level (should be implemented at Module level) - resolves issue where Admin modules could not be deleted, include link to Event Log in AddModuleMessage for Error message type, fixed fallback support for themes in siterouter, integrated auth policy into site templates for Module Creator
This commit is contained in:
Shaun Walker 2020-07-08 19:57:13 -04:00 committed by GitHub
commit 3703d87d50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 220 additions and 165 deletions

View File

@ -22,7 +22,7 @@ else
<td>@context.FinishDate</td> <td>@context.FinishDate</td>
</Row> </Row>
<Detail> <Detail>
<td colspan="4">@context.Notes</td> <td colspan="4">@((MarkupString)context.Notes)</td>
</Detail> </Detail>
</Pager> </Pager>
} }

View File

@ -75,12 +75,20 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<Label For="license" HelpText="The license of the module">License: </Label> <Label For="license" HelpText="The module license terms">License: </Label>
</td> </td>
<td> <td>
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea> <textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
</td> </td>
</tr> </tr>
<tr>
<td>
<Label For="runtimes" HelpText="The Blazor runtimes which this module supports">Runtimes: </Label>
</td>
<td>
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
</td>
</tr>
</table> </table>
</Section> </Section>
</TabPanel> </TabPanel>
@ -110,6 +118,7 @@
private string _url = ""; private string _url = "";
private string _contact = ""; private string _contact = "";
private string _license = ""; private string _license = "";
private string _runtimes = "";
private string _permissions; private string _permissions;
private string _createdby; private string _createdby;
private DateTime _createdon; private DateTime _createdon;
@ -139,6 +148,7 @@
_url = moduleDefinition.Url; _url = moduleDefinition.Url;
_contact = moduleDefinition.Contact; _contact = moduleDefinition.Contact;
_license = moduleDefinition.License; _license = moduleDefinition.License;
_runtimes = moduleDefinition.Runtimes;
_permissions = moduleDefinition.Permissions; _permissions = moduleDefinition.Permissions;
_createdby = moduleDefinition.CreatedBy; _createdby = moduleDefinition.CreatedBy;
_createdon = moduleDefinition.CreatedOn; _createdon = moduleDefinition.CreatedOn;

View File

@ -31,9 +31,15 @@
{ {
try try
{ {
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content); bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
StateHasChanged(); if (success)
NavigationManager.NavigateTo(NavigateUrl()); {
AddModuleMessage("Content Imported Successfully", MessageType.Success);
}
else
{
AddModuleMessage("A Problem Was Encountered Importing Content. Please Ensure The Content Is Formatted Correctly For The Module.", MessageType.Warning);
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -162,17 +162,6 @@
<input id="Icon" class="form-control" @bind="@_icon" /> <input id="Icon" class="form-control" @bind="@_icon" />
</td> </td>
</tr> </tr>
<tr>
<td>
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
</td>
<td>
<select id="Default-Mode" class="form-control" @bind="@_mode">
<option value="view">View Mode</option>
<option value="edit">Edit Mode</option>
</select>
</td>
</tr>
<tr> <tr>
<td> <td>
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label> <Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
@ -217,7 +206,6 @@
private string _isnavigation = "True"; private string _isnavigation = "True";
private string _url; private string _url;
private string _ispersonalizable = "False"; private string _ispersonalizable = "False";
private string _mode = "view";
private string _themetype = "-"; private string _themetype = "-";
private string _layouttype = "-"; private string _layouttype = "-";
private string _containertype = "-"; private string _containertype = "-";
@ -373,7 +361,6 @@
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
page.Url = _url; page.Url = _url;
page.EditMode = (_mode == "edit" ? true : false);
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
{ {

View File

@ -173,17 +173,6 @@
<input id="Icon" class="form-control" @bind="@_icon" /> <input id="Icon" class="form-control" @bind="@_icon" />
</td> </td>
</tr> </tr>
<tr>
<td>
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
</td>
<td>
<select id="Default-Mode" class="form-control" @bind="@_mode">
<option value="view">View Mode</option>
<option value="edit">Edit Mode</option>
</select>
</td>
</tr>
<tr> <tr>
<td> <td>
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label> <Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
@ -235,7 +224,6 @@
private string _isnavigation; private string _isnavigation;
private string _url; private string _url;
private string _ispersonalizable; private string _ispersonalizable;
private string _mode;
private string _themetype = "-"; private string _themetype = "-";
private string _layouttype = "-"; private string _layouttype = "-";
private string _containertype = "-"; private string _containertype = "-";
@ -290,7 +278,6 @@
_isnavigation = page.IsNavigation.ToString(); _isnavigation = page.IsNavigation.ToString();
_url = page.Url; _url = page.Url;
_ispersonalizable = page.IsPersonalizable.ToString(); _ispersonalizable = page.IsPersonalizable.ToString();
_mode = (page.EditMode) ? "edit" : "view";
_themetype = page.ThemeType; _themetype = page.ThemeType;
if (_themetype == PageState.Site.DefaultThemeType) if (_themetype == PageState.Site.DefaultThemeType)
{ {
@ -463,7 +450,6 @@
} }
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
page.Url = _url; page.Url = _url;
page.EditMode = (_mode == "edit");
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
{ {

View File

@ -100,7 +100,7 @@
private bool IsAuthorized() private bool IsAuthorized()
{ {
bool authorized = false; bool authorized = false;
if (PageState.EditMode || !_editmode) if (PageState.EditMode || _editmode)
{ {
SecurityAccessLevel security = SecurityAccessLevel.Host; SecurityAccessLevel security = SecurityAccessLevel.Host;
if (Security == null) if (Security == null)

View File

@ -100,7 +100,7 @@
private bool IsAuthorized() private bool IsAuthorized()
{ {
var authorized = false; var authorized = false;
if (PageState.EditMode || !_editmode) if (PageState.EditMode || _editmode)
{ {
var security = SecurityAccessLevel.Host; var security = SecurityAccessLevel.Host;
if (Security == null) if (Security == null)

View File

@ -1,9 +1,16 @@
@namespace Oqtane.Modules.Controls @namespace Oqtane.Modules.Controls
@inherits ModuleControlBase @inherits ModuleControlBase
@inject NavigationManager NavigationManager
@if (!string.IsNullOrEmpty(_message)) @if (!string.IsNullOrEmpty(_message))
{ {
<div class="@_classname" role="alert">@_message</div> <div class="@_classname" role="alert">
@_message
@if (Type == MessageType.Error && UserSecurity.IsAuthorized(PageState.User, Constants.HostRole))
{
@((MarkupString)"&nbsp;&nbsp;")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
}
</div>
<br /> <br />
} }

View File

@ -7,12 +7,12 @@
@if (PageState.EditMode) @if (PageState.EditMode)
{ {
<br /><ActionLink Action="Edit" /><br /><br /> <br /><ActionLink Action="Edit" EditMode="false" /><br /><br />
} }
@code { @code {
public override List<Resource> Resources => new List<Resource>() public override List<Resource> Resources => new List<Resource>()
{ {
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" } new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
}; };

View File

@ -127,7 +127,10 @@
{ {
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
{ {
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option> if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
{
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
}
} }
} }
</select> </select>
@ -196,26 +199,17 @@
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null)) @if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
{ {
@if (PageState.Page.EditMode) if (PageState.EditMode)
{ {
<button type="button" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off"> <button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span> <span class="oi oi-pencil"></span>
</button> </button>
} }
else else
{ {
if (PageState.EditMode) <button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
{ <span class="oi oi-pencil"></span>
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))"> </button>
<span class="oi oi-pencil"></span>
</button>
}
else
{
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
<span class="oi oi-pencil"></span>
</button>
}
} }
} }

View File

@ -2,7 +2,7 @@
@inherits ModuleActionsBase @inherits ModuleActionsBase
@attribute [OqtaneIgnore] @attribute [OqtaneIgnore]
@if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions)) @if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
{ {
<div class="app-moduleactions"> <div class="app-moduleactions">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a> <a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>

View File

@ -1,4 +1,5 @@
@namespace Oqtane.UI @using Microsoft.AspNetCore.Components.Rendering
@namespace Oqtane.UI
@inject IUserService UserService @inject IUserService UserService
@inject IModuleService ModuleService @inject IModuleService ModuleService
@inject IModuleDefinitionService ModuleDefinitionService @inject IModuleDefinitionService ModuleDefinitionService
@ -25,7 +26,7 @@
protected override void OnParametersSet() protected override void OnParametersSet()
{ {
if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane) if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
{ {
_paneadminborder = "app-pane-admin-border"; _paneadminborder = "app-pane-admin-border";
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>"; _panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
@ -51,7 +52,7 @@
{ {
typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, PageState.Action); typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, PageState.Action);
} }
var moduleType = Type.GetType(typename); var moduleType = Type.GetType(typename);
if (moduleType != null) if (moduleType != null)
{ {
@ -88,10 +89,7 @@
{ {
module.Title = module.ControlTitle; module.Title = module.ControlTitle;
} }
CreateComponent(builder, module);
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module);
builder.CloseComponent();
} }
} }
else else
@ -111,9 +109,7 @@
// check if user is authorized to view module // check if user is authorized to view module
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
{ {
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent)); CreateComponent(builder, module);
builder.AddAttribute(1, "Module", module);
builder.CloseComponent();
} }
} }
} }
@ -124,14 +120,19 @@
// check if user is authorized to view module // check if user is authorized to view module
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
{ {
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent)); CreateComponent(builder, module);
builder.AddAttribute(1, "Module", module);
builder.SetKey(module.PageModuleId);
builder.CloseComponent();
} }
} }
} }
} }
}; };
} }
private void CreateComponent(RenderTreeBuilder builder, Module module)
{
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
builder.AddAttribute(1, "Module", module);
builder.SetKey(module.PageModuleId);
builder.CloseComponent();
}
} }

View File

@ -260,17 +260,14 @@
{ {
page = pages.Where(item => item.Path == path).FirstOrDefault(); page = pages.Where(item => item.Path == path).FirstOrDefault();
reload = Reload.Page; reload = Reload.Page;
if (page != null) editmode = false;
{
editmode = page.EditMode;
}
} }
if (page != null) if (page != null)
{ {
if (PageState == null) if (PageState == null)
{ {
editmode = page.EditMode; editmode = false;
} }
// check if user is authorized to view page // check if user is authorized to view page
@ -401,6 +398,13 @@
string panes = ""; string panes = "";
Type themetype = Type.GetType(page.ThemeType); Type themetype = Type.GetType(page.ThemeType);
if (themetype == null)
{
// fallback
page.ThemeType = Constants.DefaultTheme;
page.LayoutType = Constants.DefaultLayout;
themetype = Type.GetType(Constants.DefaultTheme);
}
if (themetype != null) if (themetype != null)
{ {
var themeobject = Activator.CreateInstance(themetype) as IThemeControl; var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
@ -442,7 +446,7 @@
if (module.PageId == page.PageId || module.ModuleId == moduleid) if (module.PageId == page.PageId || module.ModuleId == moduleid)
{ {
var typename = string.Empty; var typename = string.Empty;
if (module.ModuleDefinition != null) if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
{ {
typename = module.ModuleDefinition.ControlTypeTemplate; typename = module.ModuleDefinition.ControlTypeTemplate;
} }

View File

@ -54,11 +54,6 @@
DynamicComponent = builder => DynamicComponent = builder =>
{ {
var themeType = Type.GetType(PageState.Page.ThemeType); var themeType = Type.GetType(PageState.Page.ThemeType);
if (themeType == null)
{
// fallback
themeType = Type.GetType(Constants.DefaultTheme);
}
builder.OpenComponent(0, themeType); builder.OpenComponent(0, themeType);
builder.CloseComponent(); builder.CloseComponent();
}; };

View File

@ -122,7 +122,7 @@ namespace Oqtane.Controllers
var pages = _pages.GetPages(module.SiteId).ToList(); var pages = _pages.GetPages(module.SiteId).ToList();
foreach (Page page in pages) foreach (Page page in pages)
{ {
if (page.PageId != pageModule.PageId && !page.EditMode) if (page.PageId != pageModule.PageId && !page.Path.StartsWith("admin/"))
{ {
_pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType }); _pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType });
} }

View File

@ -125,7 +125,7 @@ namespace Oqtane.Controllers
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, page.SiteId); _syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, page.SiteId);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", page); _logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", page);
if (!page.EditMode) if (!page.Path.StartsWith("admin/"))
{ {
var modules = _modules.GetModules(page.SiteId).Where(item => item.AllPages).ToList(); var modules = _modules.GetModules(page.SiteId).Where(item => item.AllPages).ToList();
foreach (Module module in modules) foreach (Module module in modules)
@ -163,7 +163,6 @@ namespace Oqtane.Controllers
page.Order = 0; page.Order = 0;
page.IsNavigation = false; page.IsNavigation = false;
page.Url = ""; page.Url = "";
page.EditMode = false;
page.ThemeType = parent.ThemeType; page.ThemeType = parent.ThemeType;
page.LayoutType = parent.LayoutType; page.LayoutType = parent.LayoutType;
page.DefaultContainerType = parent.DefaultContainerType; page.DefaultContainerType = parent.DefaultContainerType;

View File

@ -38,7 +38,7 @@ namespace Oqtane.Infrastructure
List<Site> sites = siteRepository.GetSites().ToList(); List<Site> sites = siteRepository.GetSites().ToList();
foreach (Site site in sites) foreach (Site site in sites)
{ {
log += "Processing Notifications For Site: " + site.Name + "\n\n"; log += "Processing Notifications For Site: " + site.Name + "<br />";
// get site settings // get site settings
List<Setting> sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList(); List<Setting> sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList();
@ -101,14 +101,14 @@ namespace Oqtane.Infrastructure
catch (Exception ex) catch (Exception ex)
{ {
// error // error
log += ex.Message + "\n\n"; log += ex.Message + "<br />";
} }
} }
log += "Notifications Delivered: " + sent + "\n\n"; log += "Notifications Delivered: " + sent + "<br />";
} }
else else
{ {
log += "SMTP Not Configured" + "\n\n"; log += "SMTP Not Configured" + "<br />";
} }
} }
} }
@ -116,7 +116,6 @@ namespace Oqtane.Infrastructure
return log; return log;
} }
private Dictionary<string, string> GetSettings(List<Setting> settings) private Dictionary<string, string> GetSettings(List<Setting> settings)
{ {
Dictionary<string, string> dictionary = new Dictionary<string, string>(); Dictionary<string, string> dictionary = new Dictionary<string, string>();

View File

@ -42,7 +42,6 @@ namespace Oqtane.SiteTemplates
Icon = "home", Icon = "home",
IsNavigation = true, IsNavigation = true,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> { PagePermissions = new List<Permission> {
new Permission(PermissionNames.View, Constants.AllUsersRole, true), new Permission(PermissionNames.View, Constants.AllUsersRole, true),
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -89,7 +88,6 @@ namespace Oqtane.SiteTemplates
Icon = "lock-locked", Icon = "lock-locked",
IsNavigation = true, IsNavigation = true,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> { PagePermissions = new List<Permission> {
new Permission(PermissionNames.View, Constants.RegisteredRole, true), new Permission(PermissionNames.View, Constants.RegisteredRole, true),
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -114,7 +112,6 @@ namespace Oqtane.SiteTemplates
Icon = "target", Icon = "target",
IsNavigation = true, IsNavigation = true,
IsPersonalizable = true, IsPersonalizable = true,
EditMode = false,
PagePermissions = new List<Permission> { PagePermissions = new List<Permission> {
new Permission(PermissionNames.View, Constants.AllUsersRole, true), new Permission(PermissionNames.View, Constants.AllUsersRole, true),
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),

View File

@ -30,7 +30,6 @@ namespace Oqtane.SiteTemplates
Icon = "home", Icon = "home",
IsNavigation = true, IsNavigation = true,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> { PagePermissions = new List<Permission> {
new Permission(PermissionNames.View, Constants.AllUsersRole, true), new Permission(PermissionNames.View, Constants.AllUsersRole, true),
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),

View File

@ -22,6 +22,9 @@
<Content Remove="wwwroot\Modules\Templates\**" /> <Content Remove="wwwroot\Modules\Templates\**" />
<EmbeddedResource Remove="wwwroot\Modules\Templates\**" /> <EmbeddedResource Remove="wwwroot\Modules\Templates\**" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Scripts\Tenant.01.00.02.01.sql" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Scripts\Master.00.00.00.00.sql" /> <EmbeddedResource Include="Scripts\Master.00.00.00.00.sql" />
<EmbeddedResource Include="Scripts\Master.00.09.00.00.sql" /> <EmbeddedResource Include="Scripts\Master.00.09.00.00.sql" />
@ -32,6 +35,7 @@
<EmbeddedResource Include="Scripts\Tenant.00.09.02.00.sql" /> <EmbeddedResource Include="Scripts\Tenant.00.09.02.00.sql" />
<EmbeddedResource Include="Scripts\Tenant.01.00.01.00.sql" /> <EmbeddedResource Include="Scripts\Tenant.01.00.01.00.sql" />
<EmbeddedResource Include="Scripts\Tenant.01.00.01.01.sql" /> <EmbeddedResource Include="Scripts\Tenant.01.00.01.01.sql" />
<EmbeddedResource Include="Scripts\Tenant.01.00.02.01.sql" />
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" /> <EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" /> <EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
</ItemGroup> </ItemGroup>

View File

@ -58,7 +58,6 @@ namespace Oqtane.Repository
Icon = Icons.LockLocked, Icon = Icons.LockLocked,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -88,7 +87,6 @@ namespace Oqtane.Repository
Icon = Icons.Person, Icon = Icons.Person,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -119,7 +117,6 @@ namespace Oqtane.Repository
Icon = Icons.Person, Icon = Icons.Person,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -149,7 +146,6 @@ namespace Oqtane.Repository
Icon = Icons.Person, Icon = Icons.Person,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -175,7 +171,7 @@ namespace Oqtane.Repository
// admin pages // admin pages
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "Admin", Parent = "", Path = "admin", Icon = "", IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "Admin", Parent = "", Path = "admin", Icon = "", IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -203,7 +199,6 @@ namespace Oqtane.Repository
Icon = Icons.Home, Icon = Icons.Home,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -231,7 +226,6 @@ namespace Oqtane.Repository
Icon = Icons.Layers, Icon = Icons.Layers,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -259,7 +253,6 @@ namespace Oqtane.Repository
Icon = Icons.People, Icon = Icons.People,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -287,7 +280,6 @@ namespace Oqtane.Repository
Icon = Icons.Person, Icon = Icons.Person,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -315,7 +307,6 @@ namespace Oqtane.Repository
Icon = Icons.LockLocked, Icon = Icons.LockLocked,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -343,7 +334,6 @@ namespace Oqtane.Repository
Icon = Icons.File, Icon = Icons.File,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -371,7 +361,6 @@ namespace Oqtane.Repository
Icon = Icons.Trash, Icon = Icons.Trash,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.AdminRole, true), new Permission(PermissionNames.View, Constants.AdminRole, true),
@ -401,7 +390,6 @@ namespace Oqtane.Repository
Icon = Icons.MagnifyingGlass, Icon = Icons.MagnifyingGlass,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -428,7 +416,6 @@ namespace Oqtane.Repository
Icon = Icons.List, Icon = Icons.List,
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -450,7 +437,7 @@ namespace Oqtane.Repository
}); });
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "Site Management", Parent = "Admin", Path = "admin/sites", Icon = Icons.Globe, IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "Site Management", Parent = "Admin", Path = "admin/sites", Icon = Icons.Globe, IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -472,7 +459,7 @@ namespace Oqtane.Repository
}); });
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "Module Management", Parent = "Admin", Path = "admin/modules", Icon = Icons.Browser, IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "Module Management", Parent = "Admin", Path = "admin/modules", Icon = Icons.Browser, IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -494,7 +481,7 @@ namespace Oqtane.Repository
}); });
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "Theme Management", Parent = "Admin", Path = "admin/themes", Icon = Icons.Brush, IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "Theme Management", Parent = "Admin", Path = "admin/themes", Icon = Icons.Brush, IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -516,7 +503,7 @@ namespace Oqtane.Repository
}); });
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "Scheduled Jobs", Parent = "Admin", Path = "admin/jobs", Icon = Icons.Timer, IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "Scheduled Jobs", Parent = "Admin", Path = "admin/jobs", Icon = Icons.Timer, IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -544,7 +531,6 @@ namespace Oqtane.Repository
Icon = "spreadsheet", Icon = "spreadsheet",
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -572,7 +558,6 @@ namespace Oqtane.Repository
Icon = "medical-cross", Icon = "medical-cross",
IsNavigation = false, IsNavigation = false,
IsPersonalizable = false, IsPersonalizable = false,
EditMode = true,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -594,7 +579,7 @@ namespace Oqtane.Repository
}); });
pageTemplates.Add(new PageTemplate pageTemplates.Add(new PageTemplate
{ {
Name = "System Update", Parent = "Admin", Path = "admin/update", Icon = Icons.Aperture, IsNavigation = false, IsPersonalizable = false, EditMode = true, Name = "System Update", Parent = "Admin", Path = "admin/update", Icon = Icons.Aperture, IsNavigation = false, IsPersonalizable = false,
PagePermissions = new List<Permission> PagePermissions = new List<Permission>
{ {
new Permission(PermissionNames.View, Constants.HostRole, true), new Permission(PermissionNames.View, Constants.HostRole, true),
@ -754,7 +739,6 @@ namespace Oqtane.Repository
Order = 1, Order = 1,
Url = "", Url = "",
IsNavigation = pagetemplate.IsNavigation, IsNavigation = pagetemplate.IsNavigation,
EditMode = pagetemplate.EditMode,
ThemeType = "", ThemeType = "",
LayoutType = "", LayoutType = "",
DefaultContainerType = "", DefaultContainerType = "",

View File

@ -0,0 +1,9 @@
/*
Version 1.0.2.1 migration script
*/
ALTER TABLE [dbo].[Page]
DROP COLUMN EditMode
GO

View File

@ -50,7 +50,7 @@
if (PageState.Action == "Edit") if (PageState.Action == "Edit")
{ {
_id = Int32.Parse(PageState.QueryString["id"]); _id = Int32.Parse(PageState.QueryString["id"]);
[Module] [Module] = await [Module]Service.Get[Module]Async(_id); [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
if ([Module] != null) if ([Module] != null)
{ {
_name = [Module].Name; _name = [Module].Name;
@ -82,7 +82,7 @@
} }
else else
{ {
[Module] [Module] = await [Module]Service.Get[Module]Async(_id); [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
[Module].Name = _name; [Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]); await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]); await logger.LogInformation("[Module] Updated {[Module]}", [Module]);

View File

@ -95,7 +95,7 @@ else
{ {
try try
{ {
await [Module]Service.Delete[Module]Async([Module].[Module]Id); await [Module]Service.Delete[Module]Async([Module].[Module]Id, ModuleState.ModuleId);
await logger.LogInformation("[Module] Deleted {[Module]}", [Module]); await logger.LogInformation("[Module] Deleted {[Module]}", [Module]);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
StateHasChanged(); StateHasChanged();

View File

@ -8,12 +8,12 @@ namespace [Owner].[Module]s.Services
{ {
Task<List<[Module]>> Get[Module]sAsync(int ModuleId); Task<List<[Module]>> Get[Module]sAsync(int ModuleId);
Task<[Module]> Get[Module]Async(int [Module]Id); Task<[Module]> Get[Module]Async(int [Module]Id, int ModuleId);
Task<[Module]> Add[Module]Async([Module] [Module]); Task<[Module]> Add[Module]Async([Module] [Module]);
Task<[Module]> Update[Module]Async([Module] [Module]); Task<[Module]> Update[Module]Async([Module] [Module]);
Task Delete[Module]Async(int [Module]Id); Task Delete[Module]Async(int [Module]Id, int ModuleId);
} }
} }

View File

@ -18,32 +18,44 @@ namespace [Owner].[Module]s.Services
_siteState = siteState; _siteState = siteState;
} }
private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]"); private string Apiurl => CreateApiUrl(_siteState.Alias, "[Module]");
public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId) public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId)
{ {
List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>($"{Apiurl}?moduleid={ModuleId}"); List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>(CreateAuthPolicyUrl($"{Apiurl}?moduleid={ModuleId}", ModuleId));
return [Module]s.OrderBy(item => item.Name).ToList(); return [Module]s.OrderBy(item => item.Name).ToList();
} }
public async Task<[Module]> Get[Module]Async(int [Module]Id) public async Task<[Module]> Get[Module]Async(int [Module]Id, int ModuleId)
{ {
return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}"); return await GetJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
} }
public async Task<[Module]> Add[Module]Async([Module] [Module]) public async Task<[Module]> Add[Module]Async([Module] [Module])
{ {
return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]); return await PostJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}?entityid={[Module].ModuleId}", [Module].ModuleId), [Module]);
} }
public async Task<[Module]> Update[Module]Async([Module] [Module]) public async Task<[Module]> Update[Module]Async([Module] [Module])
{ {
return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]); return await PutJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}/{[Module].[Module]Id}", [Module].ModuleId), [Module]);
} }
public async Task Delete[Module]Async(int [Module]Id) public async Task Delete[Module]Async(int [Module]Id, int ModuleId)
{ {
await DeleteAsync($"{Apiurl}/{[Module]Id}"); await DeleteAsync(CreateAuthPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
}
private string CreateAuthPolicyUrl(string Url, int ModuleId)
{
if (Url.Contains("?"))
{
return Url + "&entityid=" + ModuleId.ToString();
}
else
{
return Url + "?entityid=" + ModuleId.ToString();
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
@ -14,16 +15,22 @@ namespace [Owner].[Module]s.Controllers
{ {
private readonly I[Module]Repository _[Module]s; private readonly I[Module]Repository _[Module]s;
private readonly ILogManager _logger; private readonly ILogManager _logger;
protected int _entityId = -1;
public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger) public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger, IHttpContextAccessor accessor)
{ {
_[Module]s = [Module]s; _[Module]s = [Module]s;
_logger = logger; _logger = logger;
if (accessor.HttpContext.Request.Query.ContainsKey("entityid"))
{
_entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]);
}
} }
// GET: api/<controller>?moduleid=x // GET: api/<controller>?moduleid=x
[HttpGet] [HttpGet]
[Authorize(Roles = Constants.RegisteredRole)] [Authorize(Policy = "ViewModule")]
public IEnumerable<[Module]> Get(string moduleid) public IEnumerable<[Module]> Get(string moduleid)
{ {
return _[Module]s.Get[Module]s(int.Parse(moduleid)); return _[Module]s.Get[Module]s(int.Parse(moduleid));
@ -31,18 +38,23 @@ namespace [Owner].[Module]s.Controllers
// GET api/<controller>/5 // GET api/<controller>/5
[HttpGet("{id}")] [HttpGet("{id}")]
[Authorize(Roles = Constants.RegisteredRole)] [Authorize(Policy = "ViewModule")]
public [Module] Get(int id) public [Module] Get(int id)
{ {
return _[Module]s.Get[Module](id); [Module] [Module] = _[Module]s.Get[Module](id);
if ([Module] != null && [Module].ModuleId != _entityId)
{
[Module] = null;
}
return [Module];
} }
// POST api/<controller> // POST api/<controller>
[HttpPost] [HttpPost]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public [Module] Post([FromBody] [Module] [Module]) public [Module] Post([FromBody] [Module] [Module])
{ {
if (ModelState.IsValid) if (ModelState.IsValid && [Module].ModuleId == _entityId)
{ {
[Module] = _[Module]s.Add[Module]([Module]); [Module] = _[Module]s.Add[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]);
@ -52,10 +64,10 @@ namespace [Owner].[Module]s.Controllers
// PUT api/<controller>/5 // PUT api/<controller>/5
[HttpPut("{id}")] [HttpPut("{id}")]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public [Module] Put(int id, [FromBody] [Module] [Module]) public [Module] Put(int id, [FromBody] [Module] [Module])
{ {
if (ModelState.IsValid) if (ModelState.IsValid && [Module].ModuleId == _entityId)
{ {
[Module] = _[Module]s.Update[Module]([Module]); [Module] = _[Module]s.Update[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]);
@ -65,11 +77,15 @@ namespace [Owner].[Module]s.Controllers
// DELETE api/<controller>/5 // DELETE api/<controller>/5
[HttpDelete("{id}")] [HttpDelete("{id}")]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public void Delete(int id) public void Delete(int id)
{ {
_[Module]s.Delete[Module](id); [Module] [Module] = _[Module]s.Get[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id); if ([Module] != null && [Module].ModuleId == _entityId)
{
_[Module]s.Delete[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id);
}
} }
} }
} }

View File

@ -1 +0,0 @@
This is the location where static resources such as images, style sheets, or scripts for this module will be located. Static assets can be organized in subfolders. When the module package is deployed the assets will be extracted under the web root in a folder that matches the module namespace.

View File

@ -28,8 +28,14 @@
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
public override string Actions => "Add,Edit"; public override string Actions => "Add,Edit";
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
int _id; int _id;
string _name; string _name;
string _createdby; string _createdby;
@ -44,7 +50,7 @@
if (PageState.Action == "Edit") if (PageState.Action == "Edit")
{ {
_id = Int32.Parse(PageState.QueryString["id"]); _id = Int32.Parse(PageState.QueryString["id"]);
[Module] [Module] = await [Module]Service.Get[Module]Async(_id); [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
if ([Module] != null) if ([Module] != null)
{ {
_name = [Module].Name; _name = [Module].Name;
@ -76,7 +82,7 @@
} }
else else
{ {
[Module] [Module] = await [Module]Service.Get[Module]Async(_id); [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
[Module].Name = _name; [Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]); await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]); await logger.LogInformation("[Module] Updated {[Module]}", [Module]);

View File

@ -61,6 +61,11 @@ else
<!-- The content above is for informational purposes only and can be safely removed --> <!-- The content above is for informational purposes only and can be safely removed -->
@code { @code {
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
List<[Module]> _[Module]s; List<[Module]> _[Module]s;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@ -80,7 +85,7 @@ else
{ {
try try
{ {
await [Module]Service.Delete[Module]Async([Module].[Module]Id); await [Module]Service.Delete[Module]Async([Module].[Module]Id, ModuleState.ModuleId);
await logger.LogInformation("[Module] Deleted {[Module]}", [Module]); await logger.LogInformation("[Module] Deleted {[Module]}", [Module]);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
StateHasChanged(); StateHasChanged();

View File

@ -8,12 +8,12 @@ namespace [Owner].[Module]s.Services
{ {
Task<List<[Module]>> Get[Module]sAsync(int ModuleId); Task<List<[Module]>> Get[Module]sAsync(int ModuleId);
Task<[Module]> Get[Module]Async(int [Module]Id); Task<[Module]> Get[Module]Async(int [Module]Id, int ModuleId);
Task<[Module]> Add[Module]Async([Module] [Module]); Task<[Module]> Add[Module]Async([Module] [Module]);
Task<[Module]> Update[Module]Async([Module] [Module]); Task<[Module]> Update[Module]Async([Module] [Module]);
Task Delete[Module]Async(int [Module]Id); Task Delete[Module]Async(int [Module]Id, int ModuleId);
} }
} }

View File

@ -18,32 +18,44 @@ namespace [Owner].[Module]s.Services
_siteState = siteState; _siteState = siteState;
} }
private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]"); private string Apiurl => CreateApiUrl(_siteState.Alias, "[Module]");
public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId) public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId)
{ {
List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>($"{Apiurl}?moduleid={ModuleId}"); List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>(CreateAuthPolicyUrl($"{Apiurl}?moduleid={ModuleId}", ModuleId));
return [Module]s.OrderBy(item => item.Name).ToList(); return [Module]s.OrderBy(item => item.Name).ToList();
} }
public async Task<[Module]> Get[Module]Async(int [Module]Id) public async Task<[Module]> Get[Module]Async(int [Module]Id, int ModuleId)
{ {
return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}"); return await GetJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
} }
public async Task<[Module]> Add[Module]Async([Module] [Module]) public async Task<[Module]> Add[Module]Async([Module] [Module])
{ {
return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]); return await PostJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}?entityid={[Module].ModuleId}", [Module].ModuleId), [Module]);
} }
public async Task<[Module]> Update[Module]Async([Module] [Module]) public async Task<[Module]> Update[Module]Async([Module] [Module])
{ {
return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]); return await PutJsonAsync<[Module]>(CreateAuthPolicyUrl($"{Apiurl}/{[Module].[Module]Id}", [Module].ModuleId), [Module]);
} }
public async Task Delete[Module]Async(int [Module]Id) public async Task Delete[Module]Async(int [Module]Id, int ModuleId)
{ {
await DeleteAsync($"{Apiurl}/{[Module]Id}"); await DeleteAsync(CreateAuthPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
}
private string CreateAuthPolicyUrl(string Url, int ModuleId)
{
if (Url.Contains("?"))
{
return Url + "&entityid=" + ModuleId.ToString();
}
else
{
return Url + "?entityid=" + ModuleId.ToString();
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.Enums; using Oqtane.Enums;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
@ -14,16 +15,22 @@ namespace [Owner].[Module]s.Controllers
{ {
private readonly I[Module]Repository _[Module]s; private readonly I[Module]Repository _[Module]s;
private readonly ILogManager _logger; private readonly ILogManager _logger;
protected int _entityId = -1;
public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger) public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger, IHttpContextAccessor accessor)
{ {
_[Module]s = [Module]s; _[Module]s = [Module]s;
_logger = logger; _logger = logger;
if (accessor.HttpContext.Request.Query.ContainsKey("entityid"))
{
_entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]);
}
} }
// GET: api/<controller>?moduleid=x // GET: api/<controller>?moduleid=x
[HttpGet] [HttpGet]
[Authorize(Roles = Constants.RegisteredRole)] [Authorize(Policy = "ViewModule")]
public IEnumerable<[Module]> Get(string moduleid) public IEnumerable<[Module]> Get(string moduleid)
{ {
return _[Module]s.Get[Module]s(int.Parse(moduleid)); return _[Module]s.Get[Module]s(int.Parse(moduleid));
@ -31,18 +38,23 @@ namespace [Owner].[Module]s.Controllers
// GET api/<controller>/5 // GET api/<controller>/5
[HttpGet("{id}")] [HttpGet("{id}")]
[Authorize(Roles = Constants.RegisteredRole)] [Authorize(Policy = "ViewModule")]
public [Module] Get(int id) public [Module] Get(int id)
{ {
return _[Module]s.Get[Module](id); [Module] [Module] = _[Module]s.Get[Module](id);
if ([Module] != null && [Module].ModuleId != _entityId)
{
[Module] = null;
}
return [Module];
} }
// POST api/<controller> // POST api/<controller>
[HttpPost] [HttpPost]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public [Module] Post([FromBody] [Module] [Module]) public [Module] Post([FromBody] [Module] [Module])
{ {
if (ModelState.IsValid) if (ModelState.IsValid && [Module].ModuleId == _entityId)
{ {
[Module] = _[Module]s.Add[Module]([Module]); [Module] = _[Module]s.Add[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]);
@ -52,10 +64,10 @@ namespace [Owner].[Module]s.Controllers
// PUT api/<controller>/5 // PUT api/<controller>/5
[HttpPut("{id}")] [HttpPut("{id}")]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public [Module] Put(int id, [FromBody] [Module] [Module]) public [Module] Put(int id, [FromBody] [Module] [Module])
{ {
if (ModelState.IsValid) if (ModelState.IsValid && [Module].ModuleId == _entityId)
{ {
[Module] = _[Module]s.Update[Module]([Module]); [Module] = _[Module]s.Update[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]);
@ -65,11 +77,15 @@ namespace [Owner].[Module]s.Controllers
// DELETE api/<controller>/5 // DELETE api/<controller>/5
[HttpDelete("{id}")] [HttpDelete("{id}")]
[Authorize(Roles = Constants.AdminRole)] [Authorize(Policy = "EditModule")]
public void Delete(int id) public void Delete(int id)
{ {
_[Module]s.Delete[Module](id); [Module] [Module] = _[Module]s.Get[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id); if ([Module] != null && [Module].ModuleId == _entityId)
{
_[Module]s.Delete[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id);
}
} }
} }
} }

View File

@ -1 +0,0 @@
This is the location where static resources such as images, style sheets, or scripts for this module will be located. Static assets can be organized in subfolders. When the module package is deployed the assets will be extracted under the web root in a folder that matches the module namespace.

View File

@ -20,6 +20,7 @@ namespace Oqtane.Models
ServerManagerType = ""; ServerManagerType = "";
ControlTypeRoutes = ""; ControlTypeRoutes = "";
ReleaseVersions = ""; ReleaseVersions = "";
Runtimes = "";
Template = ""; Template = "";
} }
@ -45,6 +46,8 @@ namespace Oqtane.Models
[NotMapped] [NotMapped]
public string License { get; set; } public string License { get; set; }
[NotMapped] [NotMapped]
public string Runtimes { get; set; }
[NotMapped]
public string Dependencies { get; set; } public string Dependencies { get; set; }
[NotMapped] [NotMapped]
public string PermissionNames { get; set; } public string PermissionNames { get; set; }

View File

@ -19,7 +19,6 @@ namespace Oqtane.Models
public string DefaultContainerType { get; set; } public string DefaultContainerType { get; set; }
public string Icon { get; set; } public string Icon { get; set; }
public bool IsNavigation { get; set; } public bool IsNavigation { get; set; }
public bool EditMode { get; set; }
public int? UserId { get; set; } public int? UserId { get; set; }
public bool IsPersonalizable { get; set; } public bool IsPersonalizable { get; set; }
@ -41,5 +40,9 @@ namespace Oqtane.Models
public int Level { get; set; } public int Level { get; set; }
[NotMapped] [NotMapped]
public bool HasChildren { get; set; } public bool HasChildren { get; set; }
[Obsolete("This property is obsolete", false)]
[NotMapped]
public bool EditMode { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Oqtane.Models namespace Oqtane.Models
{ {
@ -16,9 +17,11 @@ namespace Oqtane.Models
public string Icon { get; set; } public string Icon { get; set; }
public bool IsNavigation { get; set; } public bool IsNavigation { get; set; }
public bool IsPersonalizable { get; set; } public bool IsPersonalizable { get; set; }
public bool EditMode { get; set; }
public string PagePermissions { get; set; } public string PagePermissions { get; set; }
public List<PageTemplateModule> PageTemplateModules { get; set; } public List<PageTemplateModule> PageTemplateModules { get; set; }
[Obsolete("This property is obsolete", false)]
public bool EditMode { get; set; }
} }
public class PageTemplateModule public class PageTemplateModule