Refactor host user security model, support static assets in modules and themes, module definition permissions and categories, paging control, remove SiteUsers, move seed data from script to site template for installation

This commit is contained in:
Shaun Walker
2019-09-19 16:33:48 -04:00
parent 35b9b9e89b
commit 83a212e7e3
61 changed files with 1000 additions and 979 deletions

View File

@ -9,20 +9,20 @@
@inject IPageService PageService
@inject IUserService UserService
<ul class="list-group">
<div class="row">
@foreach (var p in pages)
{
if (UserSecurity.IsAuthorized(PageState.User, "View", p.Permissions))
{
string url = NavigateUrl(p.Path);
<li class="list-group-item">
<div class="col-md-2 mx-auto text-center">
<NavLink class="nav-link" href="@url" Match="NavLinkMatch.All">
<span class="oi @p.Icon" aria-hidden="true"></span> @p.Name
<h2><span class="oi oi-@p.Icon" aria-hidden="true"></span></h2>@p.Name
</NavLink>
</li>
</div>
}
}
</ul>
</div>
<br />
<br />
@ -31,7 +31,7 @@
protected override void OnInitialized()
{
// display list of pages which are children of current page
pages = PageState.Pages.Where(item => item.ParentId == PageState.Page.PageId).ToList();
// display list of pages which are children of current page
pages = PageState.Pages.Where(item => item.ParentId == PageState.Page.PageId).ToList();
}
}
}

View File

@ -0,0 +1,91 @@
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Oqtane.Modules.Controls
@using Oqtane.Models
@using Oqtane.Services
@using Oqtane.Modules
@using Oqtane.Shared
@using Oqtane.Security
@namespace Oqtane.Modules.Admin.ModuleDefinitions
@inherits ModuleBase
@inject IModuleDefinitionService ModuleDefinitionService
@inject NavigationManager NavigationManager
<ModuleMessage Message="@message" />
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Permissions: </label>
</td>
<td>
<PermissionGrid EntityName="ModuleDefinition" PermissionNames="Utilize" Permissions="@permissions" @ref="permissiongrid" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
string message = "";
int ModuleDefinitionId;
string name;
string permissions;
string createdby;
DateTime createdon;
string modifiedby;
DateTime modifiedon;
PermissionGrid permissiongrid;
protected override void OnInitialized()
{
try
{
ModuleDefinitionId = Int32.Parse(PageState.QueryString["id"]);
ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault();
if (moduledefinition != null)
{
name = moduledefinition.Name;
permissions = moduledefinition.Permissions;
createdby = moduledefinition.CreatedBy;
createdon = moduledefinition.CreatedOn;
modifiedby = moduledefinition.ModifiedBy;
modifiedon = moduledefinition.ModifiedOn;
}
}
catch (Exception ex)
{
message = ex.Message;
}
}
private async Task SaveModuleDefinition()
{
try
{
ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault();
moduledefinition.Permissions = permissiongrid.GetPermissions();
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
}
catch (Exception ex)
{
message = ex.Message;
}
}
}

View File

@ -17,15 +17,19 @@ else
<table class="table table-borderless">
<thead>
<tr>
<th>&nbsp;</th>
<th>Name</th>
<th>Version</th>
</tr>
</thead>
<tbody>
@foreach (var moduledefinition in moduledefinitions)
{
<tr>
<td>@moduledefinition.Name</td>
</tr>
<tr>
<td><ActionLink Action="Edit" Parameters="@($"id=" + moduledefinition.ModuleDefinitionId.ToString())" /></td>
<td>@moduledefinition.Name</td>
<td>@moduledefinition.Version</td>
</tr>
}
</tbody>
</table>
@ -38,6 +42,6 @@ else
protected override async Task OnInitializedAsync()
{
moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync();
moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
}
}

View File

@ -44,7 +44,7 @@
<label for="Name" class="control-label">Permissions: </label>
</td>
<td>
<PermissionGrid EntityName="Module" Permissions="@permissions" @ref="permissiongrid" />
<PermissionGrid EntityName="Module" PermissionNames="@permissionnames" Permissions="@permissions" @ref="permissiongrid" />
</td>
</tr>
<tr>
@ -76,6 +76,7 @@
Dictionary<string, string> containers = new Dictionary<string, string>();
string title;
string containertype;
string permissionnames = "";
string permissions;
string pageid;
@ -90,6 +91,7 @@
containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync());
containertype = ModuleState.ContainerType;
permissions = ModuleState.Permissions;
permissionnames = PageState.ModuleDefinitions.Find(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).PermissionNames;
pageid = ModuleState.PageId.ToString();
DynamicComponent = builder =>

View File

@ -37,7 +37,7 @@
</td>
<td>
<select class="form-control" @onchange="(e => ParentChanged(e))">
<option value="">&lt;Site Root&gt;</option>
<option value="-1">&lt;Site Root&gt;</option>
@foreach (Page page in pages)
{
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
@ -191,7 +191,7 @@
try
{
parentid = (string)e.Value;
if (string.IsNullOrEmpty(parentid))
if (parentid == "-1")
{
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
}

View File

@ -37,7 +37,7 @@
</td>
<td>
<select class="form-control" @onchange="(e => ParentChanged(e))">
<option value="">&lt;Site Root&gt;</option>
<option value="-1">&lt;Site Root&gt;</option>
@foreach (Page page in pages)
{
if (page.PageId.ToString() == parentid)
@ -237,7 +237,7 @@
try
{
parentid = (string)e.Value;
if (string.IsNullOrEmpty(parentid))
if (parentid == "-1")
{
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
}

View File

@ -9,27 +9,20 @@
@if (PageState.Pages != null)
{
<ActionLink Action="Add" Text="Add Page" />
<table class="table table-borderless">
<thead>
<tr>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>Name</th>
</tr>
</thead>
<tbody>
@foreach (Page page in PageState.Pages)
{
<tr>
<td><ActionLink Action="Edit" Parameters="@($"id=" + page.PageId.ToString())" /></td>
<td><ActionLink Action="Delete" Parameters="@($"id=" + page.PageId.ToString())" Class="btn btn-danger" /></td>
<td>@(new string('-', page.Level * 2))@(page.Name)</td>
</tr>
}
</tbody>
</table>
<ActionLink Action="Add" Text="Add Page" Style="float: right; margin: 10px;" />
<Pager Items="@PageState.Pages" DisplayPages="3" PageSize="3">
<Header>
<th>Name</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</Header>
<Row>
<td>@(new string('-', context.Level * 2))@(context.Name)</td>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" /></td>
<td><ActionLink Action="Delete" Parameters="@($"id=" +context.PageId.ToString())" Class="btn btn-danger" /></td>
</Row>
</Pager>
}
@code {

View File

@ -34,7 +34,6 @@
user.Username = Email;
user.DisplayName = Email;
user.Email = Email;
user.IsHost = false;
user.Password = Password;
await UserService.AddUserAsync(user);
NavigationManager.NavigateTo("");

View File

@ -11,7 +11,7 @@
@inject ITenantService TenantService
@inject IAliasService AliasService
@inject ISiteService SiteService
@inject IPageService PageService
@inject IThemeService ThemeService
@if (tenants == null)
{
@ -58,6 +58,34 @@ else
<input class="form-control" @bind="@logo" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Theme: </label>
</td>
<td>
<select class="form-control" @bind="@themetype">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in themes)
{
<option value="@item.Key">@item.Value</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Default Layout: </label>
</td>
<td>
<select class="form-control" @bind="@layouttype">
<option value="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveSite">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@ -66,15 +94,23 @@ else
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
Dictionary<string, string> themes = new Dictionary<string, string>();
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
List<Tenant> tenants;
string tenantid = "";
string name = "";
string url = "";
string logo = "";
string themetype;
string layouttype;
protected override async Task OnInitializedAsync()
{
tenants = await TenantService.GetTenantsAsync();
url = PageState.Alias.Name;
themes = ThemeService.GetThemeTypes(PageState.Themes);
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes);
}
private async Task SaveSite()
@ -82,9 +118,9 @@ else
Site site = new Site();
site.Name = name;
site.Logo = (logo == null ? "" : logo);
await SiteService.AddSiteAsync(site);
List<Site> sites = await SiteService.GetSitesAsync();
site = sites.Where(item => item.Name == name).FirstOrDefault();
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site = await SiteService.AddSiteAsync(site);
Alias alias = new Alias();
alias.Name = url;
@ -92,28 +128,6 @@ else
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
// need to add a home page and admin pages
Page p = new Page();
p.SiteId = site.SiteId;
p.ParentId = null;
p.Name = "Home";
p.Path = "";
p.Order = 1;
p.IsNavigation = true;
p.ThemeType = PageState.Site.DefaultThemeType;
p.LayoutType = "";
p.Icon = "";
Type type = Type.GetType(p.ThemeType);
System.Reflection.PropertyInfo property = type.GetProperty("Panes");
p.Panes = (string)property.GetValue(Activator.CreateInstance(type), null);
List<PermissionString> permissionstrings = new List<PermissionString>();
permissionstrings.Add(new PermissionString { PermissionName = "View", Permissions = Constants.AllUsersRole });
permissionstrings.Add(new PermissionString { PermissionName = "Edit", Permissions = Constants.AdminRole });
p.Permissions = UserSecurity.SetPermissionStrings(permissionstrings);
await PageService.AddPageAsync(p);
NavigationManager.NavigateTo(url, true);
}
}

View File

@ -0,0 +1,62 @@
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Oqtane.Models
@using Oqtane.Services
@using Oqtane.Modules
@using Oqtane.Shared
@using Oqtane.Security
@namespace Oqtane.Modules.Admin.Tenants
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject ITenantService TenantService
@inject IAliasService AliasService
@inject ISiteService SiteService
@inject IPageService PageService
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Connection String: </label>
</td>
<td>
<input class="form-control" @bind="@connectionstring" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Schema: </label>
</td>
<td>
<input class="form-control" @bind="@schema" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveTenant">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
string name = "";
string connectionstring = "";
string schema = "";
private async Task SaveTenant()
{
Tenant tenant = new Tenant();
tenant.Name = name;
tenant.DBConnectionString = connectionstring;
tenant.DBSchema = schema;
await TenantService.AddTenantAsync(tenant);
NavigationManager.NavigateTo(NavigateUrl());
}
}

View File

@ -0,0 +1,43 @@
@using Microsoft.AspNetCore.Components.Web
@using Oqtane.Services
@using Oqtane.Models
@using Oqtane.Modules
@using Oqtane.Modules.Controls
@namespace Oqtane.Modules.Admin.Tenants
@inherits ModuleBase
@inject ITenantService TenantService
@if (Tenants == null)
{
<p><em>Loading...</em></p>
}
else
{
<ActionLink Action="Add" Text="Add Tenant" />
<table class="table table-borderless">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
@foreach (var Tenant in Tenants)
{
<tr>
<td>@Tenant.Name</td>
</tr>
}
</tbody>
</table>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
List<Tenant> Tenants;
protected override async Task OnInitializedAsync()
{
Tenants = await TenantService.GetTenantsAsync();
}
}

View File

@ -3,12 +3,12 @@
@using Oqtane.Models
@using Oqtane.Modules
@using Oqtane.Modules.Controls
@using Oqtane.Shared
@namespace Oqtane.Modules.Admin.Users
@inherits ModuleBase
@inject IUserRoleService UserRoleService
@inject IUserService UserService
@if (Users == null)
@if (userroles == null)
{
<p><em>Loading...</em></p>
}
@ -21,10 +21,10 @@ else
</tr>
</thead>
<tbody>
@foreach (var User in Users)
@foreach (UserRole userrole in userroles)
{
<tr>
<td>@User.Username</td>
<td>@userrole.User.Username</td>
</tr>
}
</tbody>
@ -34,10 +34,11 @@ else
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
List<User> Users;
List<UserRole> userroles;
protected override async Task OnInitializedAsync()
{
Users = await UserService.GetUsersAsync(PageState.Site.SiteId);
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
}
}