Fast Question: How to rewrite this
builder.Entity<User>().HasQueryFilter(s =>
httpContextAccessor.HttpContext.User.GetGroup() == s.Institute ||
httpContextAccessor.HttpContext.User.IsInRole(ERole.Root.ToString()));
from model builder layer to bussines and logic layer with all includes.
Description and problem itself:
I have this interface
public interface IInstituteEntity
{
public string Institute { get; set; }
}
And I want to get all entities from database where entity itself or ANY of it's properties(recursive: childs of childs) has Institute property that equals my filter OR user has role "Root" (notice that properties can not be included and can be empty/null as well)
I'm not strong with Expression Trees and can not find suitable solution, I have basic example without recursion:
public static IQueryable<T> HasInstituteAccess<T>(this IQueryable<T> entities,
IHttpContextAccessor accessor) where T : IInstituteEntity
{
var user = accessor.HttpContext?.User;
if (user is null) return Enumerable.Empty<T>().AsQueryable();
return user.IsInRole(ERole.Root.ToString())
? entities.Cast<T>()
: entities.Where(HasInstituteAccessFilter<T>(user)).Cast<T>();
}
private static Expression<Func<T, bool>> HasInstituteAccessFilter<T>(ClaimsPrincipal principal)
where T : IInstituteEntity
=> arg => principal.GetGroup() == arg.Institute;
I need it as workload about global filters that covers includes, that's the thing:
builder.Entity<User>().HasQueryFilter(s =>
httpContextAccessor.HttpContext.User.GetGroup() == s.Institute ||
httpContextAccessor.HttpContext.User.IsInRole(ERole.Root.ToString()));
But it not suits me because I need to manualy specify IgnoreQueryFilters() for all queries that have no need in this logic, so it's better to write in manually via extensions above
Expected query:
var userInfo =
await context.UserInfo.AsNoTracking()
.Where(ui => !ui.IsDeleted)
.Include(ui => ui.User)
.HasInstituteAccess(accessor)
.FirstOrDefaultAsync(ui => ui.Id == request.Id, cancellationToken);
Expected result: return some info if authorized user has access to ui.User.Institute (UserInfo has no institute property)
Aucun commentaire:
Enregistrer un commentaire