Merge pull request #1895 from sbwalker/dev
added support for default alias specification, alias auto registration, alias redirect, alias line break delimiters
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Site
|
@namespace Oqtane.Modules.Admin.Site
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject ITenantService TenantService
|
@inject ITenantService TenantService
|
||||||
@ -21,31 +22,6 @@
|
|||||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="alias" HelpText="The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas." ResourceKey="Aliases">Aliases: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
|
||||||
{
|
|
||||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" required></textarea>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" readonly></textarea>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -94,9 +70,17 @@
|
|||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Deleted? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
|
||||||
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -176,6 +160,27 @@
|
|||||||
</Section>
|
</Section>
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
|
<Section Name="Aliases" Heading="Aliases" ResourceKey="Aliases">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="alias" HelpText="The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas." ResourceKey="Aliases">Aliases: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" required></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="defaultalias" HelpText="The default alias for the site. Requests for non-default aliases will be redirected to the default alias." ResourceKey="DefaultAlias">Default Alias: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="defaultalias" class="form-select" @bind="@_defaultalias" required>
|
||||||
|
@foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
<option value="@name">@name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
|
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -238,7 +243,8 @@
|
|||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private List<Alias> _aliasList;
|
private List<Alias> _aliases;
|
||||||
|
private string _defaultalias = string.Empty;
|
||||||
private string _urls = string.Empty;
|
private string _urls = string.Empty;
|
||||||
private string _runtime = "";
|
private string _runtime = "";
|
||||||
private string _prerender = "";
|
private string _prerender = "";
|
||||||
@ -288,13 +294,7 @@
|
|||||||
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
_aliasList = await AliasService.GetAliasesAsync();
|
await GetAliases();
|
||||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
|
||||||
{
|
|
||||||
_urls += alias.Name + ",";
|
|
||||||
}
|
|
||||||
_urls = _urls.Substring(0, _urls.Length - 1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site.LogoFileId != null)
|
if (site.LogoFileId != null)
|
||||||
@ -395,14 +395,16 @@
|
|||||||
{
|
{
|
||||||
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-")
|
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-")
|
||||||
{
|
{
|
||||||
|
_urls = Regex.Replace(_urls, @"\r\n?|\n", ","); // convert line breaks to commas
|
||||||
var unique = true;
|
var unique = true;
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray())
|
||||||
{
|
{
|
||||||
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
|
var alias = _aliases.Where(item => item.Name == name).FirstOrDefault();
|
||||||
|
if (alias != null && unique)
|
||||||
{
|
{
|
||||||
unique = false;
|
unique = (alias.TenantId == PageState.Site.TenantId && alias.SiteId == PageState.Site.SiteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,27 +488,40 @@
|
|||||||
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
.Select(sValue => sValue.Trim()).ToArray();
|
||||||
|
foreach (Alias alias in _aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
||||||
{
|
{
|
||||||
if (!names.Contains(alias.Name))
|
if (!names.Contains(alias.Name))
|
||||||
{
|
{
|
||||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!names.Contains(_defaultalias)) { _defaultalias = names[0]; }
|
||||||
|
|
||||||
foreach (string name in names)
|
foreach (string name in names)
|
||||||
{
|
{
|
||||||
if (!_aliasList.Exists(item => item.Name == name))
|
var alias = _aliases.Find(item => item.Name == name);
|
||||||
|
if (alias == null)
|
||||||
{
|
{
|
||||||
Alias alias = new Alias();
|
alias = new Alias();
|
||||||
alias.Name = name;
|
alias.Name = name;
|
||||||
alias.TenantId = site.TenantId;
|
alias.TenantId = site.TenantId;
|
||||||
alias.SiteId = site.SiteId;
|
alias.SiteId = site.SiteId;
|
||||||
|
alias.IsDefault = (name == _defaultalias);
|
||||||
await AliasService.AddAliasAsync(alias);
|
await AliasService.AddAliasAsync(alias);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alias.IsDefault != (alias.Name == _defaultalias))
|
||||||
|
{
|
||||||
|
alias.IsDefault = (name == _defaultalias);
|
||||||
|
await AliasService.UpdateAliasAsync(alias);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
await GetAliases();
|
||||||
|
}
|
||||||
|
|
||||||
await logger.LogInformation("Site Settings Saved {Site}", site);
|
await logger.LogInformation("Site Settings Saved {Site}", site);
|
||||||
|
|
||||||
@ -602,4 +617,19 @@
|
|||||||
AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task GetAliases()
|
||||||
|
{
|
||||||
|
_urls = string.Empty;
|
||||||
|
_defaultalias = string.Empty;
|
||||||
|
_aliases = await AliasService.GetAliasesAsync();
|
||||||
|
foreach (Alias alias in _aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId).ToList())
|
||||||
|
{
|
||||||
|
_urls += (_urls == string.Empty) ? alias.Name : ", " + alias.Name;
|
||||||
|
if (alias.IsDefault && string.IsNullOrEmpty(_defaultalias))
|
||||||
|
{
|
||||||
|
_defaultalias = alias.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Sites
|
@namespace Oqtane.Modules.Admin.Sites
|
||||||
@using Oqtane.Interfaces
|
@using Oqtane.Interfaces
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject ITenantService TenantService
|
@inject ITenantService TenantService
|
||||||
@ -282,6 +283,7 @@ else
|
|||||||
{
|
{
|
||||||
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-")
|
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-")
|
||||||
{
|
{
|
||||||
|
_urls = Regex.Replace(_urls, @"\r\n?|\n", ",");
|
||||||
var duplicates = new List<string>();
|
var duplicates = new List<string>();
|
||||||
var aliases = await AliasService.GetAliasesAsync();
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
@ -43,7 +43,7 @@ else
|
|||||||
_sites = new List<Alias>();
|
_sites = new List<Alias>();
|
||||||
foreach (Alias alias in aliases)
|
foreach (Alias alias in aliases)
|
||||||
{
|
{
|
||||||
if (!_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
if (alias.IsDefault && !_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
||||||
{
|
{
|
||||||
_sites.Add(alias);
|
_sites.Add(alias);
|
||||||
}
|
}
|
||||||
@ -52,16 +52,11 @@ else
|
|||||||
|
|
||||||
private void Edit(string name)
|
private void Edit(string name)
|
||||||
{
|
{
|
||||||
if (name.Equals("*"))
|
NavigationManager.NavigateTo(_scheme + name + "/admin/site", true);
|
||||||
{
|
|
||||||
var uri = new Uri(NavigationManager.Uri);
|
|
||||||
name = uri.Authority;
|
|
||||||
}
|
|
||||||
NavigationManager.NavigateTo(_scheme + name + "/admin/site/?reload");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Browse(string name)
|
private void Browse(string name)
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(_scheme + name + "/?reload");
|
NavigationManager.NavigateTo(_scheme + name, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,9 +129,6 @@
|
|||||||
<data name="DefaultContainer.Text" xml:space="preserve">
|
<data name="DefaultContainer.Text" xml:space="preserve">
|
||||||
<value>Default Container: </value>
|
<value>Default Container: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Appearance.Heading" xml:space="preserve">
|
|
||||||
<value>Appearance</value>
|
|
||||||
</data>
|
|
||||||
<data name="DefaultAdminContainer" xml:space="preserve">
|
<data name="DefaultAdminContainer" xml:space="preserve">
|
||||||
<value>Default Admin Container</value>
|
<value>Default Admin Container</value>
|
||||||
</data>
|
</data>
|
||||||
@ -223,7 +220,7 @@
|
|||||||
<value>Aliases: </value>
|
<value>Aliases: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDeleted.Text" xml:space="preserve">
|
<data name="IsDeleted.Text" xml:space="preserve">
|
||||||
<value>Is Deleted? </value>
|
<value>Deleted? </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Logo.Text" xml:space="preserve">
|
<data name="Logo.Text" xml:space="preserve">
|
||||||
<value>Logo: </value>
|
<value>Logo: </value>
|
||||||
@ -318,4 +315,13 @@
|
|||||||
<data name="DeleteSite.Text" xml:space="preserve">
|
<data name="DeleteSite.Text" xml:space="preserve">
|
||||||
<value>Delete Site</value>
|
<value>Delete Site</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DefaultAlias.HelpText" xml:space="preserve">
|
||||||
|
<value>The default alias for the site. Requests for non-default aliases will be redirected to the default alias.</value>
|
||||||
|
</data>
|
||||||
|
<data name="DefaultAlias.Text" xml:space="preserve">
|
||||||
|
<value>Default Alias: </value>
|
||||||
|
</data>
|
||||||
|
<data name="Aliases.Heading" xml:space="preserve">
|
||||||
|
<value>Aliases</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -152,7 +152,7 @@ namespace Oqtane.Services
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (setting.SettingValue != kvp.Value)
|
if (setting.SettingValue != value || setting.IsPublic != ispublic)
|
||||||
{
|
{
|
||||||
setting.SettingValue = value;
|
setting.SettingValue = value;
|
||||||
setting.IsPublic = ispublic;
|
setting.IsPublic = ispublic;
|
||||||
|
@ -367,7 +367,9 @@ namespace Oqtane.Infrastructure
|
|||||||
tenant = db.Tenant.FirstOrDefault(item => item.Name == install.TenantName);
|
tenant = db.Tenant.FirstOrDefault(item => item.Name == install.TenantName);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var aliasName in install.Aliases.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
|
var aliasNames = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray();
|
||||||
|
var firstAlias = aliasNames[0];
|
||||||
|
foreach (var aliasName in aliasNames)
|
||||||
{
|
{
|
||||||
if (tenant != null)
|
if (tenant != null)
|
||||||
{
|
{
|
||||||
@ -376,6 +378,7 @@ namespace Oqtane.Infrastructure
|
|||||||
Name = aliasName,
|
Name = aliasName,
|
||||||
TenantId = tenant.TenantId,
|
TenantId = tenant.TenantId,
|
||||||
SiteId = -1,
|
SiteId = -1,
|
||||||
|
IsDefault = (aliasName == firstAlias),
|
||||||
CreatedBy = "",
|
CreatedBy = "",
|
||||||
CreatedOn = DateTime.UtcNow,
|
CreatedOn = DateTime.UtcNow,
|
||||||
ModifiedBy = "",
|
ModifiedBy = "",
|
||||||
@ -558,7 +561,8 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
// set the alias explicitly so the tenant can be resolved
|
// set the alias explicitly so the tenant can be resolved
|
||||||
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
var aliases = scope.ServiceProvider.GetRequiredService<IAliasRepository>();
|
||||||
var firstAlias = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
var aliasNames = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray();
|
||||||
|
var firstAlias = aliasNames[0];
|
||||||
var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
|
var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
|
||||||
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
var tenantManager = scope.ServiceProvider.GetRequiredService<ITenantManager>();
|
||||||
tenantManager.SetAlias(alias);
|
tenantManager.SetAlias(alias);
|
||||||
@ -650,7 +654,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var aliasName in install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (var aliasName in aliasNames)
|
||||||
{
|
{
|
||||||
alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
|
alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
|
||||||
if (alias != null)
|
if (alias != null)
|
||||||
|
31
Oqtane.Server/Migrations/Master/03000201_AddAliasRedirect.cs
Normal file
31
Oqtane.Server/Migrations/Master/03000201_AddAliasRedirect.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Oqtane.Databases.Interfaces;
|
||||||
|
using Oqtane.Migrations.EntityBuilders;
|
||||||
|
using Oqtane.Repository;
|
||||||
|
|
||||||
|
namespace Oqtane.Migrations.Master
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MasterDBContext))]
|
||||||
|
[Migration("Master.03.00.02.01")]
|
||||||
|
public class AddAliasRedirect : MultiDatabaseMigration
|
||||||
|
{
|
||||||
|
public AddAliasRedirect(IDatabase database) : base(database)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
//Add Column to Alias table
|
||||||
|
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
aliasEntityBuilder.AddBooleanColumn("IsDefault", true);
|
||||||
|
aliasEntityBuilder.UpdateColumn("IsDefault", "1", "bool", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
var aliasEntityBuilder = new AliasEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||||
|
aliasEntityBuilder.DropColumn("IsDefault");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace Oqtane.Pages
|
namespace Oqtane.Pages
|
||||||
{
|
{
|
||||||
@ -32,8 +33,9 @@ namespace Oqtane.Pages
|
|||||||
private readonly IPageRepository _pages;
|
private readonly IPageRepository _pages;
|
||||||
private readonly IUrlMappingRepository _urlMappings;
|
private readonly IUrlMappingRepository _urlMappings;
|
||||||
private readonly IVisitorRepository _visitors;
|
private readonly IVisitorRepository _visitors;
|
||||||
|
private readonly IAliasRepository _aliases;
|
||||||
|
|
||||||
public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors)
|
public HostModel(IConfiguration configuration, ITenantManager tenantManager, ILocalizationManager localizationManager, ILanguageRepository languages, IAntiforgery antiforgery, ISiteRepository sites, IPageRepository pages, IUrlMappingRepository urlMappings, IVisitorRepository visitors, IAliasRepository aliases)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_tenantManager = tenantManager;
|
_tenantManager = tenantManager;
|
||||||
@ -44,6 +46,7 @@ namespace Oqtane.Pages
|
|||||||
_pages = pages;
|
_pages = pages;
|
||||||
_urlMappings = urlMappings;
|
_urlMappings = urlMappings;
|
||||||
_visitors = visitors;
|
_visitors = visitors;
|
||||||
|
_aliases = aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string AntiForgeryToken = "";
|
public string AntiForgeryToken = "";
|
||||||
@ -77,11 +80,25 @@ namespace Oqtane.Pages
|
|||||||
var alias = _tenantManager.GetAlias();
|
var alias = _tenantManager.GetAlias();
|
||||||
if (alias != null)
|
if (alias != null)
|
||||||
{
|
{
|
||||||
Route route = new Route(HttpContext.Request.GetEncodedUrl(), alias.Path);
|
var url = WebUtility.UrlDecode(HttpContext.Request.GetEncodedUrl());
|
||||||
|
|
||||||
|
// redirect non-default alias
|
||||||
|
if (!alias.IsDefault)
|
||||||
|
{
|
||||||
|
var redirect = _aliases.GetAliases()
|
||||||
|
.Where(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId && item.IsDefault)
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (redirect != null)
|
||||||
|
{
|
||||||
|
return RedirectPermanent(url.Replace(alias.Name, redirect.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var site = _sites.GetSite(alias.SiteId);
|
var site = _sites.GetSite(alias.SiteId);
|
||||||
if (site != null)
|
if (site != null)
|
||||||
{
|
{
|
||||||
|
Route route = new Route(url, alias.Path);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(site.Runtime))
|
if (!string.IsNullOrEmpty(site.Runtime))
|
||||||
{
|
{
|
||||||
Runtime = site.Runtime;
|
Runtime = site.Runtime;
|
||||||
@ -128,7 +145,7 @@ namespace Oqtane.Pages
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// page does not exist
|
// page does not exist
|
||||||
var url = route.SiteUrl + "/" + route.PagePath;
|
url = route.SiteUrl + "/" + route.PagePath;
|
||||||
var urlMapping = _urlMappings.GetUrlMapping(site.SiteId, url);
|
var urlMapping = _urlMappings.GetUrlMapping(site.SiteId, url);
|
||||||
if (urlMapping != null && !string.IsNullOrEmpty(urlMapping.MappedUrl))
|
if (urlMapping != null && !string.IsNullOrEmpty(urlMapping.MappedUrl))
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Repository
|
namespace Oqtane.Repository
|
||||||
{
|
{
|
||||||
@ -72,7 +73,7 @@ namespace Oqtane.Repository
|
|||||||
int start = segments.Length;
|
int start = segments.Length;
|
||||||
for (int i = 0; i < segments.Length; i++)
|
for (int i = 0; i < segments.Length; i++)
|
||||||
{
|
{
|
||||||
if (segments[i] == "api" || segments[i] == "pages" || segments[i] == "*")
|
if (segments[i] == "api" || segments[i] == "pages" || segments[i] == Constants.ModuleDelimiter)
|
||||||
{
|
{
|
||||||
start = i;
|
start = i;
|
||||||
break;
|
break;
|
||||||
@ -89,8 +90,18 @@ namespace Oqtane.Repository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return fallback alias if none found
|
// auto register alias if there is only a single tenant/site
|
||||||
return alias ?? aliases.Find(item => item.Name.Equals("*"));
|
if (alias == null && aliases.Select(item => new { item.TenantId, item.SiteId }).Distinct().Count() == 1)
|
||||||
|
{
|
||||||
|
alias = new Alias();
|
||||||
|
alias.TenantId = aliases.First().TenantId;
|
||||||
|
alias.SiteId = aliases.First().SiteId;
|
||||||
|
alias.Name = url;
|
||||||
|
alias.IsDefault = false;
|
||||||
|
alias = AddAlias(alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteAlias(int aliasId)
|
public void DeleteAlias(int aliasId)
|
||||||
|
@ -30,6 +30,11 @@ namespace Oqtane.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int SiteId { get; set; }
|
public int SiteId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies if the alias is the default for the tenant/site. Requests for non-default aliases are redirected to the default alias.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDefault { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string CreatedBy { get; set; }
|
public string CreatedBy { get; set; }
|
||||||
|
|
||||||
@ -62,5 +67,6 @@ namespace Oqtane.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace Oqtane.Models
|
|||||||
Action = "";
|
Action = "";
|
||||||
UrlParameters = "";
|
UrlParameters = "";
|
||||||
|
|
||||||
if (AliasPath.Length != 0)
|
if (AliasPath.Length != 0 && PagePath.StartsWith("/" + AliasPath))
|
||||||
{
|
{
|
||||||
PagePath = PagePath.Substring(AliasPath.Length + 1);
|
PagePath = PagePath.Substring(AliasPath.Length + 1);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user