Merge pull request #2300 from sbwalker/dev
performance optimization for permissions
This commit is contained in:
commit
c62e6c0045
@ -1,11 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Policy;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace Oqtane.Repository
|
namespace Oqtane.Repository
|
||||||
{
|
{
|
||||||
public interface IPermissionRepository
|
public interface IPermissionRepository
|
||||||
{
|
{
|
||||||
IEnumerable<Permission> GetPermissions(int siteId, string entityName);
|
IEnumerable<Permission> GetPermissions(int siteId, string entityName);
|
||||||
IEnumerable<Permission> GetPermissions(string entityName, int entityId);
|
IEnumerable<Permission> GetPermissions(string entityName, int entityId);
|
||||||
IEnumerable<Permission> GetPermissions(string entityName, int entityId, string permissionName);
|
IEnumerable<Permission> GetPermissions(string entityName, int entityId, string permissionName);
|
||||||
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Oqtane.Extensions;
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Repository
|
namespace Oqtane.Repository
|
||||||
{
|
{
|
||||||
@ -24,7 +25,7 @@ namespace Oqtane.Repository
|
|||||||
.Where(item => item.Module.SiteId == siteId);
|
.Where(item => item.Module.SiteId == siteId);
|
||||||
if (pagemodules.Any())
|
if (pagemodules.Any())
|
||||||
{
|
{
|
||||||
IEnumerable<Permission> permissions = _permissions.GetPermissions(pagemodules.FirstOrDefault().Module.SiteId, "Module").ToList();
|
IEnumerable<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.Module).ToList();
|
||||||
foreach (PageModule pagemodule in pagemodules)
|
foreach (PageModule pagemodule in pagemodules)
|
||||||
{
|
{
|
||||||
pagemodule.Module.Permissions = permissions.Where(item => item.EntityId == pagemodule.ModuleId).EncodePermissions();
|
pagemodule.Module.Permissions = permissions.Where(item => item.EntityId == pagemodule.ModuleId).EncodePermissions();
|
||||||
@ -44,7 +45,8 @@ namespace Oqtane.Repository
|
|||||||
}
|
}
|
||||||
if (pagemodules.Any())
|
if (pagemodules.Any())
|
||||||
{
|
{
|
||||||
IEnumerable<Permission> permissions = _permissions.GetPermissions(pagemodules.FirstOrDefault().Module.SiteId, "Module").ToList();
|
var siteId = pagemodules.FirstOrDefault().Module.SiteId;
|
||||||
|
IEnumerable<Permission> permissions = _permissions.GetPermissions(siteId, EntityNames.Module).ToList();
|
||||||
foreach (PageModule pagemodule in pagemodules)
|
foreach (PageModule pagemodule in pagemodules)
|
||||||
{
|
{
|
||||||
pagemodule.Module.Permissions = permissions.Where(item => item.EntityId == pagemodule.ModuleId).EncodePermissions();
|
pagemodule.Module.Permissions = permissions.Where(item => item.EntityId == pagemodule.ModuleId).EncodePermissions();
|
||||||
@ -87,7 +89,7 @@ namespace Oqtane.Repository
|
|||||||
}
|
}
|
||||||
if (pagemodule != null)
|
if (pagemodule != null)
|
||||||
{
|
{
|
||||||
pagemodule.Module.Permissions = _permissions.GetPermissionString("Module", pagemodule.ModuleId);
|
pagemodule.Module.Permissions = _permissions.GetPermissionString(EntityNames.Module, pagemodule.ModuleId);
|
||||||
}
|
}
|
||||||
return pagemodule;
|
return pagemodule;
|
||||||
}
|
}
|
||||||
@ -98,7 +100,7 @@ namespace Oqtane.Repository
|
|||||||
.SingleOrDefault(item => item.PageId == pageId && item.ModuleId == moduleId);
|
.SingleOrDefault(item => item.PageId == pageId && item.ModuleId == moduleId);
|
||||||
if (pagemodule != null)
|
if (pagemodule != null)
|
||||||
{
|
{
|
||||||
pagemodule.Module.Permissions = _permissions.GetPermissionString("Module", pagemodule.ModuleId);
|
pagemodule.Module.Permissions = _permissions.GetPermissionString(EntityNames.Module, pagemodule.ModuleId);
|
||||||
}
|
}
|
||||||
return pagemodule;
|
return pagemodule;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Oqtane.Extensions;
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
namespace Oqtane.Repository
|
namespace Oqtane.Repository
|
||||||
{
|
{
|
||||||
@ -13,33 +15,49 @@ namespace Oqtane.Repository
|
|||||||
{
|
{
|
||||||
private TenantDBContext _db;
|
private TenantDBContext _db;
|
||||||
private readonly IRoleRepository _roles;
|
private readonly IRoleRepository _roles;
|
||||||
|
private readonly IMemoryCache _cache;
|
||||||
|
private readonly IHttpContextAccessor _accessor;
|
||||||
|
|
||||||
public PermissionRepository(TenantDBContext context, IRoleRepository roles)
|
public PermissionRepository(TenantDBContext context, IRoleRepository roles, IMemoryCache cache, IHttpContextAccessor accessor)
|
||||||
{
|
{
|
||||||
_db = context;
|
_db = context;
|
||||||
_roles = roles;
|
_roles = roles;
|
||||||
|
_cache = cache;
|
||||||
|
_accessor = accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Permission> GetPermissions(int siteId, string entityName)
|
public IEnumerable<Permission> GetPermissions(int siteId, string entityName)
|
||||||
{
|
{
|
||||||
return _db.Permission.Where(item => item.SiteId == siteId)
|
var alias = _accessor.HttpContext.GetAlias();
|
||||||
.Where(item => item.EntityName == entityName)
|
if (alias != null)
|
||||||
.Include(item => item.Role); // eager load roles
|
{
|
||||||
|
return _cache.GetOrCreate($"permissions:{alias.SiteKey}:{entityName}", entry =>
|
||||||
|
{
|
||||||
|
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||||
|
return _db.Permission.Where(item => item.SiteId == alias.SiteId)
|
||||||
|
.Where(item => item.EntityName == entityName)
|
||||||
|
.Include(item => item.Role).ToList(); // eager load roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _db.Permission.Where(item => item.SiteId == siteId || siteId == -1)
|
||||||
|
.Where(item => item.EntityName == entityName)
|
||||||
|
.Include(item => item.Role).ToList(); // eager load roles
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Permission> GetPermissions(string entityName, int entityId)
|
public IEnumerable<Permission> GetPermissions(string entityName, int entityId)
|
||||||
{
|
{
|
||||||
return _db.Permission.Where(item => item.EntityName == entityName)
|
var permissions = GetPermissions(-1, entityName);
|
||||||
.Where(item => item.EntityId == entityId)
|
return permissions.Where(item => item.EntityId == entityId);
|
||||||
.Include(item => item.Role); // eager load roles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Permission> GetPermissions(string entityName, int entityId, string permissionName)
|
public IEnumerable<Permission> GetPermissions(string entityName, int entityId, string permissionName)
|
||||||
{
|
{
|
||||||
return _db.Permission.Where(item => item.EntityName == entityName)
|
var permissions = GetPermissions(-1, entityName);
|
||||||
.Where(item => item.EntityId == entityId)
|
return permissions.Where(item => item.EntityId == entityId)
|
||||||
.Where(item => item.PermissionName == permissionName)
|
.Where(item => item.PermissionName == permissionName);
|
||||||
.Include(item => item.Role); // eager load roles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetPermissionString(int siteId, string entityName)
|
public string GetPermissionString(int siteId, string entityName)
|
||||||
@ -62,6 +80,7 @@ namespace Oqtane.Repository
|
|||||||
{
|
{
|
||||||
_db.Permission.Add(permission);
|
_db.Permission.Add(permission);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(permission.EntityName);
|
||||||
return permission;
|
return permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +88,7 @@ namespace Oqtane.Repository
|
|||||||
{
|
{
|
||||||
_db.Entry(permission).State = EntityState.Modified;
|
_db.Entry(permission).State = EntityState.Modified;
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(permission.EntityName);
|
||||||
return permission;
|
return permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +110,7 @@ namespace Oqtane.Repository
|
|||||||
_db.Permission.Add(permission);
|
_db.Permission.Add(permission);
|
||||||
}
|
}
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(entityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Permission GetPermission(int permissionId)
|
public Permission GetPermission(int permissionId)
|
||||||
@ -102,6 +123,7 @@ namespace Oqtane.Repository
|
|||||||
Permission permission = _db.Permission.Find(permissionId);
|
Permission permission = _db.Permission.Find(permissionId);
|
||||||
_db.Permission.Remove(permission);
|
_db.Permission.Remove(permission);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(permission.EntityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeletePermissions(int siteId, string entityName, int entityId)
|
public void DeletePermissions(int siteId, string entityName, int entityId)
|
||||||
@ -115,6 +137,16 @@ namespace Oqtane.Repository
|
|||||||
_db.Permission.Remove(permission);
|
_db.Permission.Remove(permission);
|
||||||
}
|
}
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
ClearCache(entityName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearCache(string entityName)
|
||||||
|
{
|
||||||
|
var alias = _accessor.HttpContext.GetAlias();
|
||||||
|
if (alias != null)
|
||||||
|
{
|
||||||
|
_cache.Remove($"permissions:{alias.SiteKey}:{entityName}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// permissions are stored in the format "{permissionname:!rolename1;![userid1];rolename2;rolename3;[userid2];[userid3]}" where "!" designates Deny permissions
|
// permissions are stored in the format "{permissionname:!rolename1;![userid1];rolename2;rolename3;[userid2];[userid3]}" where "!" designates Deny permissions
|
||||||
|
Reference in New Issue
Block a user