allow themes to define usage permissions similar to modules

This commit is contained in:
sbwalker
2025-09-25 13:55:02 -04:00
parent bebe70f46b
commit 8d23d9aba3
18 changed files with 296 additions and 130 deletions

View File

@ -386,6 +386,7 @@ namespace Oqtane.Repository
moduledefinition.Categories = "Common";
}
// default permissions
if (moduledefinition.Categories == "Admin")
{
var shortName = moduledefinition.ModuleDefinitionName.Replace("Oqtane.Modules.Admin.", "").Replace(", Oqtane.Client", "");
@ -455,18 +456,21 @@ namespace Oqtane.Repository
private List<Permission> ClonePermissions(int siteId, List<Permission> permissionList)
{
var permissions = new List<Permission>();
foreach (var p in permissionList)
if (permissionList != null)
{
var permission = new Permission();
permission.SiteId = siteId;
permission.EntityName = p.EntityName;
permission.EntityId = p.EntityId;
permission.PermissionName = p.PermissionName;
permission.RoleId = null;
permission.RoleName = p.RoleName;
permission.UserId = p.UserId;
permission.IsAuthorized = p.IsAuthorized;
permissions.Add(permission);
foreach (var p in permissionList)
{
var permission = new Permission();
permission.SiteId = siteId;
permission.EntityName = p.EntityName;
permission.EntityId = p.EntityId;
permission.PermissionName = p.PermissionName;
permission.RoleId = null;
permission.RoleName = p.RoleName;
permission.UserId = p.UserId;
permission.IsAuthorized = p.IsAuthorized;
permissions.Add(permission);
}
}
return permissions;
}

View File

@ -135,7 +135,7 @@ namespace Oqtane.Repository
if (site != null)
{
// initialize theme Assemblies
site.Themes = _themeRepository.GetThemes().ToList();
site.Themes = _themeRepository.GetThemes(site.SiteId).ToList();
// initialize module Assemblies
var moduleDefinitions = _moduleDefinitionRepository.GetModuleDefinitions(alias.SiteId);

View File

@ -15,7 +15,7 @@ namespace Oqtane.Repository
{
public interface IThemeRepository
{
IEnumerable<Theme> GetThemes();
IEnumerable<Theme> GetThemes(int siteId);
Theme GetTheme(int themeId, int siteId);
void UpdateTheme(Theme theme);
void DeleteTheme(int themeId);
@ -26,24 +26,25 @@ namespace Oqtane.Repository
{
private MasterDBContext _db;
private readonly IMemoryCache _cache;
private readonly IPermissionRepository _permissions;
private readonly ITenantManager _tenants;
private readonly ISettingRepository _settings;
private readonly IServerStateManager _serverState;
private readonly string settingprefix = "SiteEnabled:";
public ThemeRepository(MasterDBContext context, IMemoryCache cache, ITenantManager tenants, ISettingRepository settings, IServerStateManager serverState)
public ThemeRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions, ITenantManager tenants, ISettingRepository settings, IServerStateManager serverState)
{
_db = context;
_cache = cache;
_permissions = permissions;
_tenants = tenants;
_settings = settings;
_serverState = serverState;
}
public IEnumerable<Theme> GetThemes()
public IEnumerable<Theme> GetThemes(int siteId)
{
// for consistency siteid should be passed in as parameter, but this would require breaking change
return LoadThemes(_tenants.GetAlias().SiteId);
return LoadThemes(siteId);
}
public Theme GetTheme(int themeId, int siteId)
@ -56,6 +57,7 @@ namespace Oqtane.Repository
{
_db.Entry(theme).State = EntityState.Modified;
_db.SaveChanges();
_permissions.UpdatePermissions(theme.SiteId, EntityNames.Theme, theme.ThemeId, theme.PermissionList);
var settingname = $"{settingprefix}{_tenants.GetAlias().SiteKey}";
var setting = _settings.GetSetting(EntityNames.Theme, theme.ThemeId, settingname);
@ -96,6 +98,7 @@ namespace Oqtane.Repository
Theme.ThemeSettingsType = theme.ThemeSettingsType;
Theme.ContainerSettingsType = theme.ContainerSettingsType;
Theme.PackageName = theme.PackageName;
Theme.PermissionList = theme.PermissionList;
Theme.Fingerprint = Utilities.GenerateSimpleHash(theme.ModifiedOn.ToString("yyyyMMddHHmm"));
Themes.Add(Theme);
}
@ -176,6 +179,9 @@ namespace Oqtane.Repository
var siteKey = _tenants.GetAlias().SiteKey;
var assemblies = new List<string>();
// get all module definition permissions for site
List<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.Theme).ToList();
// get settings for site
var settings = _settings.GetSettings(EntityNames.Theme).ToList();
@ -212,6 +218,26 @@ namespace Oqtane.Repository
}
}
}
if (permissions.Count == 0)
{
// no module definition permissions exist for this site
theme.PermissionList = ClonePermissions(siteId, theme.PermissionList);
_permissions.UpdatePermissions(siteId, EntityNames.Theme, theme.ThemeId, theme.PermissionList);
}
else
{
if (permissions.Any(item => item.EntityId == theme.ThemeId))
{
theme.PermissionList = permissions.Where(item => item.EntityId == theme.ThemeId).ToList();
}
else
{
// permissions for theme do not exist for this site
theme.PermissionList = ClonePermissions(siteId, theme.PermissionList);
_permissions.UpdatePermissions(siteId, EntityNames.Theme, theme.ThemeId, theme.PermissionList);
}
}
}
// cache site assemblies
@ -220,6 +246,20 @@ namespace Oqtane.Repository
{
if (!serverState.Assemblies.Contains(assembly)) serverState.Assemblies.Add(assembly);
}
// clean up any orphaned permissions
var ids = new HashSet<int>(Themes.Select(item => item.ThemeId));
foreach (var permission in permissions.Where(item => !ids.Contains(item.EntityId)))
{
try
{
_permissions.DeletePermission(permission.PermissionId);
}
catch
{
// multi-threading can cause a race condition to occur
}
}
}
return Themes;
@ -295,6 +335,14 @@ namespace Oqtane.Repository
}
}
}
// default permissions
theme.PermissionList = new List<Permission>
{
new Permission(PermissionNames.Utilize, RoleNames.Admin, true),
new Permission(PermissionNames.Utilize, RoleNames.Registered, true)
};
Debug.WriteLine($"Oqtane Info: Registering Theme {theme.ThemeName}");
themes.Add(theme);
index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
@ -335,5 +383,27 @@ namespace Oqtane.Repository
}
return themes;
}
private List<Permission> ClonePermissions(int siteId, List<Permission> permissionList)
{
var permissions = new List<Permission>();
if (permissionList != null)
{
foreach (var p in permissionList)
{
var permission = new Permission();
permission.SiteId = siteId;
permission.EntityName = p.EntityName;
permission.EntityId = p.EntityId;
permission.PermissionName = p.PermissionName;
permission.RoleId = null;
permission.RoleName = p.RoleName;
permission.UserId = p.UserId;
permission.IsAuthorized = p.IsAuthorized;
permissions.Add(permission);
}
}
return permissions;
}
}
}