Merge pull request #5857 from sbwalker/dev
move user workload from siterouter to app component to improve performance and 404 handling
This commit is contained in:
@ -29,8 +29,6 @@ namespace Oqtane.UI
|
||||
public bool Refresh { get; set; }
|
||||
public bool AllowCookies { get; set; }
|
||||
|
||||
public int? StatusCode { get; set; }
|
||||
|
||||
public List<Page> Pages
|
||||
{
|
||||
get { return Site?.Pages; }
|
||||
@ -65,8 +63,7 @@ namespace Oqtane.UI
|
||||
IsInternalNavigation = IsInternalNavigation,
|
||||
RenderId = RenderId,
|
||||
Refresh = Refresh,
|
||||
AllowCookies = AllowCookies,
|
||||
StatusCode = StatusCode
|
||||
AllowCookies = AllowCookies
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,13 +158,17 @@
|
||||
|
||||
// verify user is authenticated for current site
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
if (authState.User.Identity.IsAuthenticated
|
||||
&& authState.User.Claims.Any(item => item.Type == Constants.SiteKeyClaimType && item.Value == SiteState.Alias.SiteKey)
|
||||
&& PageState.StatusCode != (int)HttpStatusCode.NotFound)
|
||||
if (authState.User.IsAuthenticated() && authState.User.SiteKey() == SiteState.Alias.SiteKey)
|
||||
{
|
||||
// get user
|
||||
var userid = int.Parse(authState.User.Claims.First(item => item.Type == ClaimTypes.NameIdentifier).Value);
|
||||
user = await UserService.GetUserAsync(userid, SiteState.Alias.SiteId);
|
||||
if (PageState == null || PageState.User == null || PageState.User.UserId != authState.User.UserId())
|
||||
{
|
||||
// get user
|
||||
user = await UserService.GetUserAsync(authState.User.UserId(), SiteState.Alias.SiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
user = PageState.User;
|
||||
}
|
||||
if (user != null)
|
||||
{
|
||||
user.IsAuthenticated = authState.User.Identity.IsAuthenticated;
|
||||
@ -339,7 +343,6 @@
|
||||
IsInternalNavigation = _isInternalNavigation,
|
||||
RenderId = renderid,
|
||||
Refresh = false,
|
||||
StatusCode = PageState?.StatusCode,
|
||||
AllowCookies = _allowCookies.GetValueOrDefault(true)
|
||||
};
|
||||
OnStateChange?.Invoke(_pagestate);
|
||||
|
||||
@ -27,3 +27,4 @@
|
||||
@using Oqtane.Enums
|
||||
@using Oqtane.Installer
|
||||
@using Oqtane.Interfaces
|
||||
@using Oqtane.Extensions
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
}
|
||||
@((MarkupString)_headResources)
|
||||
</head>
|
||||
<body data-enhance-nav="@_enhancedNavigation.ToString().ToLower()">
|
||||
<body @attributes="_bodyAttributes">
|
||||
@if (string.IsNullOrEmpty(_message))
|
||||
{
|
||||
@if (_renderMode == RenderModes.Static)
|
||||
@ -97,7 +97,7 @@
|
||||
private string _renderMode = RenderModes.Interactive;
|
||||
private string _runtime = Runtimes.Server;
|
||||
private bool _prerender = true;
|
||||
private bool _enhancedNavigation = true;
|
||||
Dictionary<string, object> _bodyAttributes { get; set; } = new();
|
||||
private string _fingerprint = "";
|
||||
private int _visitorId = -1;
|
||||
private string _antiForgeryToken = "";
|
||||
@ -142,7 +142,10 @@
|
||||
_renderMode = site.RenderMode;
|
||||
_runtime = site.Runtime;
|
||||
_prerender = site.Prerender;
|
||||
_enhancedNavigation = site.EnhancedNavigation;
|
||||
if (_renderMode == RenderModes.Static && !site.EnhancedNavigation)
|
||||
{
|
||||
_bodyAttributes.Add("data-enhance-nav", "false");
|
||||
}
|
||||
_fingerprint = site.Fingerprint;
|
||||
|
||||
var cookieConsentSettings = SettingService.GetSetting(site.Settings, "CookieConsent", string.Empty);
|
||||
@ -234,7 +237,7 @@
|
||||
Site = site,
|
||||
Page = page,
|
||||
Modules = modules,
|
||||
User = null,
|
||||
User = site.User,
|
||||
Uri = new Uri(url, UriKind.Absolute),
|
||||
Route = route,
|
||||
QueryString = Utilities.ParseQueryString(route.Query),
|
||||
@ -251,7 +254,6 @@
|
||||
IsInternalNavigation = false,
|
||||
RenderId = Guid.NewGuid(),
|
||||
Refresh = true,
|
||||
StatusCode = Context.Response.StatusCode,
|
||||
AllowCookies = _allowCookies
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface ISiteNamedOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
void Configure(string name, TOptions options, Alias alias, Dictionary<string, string> sitesettings);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface ISiteOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
void Configure(TOptions options, Alias alias, Dictionary<string, string> sitesettings);
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,12 @@ using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface ISiteNamedOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
void Configure(string name, TOptions options, Alias alias, Dictionary<string, string> sitesettings);
|
||||
}
|
||||
|
||||
public class SiteNamedOptions<TOptions> : ISiteNamedOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
|
||||
@ -4,6 +4,12 @@ using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface ISiteOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
void Configure(TOptions options, Alias alias, Dictionary<string, string> sitesettings);
|
||||
}
|
||||
|
||||
public class SiteOptions<TOptions> : ISiteOptions<TOptions>
|
||||
where TOptions : class, new()
|
||||
{
|
||||
|
||||
@ -13,6 +13,7 @@ using Oqtane.Enums;
|
||||
using Oqtane.Shared;
|
||||
using System.Globalization;
|
||||
using Oqtane.Extensions;
|
||||
using Oqtane.Managers;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
@ -25,6 +26,7 @@ namespace Oqtane.Services
|
||||
private readonly IPageModuleRepository _pageModules;
|
||||
private readonly IModuleDefinitionRepository _moduleDefinitions;
|
||||
private readonly ILanguageRepository _languages;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserPermissions _userPermissions;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly ITenantManager _tenantManager;
|
||||
@ -35,7 +37,7 @@ namespace Oqtane.Services
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
private readonly string _private = "[PRIVATE]";
|
||||
|
||||
public ServerSiteService(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, IConfigManager configManager, ILogManager logger, IMemoryCache cache, IHttpContextAccessor accessor)
|
||||
public ServerSiteService(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserManager userManager, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, IConfigManager configManager, ILogManager logger, IMemoryCache cache, IHttpContextAccessor accessor)
|
||||
{
|
||||
_sites = sites;
|
||||
_pages = pages;
|
||||
@ -43,6 +45,7 @@ namespace Oqtane.Services
|
||||
_pageModules = pageModules;
|
||||
_moduleDefinitions = moduleDefinitions;
|
||||
_languages = languages;
|
||||
_userManager = userManager;
|
||||
_userPermissions = userPermissions;
|
||||
_settings = settings;
|
||||
_tenantManager = tenantManager;
|
||||
@ -146,6 +149,12 @@ namespace Oqtane.Services
|
||||
// themes
|
||||
site.Themes = _themes.FilterThemes(_themes.GetThemes(site.SiteId).ToList());
|
||||
|
||||
// user
|
||||
if (_accessor.HttpContext.User.IsAuthenticated())
|
||||
{
|
||||
site.User = _userManager.GetUser(_accessor.HttpContext.User.UserId(), site.SiteId);
|
||||
}
|
||||
|
||||
// installation date used for fingerprinting static assets
|
||||
site.Fingerprint = Utilities.GenerateSimpleHash(_configManager.GetSetting("InstallationDate", DateTime.UtcNow.ToString("yyyyMMddHHmm")));
|
||||
|
||||
|
||||
@ -8,6 +8,18 @@ namespace Oqtane.Extensions
|
||||
{
|
||||
// extension methods cannot be properties - the methods below must include a () suffix when referenced
|
||||
|
||||
public static bool IsAuthenticated(this ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
if (claimsPrincipal.Identity != null)
|
||||
{
|
||||
return claimsPrincipal.Identity.IsAuthenticated;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Username(this ClaimsPrincipal claimsPrincipal)
|
||||
{
|
||||
if (claimsPrincipal.HasClaim(item => item.Type == ClaimTypes.Name))
|
||||
@ -192,6 +192,12 @@ namespace Oqtane.Models
|
||||
[NotMapped]
|
||||
public List<Theme> Themes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current user
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public User User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// fingerprint for framework static assets
|
||||
/// </summary>
|
||||
@ -246,6 +252,7 @@ namespace Oqtane.Models
|
||||
Pages = Pages.ConvertAll(page => page.Clone()),
|
||||
Languages = Languages.ConvertAll(language => language.Clone()),
|
||||
Themes = Themes,
|
||||
User = User.Clone(),
|
||||
Fingerprint = Fingerprint,
|
||||
TenantId = TenantId
|
||||
};
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
@ -128,5 +130,34 @@ namespace Oqtane.Models
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public Dictionary<string, string> Settings { get; set; }
|
||||
|
||||
public User Clone()
|
||||
{
|
||||
return new User
|
||||
{
|
||||
UserId = UserId,
|
||||
Username = Username,
|
||||
DisplayName = DisplayName,
|
||||
Email = Email,
|
||||
TimeZoneId = TimeZoneId,
|
||||
PhotoFileId = PhotoFileId,
|
||||
LastLoginOn = LastLoginOn,
|
||||
LastIPAddress = LastIPAddress,
|
||||
TwoFactorRequired = TwoFactorRequired,
|
||||
TwoFactorCode = TwoFactorCode,
|
||||
TwoFactorExpiry = TwoFactorExpiry,
|
||||
SecurityStamp = SecurityStamp,
|
||||
SiteId = SiteId,
|
||||
Roles = Roles,
|
||||
DeletedBy = DeletedBy,
|
||||
DeletedOn = DeletedOn,
|
||||
IsDeleted = IsDeleted,
|
||||
Password = Password,
|
||||
IsAuthenticated = IsAuthenticated,
|
||||
EmailConfirmed = EmailConfirmed,
|
||||
SuppressNotification = SuppressNotification,
|
||||
Settings = Settings.ToDictionary(setting => setting.Key, setting => setting.Value)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user