From 0c8dc6308551315c39cbbecfc5808da12a3a93bb Mon Sep 17 00:00:00 2001 From: sbwalker Date: Tue, 12 Mar 2024 10:27:32 -0400 Subject: [PATCH] improve caching for sites with many registered users --- .../Extensions/ClaimsPrincipalExtensions.cs | 13 +++++++++++ Oqtane.Server/Services/SiteService.cs | 23 +++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Oqtane.Server/Extensions/ClaimsPrincipalExtensions.cs b/Oqtane.Server/Extensions/ClaimsPrincipalExtensions.cs index 3a5ca2f4..98cd043c 100644 --- a/Oqtane.Server/Extensions/ClaimsPrincipalExtensions.cs +++ b/Oqtane.Server/Extensions/ClaimsPrincipalExtensions.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Security.Claims; +using Oqtane.Shared; namespace Oqtane.Extensions { @@ -70,5 +71,17 @@ namespace Oqtane.Extensions } return -1; } + + public static bool IsOnlyInRole(this ClaimsPrincipal claimsPrincipal, string role) + { + var identity = claimsPrincipal.Identities.FirstOrDefault(item => item.AuthenticationType == Constants.AuthenticationScheme); + if (identity != null) + { + // check if user has role claim specified and no other role claims + return identity.Claims.Any(item => item.Type == ClaimTypes.Role && item.Value == role) && + !identity.Claims.Any(item => item.Type == ClaimTypes.Role && item.Value != role); + } + return false; + } } } diff --git a/Oqtane.Server/Services/SiteService.cs b/Oqtane.Server/Services/SiteService.cs index f94d3f3f..f8656ba7 100644 --- a/Oqtane.Server/Services/SiteService.cs +++ b/Oqtane.Server/Services/SiteService.cs @@ -64,19 +64,32 @@ namespace Oqtane.Services { if (!_accessor.HttpContext.User.Identity.IsAuthenticated) { + // unauthenticated return await _cache.GetOrCreateAsync($"site:{_accessor.HttpContext.GetAlias().SiteKey}", async entry => { entry.SlidingExpiration = TimeSpan.FromMinutes(30); return await GetSite(siteId); }, true); } - else // authenticated - cached per user + else // authenticated { - return await _cache.GetOrCreateAsync($"site:{_accessor.HttpContext.GetAlias().SiteKey}:{_accessor.HttpContext.User.UserId}", async entry => + // is only in registered users role - cache by role + if (_accessor.HttpContext.User.IsOnlyInRole(RoleNames.Registered)) { - entry.SlidingExpiration = TimeSpan.FromMinutes(30); - return await GetSite(siteId); - }, true); + return await _cache.GetOrCreateAsync($"site:{_accessor.HttpContext.GetAlias().SiteKey}:{RoleNames.Registered}", async entry => + { + entry.SlidingExpiration = TimeSpan.FromMinutes(30); + return await GetSite(siteId); + }, true); + } + else // cache by user + { + return await _cache.GetOrCreateAsync($"site:{_accessor.HttpContext.GetAlias().SiteKey}:{_accessor.HttpContext.User.UserId}", async entry => + { + entry.SlidingExpiration = TimeSpan.FromMinutes(30); + return await GetSite(siteId); + }, true); + } } }