Initial commit

This commit is contained in:
oqtane
2019-05-04 20:32:08 -04:00
committed by Shaun Walker
parent 2f232eea7e
commit d71de1c21f
177 changed files with 8536 additions and 0 deletions

View File

@ -0,0 +1,17 @@
namespace Oqtane.Shared
{
public class Constants
{
public const string DefaultPage = "Oqtane.Client.Shared.Skin, Oqtane.Client";
public const string DefaultContainer = "Oqtane.Client.Shared.Container, Oqtane.Client";
public const string DefaultAdminContainer = "Oqtane.Client.Skins.AdminContainer, Oqtane.Client";
public const string DefaultSettingsControl = "Oqtane.Client.Modules.Admin.ModuleSettings.Index, Oqtane.Client";
public const string PageManagementModule = "Oqtane.Client.Modules.Admin.Pages, Oqtane.Client";
public const string DefaultControl = "Index";
public const string AdminPane = "Admin";
public const string AllUsersRole = "All Users";
public const string AdminRole = "Administrators";
}
}

View File

@ -0,0 +1,45 @@
@using Oqtane.Models
@using Oqtane.Shared
<CascadingValue Value="@ModuleState">
@DynamicComponent
</CascadingValue>
@functions {
[CascadingParameter]
protected PageState PageState { get; set; }
[Parameter]
private Module ModuleState { get; set; }
string container;
RenderFragment DynamicComponent { get; set; }
protected override void OnInit()
{
DynamicComponent = builder =>
{
Type containerType = Type.GetType(container);
if (containerType != null)
{
builder.OpenComponent(0, containerType);
builder.CloseComponent();
}
else
{
// container does not exist with type specified
}
};
}
protected override Task OnParametersSetAsync()
{
container = ModuleState.ContainerType;
if (PageState.ModuleId != -1 && PageState.Control != "")
{
container = Constants.DefaultAdminContainer;
}
return Task.CompletedTask;
}
}

View File

@ -0,0 +1,58 @@
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;
namespace Oqtane.Shared
{
public class Interop
{
private readonly IJSRuntime jsRuntime;
public Interop(IJSRuntime jsRuntime)
{
this.jsRuntime = jsRuntime;
}
public Task<string> SetCookie(string name, string value, int days)
{
try
{
return jsRuntime.InvokeAsync<string>(
"interop.setCookie",
name, value, days);
}
catch
{
return Task.FromResult(string.Empty);
}
}
public Task<string> GetCookie(string name)
{
try
{
return jsRuntime.InvokeAsync<string>(
"interop.getCookie",
name);
}
catch
{
return Task.FromResult(string.Empty);
}
}
public Task<string> AddCSS(string filename)
{
try
{
return jsRuntime.InvokeAsync<string>(
"interop.addCSS",
filename);
}
catch
{
return Task.FromResult(string.Empty);
}
}
}
}

View File

@ -0,0 +1,36 @@
@using Oqtane.Models
@using Oqtane.Shared
@DynamicComponent
@functions {
[CascadingParameter]
protected PageState PageState { get; set; }
[CascadingParameter]
private Module ModuleState { get; set; }
RenderFragment DynamicComponent { get; set; }
protected override void OnInit()
{
DynamicComponent = builder =>
{
string typename = ModuleState.ModuleType;
if (PageState.Control == "Settings") // module settings are a core component
{
typename = Constants.DefaultSettingsControl;
}
Type moduleType = Type.GetType(typename);
if (moduleType != null)
{
builder.OpenComponent(0, moduleType);
builder.CloseComponent();
}
else
{
// module control does not exist with typename specified
}
};
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using Oqtane.Models;
namespace Oqtane.Shared
{
public class PageState
{
public string Alias { get; set; }
public Site Site { get; set; }
public List<Page> Pages { get; set; }
public Page Page { get; set; }
public User User { get; set; }
public List<Module> Modules { get; set; }
public Uri Uri { get; set; }
public Dictionary<string, string> QueryString { get; set; }
public int ModuleId { get; set; }
public string Control { get; set; }
public string Mode { get; set; }
}
}

View File

@ -0,0 +1,127 @@
@using System
@using Oqtane.Services
@using Oqtane.Modules
@using Oqtane.Models
@using Oqtane.Shared
@using System.Linq
@inject IUserService UserService
@inject IModuleService ModuleService
@inject IModuleDefinitionService ModuleDefinitionService
<div class="@paneadminborder">
@((MarkupString)panetitle)
@DynamicComponent
</div>
@functions {
[CascadingParameter]
protected PageState PageState { get; set; }
[Parameter]
private string Name { get; set; }
RenderFragment DynamicComponent { get; set; }
string paneadminborder = "";
string panetitle = "";
protected override void OnInit()
{
if (UserService.IsAuthorized(PageState.User, PageState.Page.EditPermissions) && Name != Constants.AdminPane)
{
paneadminborder = "pane-admin-border";
panetitle = "<div class=\"pane-admin-title\">" + Name + " Pane</div>";
}
DynamicComponent = builder =>
{
if (PageState.ModuleId != -1 && PageState.Control != "")
{
if (Name == Constants.AdminPane)
{
Module module = PageState.Modules.Where(item => item.ModuleId == PageState.ModuleId).FirstOrDefault();
if (module != null)
{
string typename = module.ModuleType;
if (PageState.Control == "Settings")
{
typename = Constants.DefaultSettingsControl;
}
Type moduleType = Type.GetType(typename);
if (moduleType != null)
{
var moduleobject = Activator.CreateInstance(moduleType);
// verify security access level for this module control
SecurityAccessLevelEnum SecurityAccessLevel = (SecurityAccessLevelEnum)moduleType.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
bool authorized = false;
switch (SecurityAccessLevel)
{
case SecurityAccessLevelEnum.Anonymous:
authorized = true;
break;
case SecurityAccessLevelEnum.View:
authorized = UserService.IsAuthorized(PageState.User, module.ViewPermissions);
break;
case SecurityAccessLevelEnum.Edit:
authorized = UserService.IsAuthorized(PageState.User, module.EditPermissions);
break;
case SecurityAccessLevelEnum.Admin:
authorized = UserService.IsAuthorized(PageState.User, Constants.AdminRole);
break;
case SecurityAccessLevelEnum.Host:
authorized = PageState.User.IsSuperUser;
break;
}
if (authorized)
{
// get module control title
string title = (string)moduleType.GetProperty("Title").GetValue(moduleobject);
if (title != "")
{
module.Title = title;
}
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer));
builder.AddAttribute(1, "ModuleState", module);
builder.CloseComponent();
}
}
else
{
// module control does not exist with name specified
}
}
}
}
else
{
if (PageState.ModuleId != -1)
{
Module module = PageState.Modules.Where(item => item.ModuleId == PageState.ModuleId).FirstOrDefault();
if (module != null && module.Pane == Name)
{
// check if user is authorized to view module
if (UserService.IsAuthorized(PageState.User, module.ViewPermissions))
{
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer));
builder.AddAttribute(1, "ModuleState", module);
builder.CloseComponent();
}
}
}
else
{
foreach (Module module in PageState.Modules.Where(item => item.Pane == Name).OrderBy(x => x.Order).ToArray())
{
// check if user is authorized to view module
if (UserService.IsAuthorized(PageState.User, module.ViewPermissions))
{
builder.OpenComponent(0, Type.GetType(Constants.DefaultContainer));
builder.AddAttribute(1, "ModuleState", module);
builder.CloseComponent();
}
}
}
};
};
}
}

View File

@ -0,0 +1,28 @@
@using System
@using Oqtane.Shared
@DynamicComponent
@functions {
[CascadingParameter]
protected PageState PageState { get; set; }
RenderFragment DynamicComponent { get; set; }
protected override void OnInit()
{
DynamicComponent = builder =>
{
Type layoutType = Type.GetType(PageState.Page.LayoutType);
if (layoutType != null)
{
builder.OpenComponent(0, layoutType);
builder.CloseComponent();
}
else
{
// layout does not exist with type specified
}
};
}
}

View File

@ -0,0 +1,312 @@
@using System
@using Oqtane.Services
@using Oqtane.Models
@using System.Linq
@using System.Collections.Generic
@using Oqtane.Shared
@using Microsoft.JSInterop
@inject IUriHelper UriHelper
@inject IJSRuntime jsRuntime
@inject ITenantService TenantService
@inject ISiteService SiteService
@inject IPageService PageService
@inject IUserService UserService
@inject IModuleService ModuleService
@inject IModuleDefinitionService ModuleDefinitionService
@inject ISkinService SkinService
@DynamicComponent
@functions {
[CascadingParameter] PageState PageState { get; set; }
[Parameter] Action<PageState> OnStateChange { get; set; }
RenderFragment DynamicComponent { get; set; }
private string _absoluteUri;
string alias;
Site site;
List<Page> pages;
Page page;
User user;
List<Module> modules;
PageState pagestate;
protected override void OnInit()
{
_absoluteUri = UriHelper.GetAbsoluteUri();
UriHelper.OnLocationChanged += OnLocationChanged;
DynamicComponent = builder =>
{
if (pagestate != null)
{
builder.OpenComponent(0, Type.GetType(Constants.DefaultPage));
builder.CloseComponent();
}
};
}
public void Dispose()
{
UriHelper.OnLocationChanged -= OnLocationChanged;
}
protected override async Task OnParametersSetAsync()
{
if (PageState == null)
{
await Refresh();
}
}
private async Task Refresh()
{
List<ModuleDefinition> moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync();
List<Models.Skin> skins = await SkinService.GetSkinsAsync();
bool reload = false;
if (PageState == null)
{
Tenant tenant = await TenantService.GetTenantAsync();
site = await SiteService.GetSiteAsync(tenant.SiteId);
alias = Utilities.GetAlias(_absoluteUri);
}
else
{
site = PageState.Site;
alias = PageState.Alias;
}
if (Utilities.GetAlias(_absoluteUri) != alias)
{
Tenant tenant = await TenantService.GetTenantAsync();
site = await SiteService.GetSiteAsync(tenant.SiteId);
alias = Utilities.GetAlias(_absoluteUri);
reload = true;
}
if (site != null)
{
var interop = new Interop(jsRuntime);
string userid = await interop.GetCookie("user");
if (PageState == null || reload == true)
{
if (!string.IsNullOrEmpty(userid))
{
user = await UserService.GetUserAsync(int.Parse(userid));
}
}
else
{
user = PageState.User;
}
if (!string.IsNullOrEmpty(userid))
{
if (user != null && user.UserId != int.Parse(userid))
{
user = await UserService.GetUserAsync(int.Parse(userid));
}
// this is a hack for server-side Blazor where JSInterop is not working OnInit() which means the userid is not being retrieved from the cookie on the initial render and is not being loaded into PageState
if (user == null)
{
user = await UserService.GetUserAsync(int.Parse(userid));
}
}
else
{
user = null;
}
string path = new Uri(_absoluteUri).PathAndQuery.Substring(1);
if (alias != "")
{
path = path.Replace(alias, "");
}
Dictionary<string, string> querystring = ParseQueryString(path);
if (querystring.ContainsKey("reload"))
{
reload = true;
}
if (PageState == null || reload == true)
{
pages = await PageService.GetPagesAsync(site.SiteId);
}
else
{
pages = PageState.Pages;
}
if (path.IndexOf("?") != -1)
{
path = path.Substring(0, path.IndexOf("?"));
}
if (PageState == null || reload == true)
{
page = pages.Where(item => item.Path == path).FirstOrDefault();
}
else
{
page = PageState.Page;
}
if (page.Path != path)
{
page = pages.Where(item => item.Path == path).FirstOrDefault();
reload = true;
}
if (page != null)
{
// check if user is authorized to view page
if (UserService.IsAuthorized(user, page.ViewPermissions))
{
pagestate = new PageState();
pagestate.Alias = alias;
pagestate.Site = site;
pagestate.Pages = pages;
pagestate.Page = page;
pagestate.User = user;
pagestate.Uri = new Uri(_absoluteUri, UriKind.Absolute);
pagestate.QueryString = querystring;
pagestate.ModuleId = -1;
pagestate.Control = "";
pagestate.Mode = "client";
if (querystring.ContainsKey("mid"))
{
pagestate.ModuleId = int.Parse(querystring["mid"]);
}
if (querystring.ContainsKey("ctl"))
{
pagestate.Control = querystring["ctl"];
}
if (PageState != null && (PageState.ModuleId != pagestate.ModuleId || PageState.Control != pagestate.Control))
{
reload = true;
}
if (PageState == null || reload == true)
{
modules = await ModuleService.GetModulesAsync(page.PageId);
modules = ProcessModules(modules, moduledefinitions, pagestate.Control, page.Panes);
}
else
{
modules = PageState.Modules;
}
pagestate.Modules = modules;
OnStateChange?.Invoke(pagestate);
}
else
{
// user is not authorized to view page
}
}
else
{
// page does not exist
}
}
else
{
// site does not exist
}
StateHasChanged();
}
private async void OnLocationChanged(object sender, string AbsoluteUri)
{
_absoluteUri = AbsoluteUri;
await LocationChanged();
}
public async Task LocationChanged()
{
await Refresh();
}
private Dictionary<string, string> ParseQueryString(string path)
{
Dictionary<string, string> querystring = new Dictionary<string, string>();
if (path.IndexOf("?") != -1)
{
foreach (string kvp in path.Substring(path.IndexOf("?") + 1).Split('&'))
{
if (kvp != "")
{
if (kvp.Contains("="))
{
string[] pair = kvp.Split('=');
querystring.Add(pair[0], pair[1]);
}
else
{
querystring.Add(kvp, "true"); // default querystring when no value is provided
}
}
}
}
return querystring;
}
private List<Module> ProcessModules(List<Module> modules, List<ModuleDefinition> moduledefinitions, string control, string panes)
{
ModuleDefinition moduledefinition;
if (control == "")
{
control = Constants.DefaultControl;
}
Dictionary<string, int> paneindex = new Dictionary<string, int>();
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 = moduledefinition.ControlTypeTemplate;
if (moduledefinition.ControlTypeRoutes != "")
{
foreach (string route in moduledefinition.ControlTypeRoutes.Split(';'))
{
if (route.StartsWith(control + "="))
{
typename = route.Replace(control + "=", "");
}
}
}
module.ModuleType = typename.Replace("{Control}", control);
}
// ensure module's pane exists in current page and if not, assign it to the Admin pane
if (!panes.Contains(module.Pane))
{
module.Pane = Constants.AdminPane;
}
// calculate module position within pane
if (paneindex.ContainsKey(module.Pane))
{
paneindex[module.Pane] += 1;
}
else
{
paneindex.Add(module.Pane, 0);
}
module.PaneModuleIndex = paneindex[module.Pane];
}
foreach (Module module in modules)
{
module.PaneModuleCount = paneindex[module.Pane] + 1;
}
return modules;
}
}

View File

@ -0,0 +1,26 @@
@using Oqtane.Shared
@DynamicComponent
@functions {
[CascadingParameter] PageState PageState { get; set; }
RenderFragment DynamicComponent { get; set; }
protected override void OnInit()
{
DynamicComponent = builder =>
{
Type skinType = Type.GetType(PageState.Page.SkinType);
if (skinType != null)
{
builder.OpenComponent(0, skinType);
builder.CloseComponent();
}
else
{
// skin does not exist with type specified
}
};
}
}

View File

@ -0,0 +1,28 @@
using System;
namespace Oqtane.Shared
{
public class Utilities
{
public static string GetAlias(string absoluteUri)
{
string alias = "";
Uri uri = new Uri(absoluteUri);
if (uri.AbsolutePath.StartsWith("/~"))
{
alias = uri.Segments[1];
}
return alias;
}
public static string GetTypeNameClass(string typename)
{
if (typename.Contains(","))
{
typename = typename.Substring(0, typename.IndexOf(","));
}
string[] fragments = typename.Split('.');
return fragments[fragments.Length - 1];
}
}
}