fix #4401 - avoid mutating Site object in cache

This commit is contained in:
sbwalker 2024-07-15 08:37:23 -04:00
parent c3f041dc87
commit 6275ab23ff
2 changed files with 105 additions and 20 deletions

View File

@ -69,6 +69,7 @@ namespace Oqtane.Services
return await GetSite(siteId); return await GetSite(siteId);
}); });
// trim pages based on user permissions
var pages = new List<Page>(); var pages = new List<Page>();
foreach (Page page in site.Pages) foreach (Page page in site.Pages)
{ {
@ -77,6 +78,9 @@ namespace Oqtane.Services
pages.Add(page); pages.Add(page);
} }
} }
// clone object so that cache is not mutated
site = site.Clone(site);
site.Pages = pages; site.Pages = pages;
return site; return site;

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Oqtane.Models namespace Oqtane.Models
{ {
@ -11,7 +12,7 @@ namespace Oqtane.Models
public class Site : ModelBase, IDeletable public class Site : ModelBase, IDeletable
{ {
/// <summary> /// <summary>
/// Internal ID, not to be confused with the <see cref="Alias.AliasId"/> /// The ID of the Site
/// </summary> /// </summary>
public int SiteId { get; set; } public int SiteId { get; set; }
@ -22,7 +23,6 @@ namespace Oqtane.Models
/// <summary> /// <summary>
/// The site Name /// The site Name
/// TODO: todoc where this will be used / shown
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
@ -37,15 +37,37 @@ namespace Oqtane.Models
/// Reference to a <see cref="File"/> which has the FavIcon for this site. /// Reference to a <see cref="File"/> which has the FavIcon for this site.
/// Should be an image. /// Should be an image.
/// The theme can then use this where needed. /// The theme can then use this where needed.
/// TODO: todoc does this get applied automatically, or does the Theme do this?
/// </summary> /// </summary>
public int? FaviconFileId { get; set; } public int? FaviconFileId { get; set; }
/// <summary>
/// Default theme for the site
/// </summary>
public string DefaultThemeType { get; set; } public string DefaultThemeType { get; set; }
/// <summary>
/// Default container for the site
/// </summary>
public string DefaultContainerType { get; set; } public string DefaultContainerType { get; set; }
/// <summary>
/// Default admin container
/// </summary>
public string AdminContainerType { get; set; } public string AdminContainerType { get; set; }
/// <summary>
/// Indicates if the site is a progressive web application (PWA)
/// </summary>
public bool PwaIsEnabled { get; set; } public bool PwaIsEnabled { get; set; }
/// <summary>
/// The app icon for the progressive web application (PWA)
/// </summary>
public int? PwaAppIconFileId { get; set; } public int? PwaAppIconFileId { get; set; }
/// <summary>
/// The splash icon for the progressive web application (PWA)
/// </summary>
public int? PwaSplashIconFileId { get; set; } public int? PwaSplashIconFileId { get; set; }
/// <summary> /// <summary>
@ -54,7 +76,7 @@ namespace Oqtane.Models
public bool AllowRegistration { get; set; } public bool AllowRegistration { get; set; }
/// <summary> /// <summary>
/// Determines if visitors will be tracked /// Determines if site visitors will be recorded
/// </summary> /// </summary>
public bool VisitorTracking { get; set; } public bool VisitorTracking { get; set; }
@ -94,7 +116,7 @@ namespace Oqtane.Models
public string Version { get; set; } public string Version { get; set; }
/// <summary> /// <summary>
/// The home page of the site which will be used as a fallback if no page has a path of "/" /// The home page of the site - the "/" path will be used by default if no home page is specified
/// </summary> /// </summary>
public int? HomePageId { get; set; } public int? HomePageId { get; set; }
@ -109,42 +131,101 @@ namespace Oqtane.Models
public string BodyContent { get; set; } public string BodyContent { get; set; }
/// <summary> /// <summary>
/// The ImageFile extensions /// Indicates if site is deleted
/// </summary>
public bool IsDeleted { get; set; }
/// <summary>
/// The user who deleted site
/// </summary>
public string DeletedBy { get; set; }
/// <summary>
/// Date site was deleted
/// </summary>
public DateTime? DeletedOn { get; set; }
/// <summary>
/// The allowable iamge file extensions
/// </summary> /// </summary>
[NotMapped] [NotMapped]
public string ImageFiles { get; set; } public string ImageFiles { get; set; }
/// <summary> /// <summary>
/// The UploadableFile extensions /// The allowable file extensions which can be uploaded
/// </summary> /// </summary>
[NotMapped] [NotMapped]
public string UploadableFiles { get; set; } public string UploadableFiles { get; set; }
/// <summary>
/// Used when provisioning a site from a site template
/// </summary>
[NotMapped]
public string SiteTemplateType { get; set; }
/// <summary>
/// The settings for the site
/// </summary>
[NotMapped] [NotMapped]
public Dictionary<string, string> Settings { get; set; } public Dictionary<string, string> Settings { get; set; }
/// <summary>
/// List of pages for the site
/// </summary>
[NotMapped] [NotMapped]
public List<Page> Pages { get; set; } public List<Page> Pages { get; set; }
//[NotMapped] /// <summary>
//public List<Module> Modules { get; set; } /// List of languages for the site
/// </summary>
[NotMapped] [NotMapped]
public List<Language> Languages { get; set; } public List<Language> Languages { get; set; }
/// <summary>
/// List of themes for the site
/// </summary>
[NotMapped] [NotMapped]
public List<Theme> Themes { get; set; } public List<Theme> Themes { get; set; }
#region IDeletable Properties public Site Clone(Site site)
{
public string DeletedBy { get; set; } return new Site
public DateTime? DeletedOn { get; set; } {
public bool IsDeleted { get; set; } SiteId = site.SiteId,
TenantId = site.TenantId,
#endregion Name = site.Name,
LogoFileId = site.LogoFileId,
[NotMapped] FaviconFileId = site.FaviconFileId,
public string SiteTemplateType { get; set; } DefaultThemeType = site.DefaultThemeType,
DefaultContainerType = site.DefaultContainerType,
AdminContainerType = site.AdminContainerType,
PwaIsEnabled = site.PwaIsEnabled,
PwaAppIconFileId = site.PwaAppIconFileId,
PwaSplashIconFileId = site.PwaSplashIconFileId,
AllowRegistration = site.AllowRegistration,
VisitorTracking = site.VisitorTracking,
CaptureBrokenUrls = site.CaptureBrokenUrls,
SiteGuid = site.SiteGuid,
RenderMode = site.RenderMode,
Runtime = site.Runtime,
Prerender = site.Prerender,
Hybrid = site.Hybrid,
Version = site.Version,
HomePageId = site.HomePageId,
HeadContent = site.HeadContent,
BodyContent = site.BodyContent,
IsDeleted = site.IsDeleted,
DeletedBy = site.DeletedBy,
DeletedOn = site.DeletedOn,
ImageFiles = site.ImageFiles,
UploadableFiles = site.UploadableFiles,
SiteTemplateType = site.SiteTemplateType,
Settings = site.Settings.ToDictionary(),
Pages = site.Pages.ToList(),
Languages = site.Languages.ToList(),
Themes = site.Themes.ToList()
};
}
#region Obsolete properties #region Obsolete properties
[NotMapped] [NotMapped]