diff --git a/src/api/Areas/Dashboard/Controllers/OperatingSystemItemController.cs b/src/api/Areas/Dashboard/Controllers/OperatingSystemItemController.cs
index 2bb32493..ea08a45b 100644
--- a/src/api/Areas/Dashboard/Controllers/OperatingSystemItemController.cs
+++ b/src/api/Areas/Dashboard/Controllers/OperatingSystemItemController.cs
@@ -55,7 +55,6 @@ public OperatingSystemItemController(
#endregion
#region Endpoints
- // TODO: Limit based on role and tenant.
///
///
///
@@ -64,6 +63,7 @@ public OperatingSystemItemController(
[Produces(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
[SwaggerOperation(Tags = new[] { "Operating System Item" })]
+ [ResponseCache(VaryByQueryKeys = new[] { "*" }, Location = ResponseCacheLocation.Client, Duration = 60)]
public IActionResult Find()
{
var uri = new Uri(this.Request.GetDisplayUrl());
@@ -87,7 +87,6 @@ public IActionResult Find()
}
}
- // TODO: Limit based on role and tenant.
///
///
///
diff --git a/src/api/Areas/Dashboard/Controllers/OrganizationController.cs b/src/api/Areas/Dashboard/Controllers/OrganizationController.cs
index a699df48..8cdaa7dd 100644
--- a/src/api/Areas/Dashboard/Controllers/OrganizationController.cs
+++ b/src/api/Areas/Dashboard/Controllers/OrganizationController.cs
@@ -51,15 +51,16 @@ public OrganizationController(
#endregion
#region Endpoints
- // TODO: Limit based on role and tenant.
///
- ///
+ /// Find all organizations that match the specified query filter.
+ /// Only returns organizations the current user has access to.
///
///
[HttpGet(Name = "GetOrganizations-Dashboard")]
[Produces(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
[SwaggerOperation(Tags = new[] { "Organization" })]
+ [ResponseCache(VaryByQueryKeys = new[] { "*" }, Location = ResponseCacheLocation.Client, Duration = 60)]
public IActionResult Find()
{
var uri = new Uri(this.Request.GetDisplayUrl());
@@ -69,7 +70,7 @@ public IActionResult Find()
var isHSB = this.User.HasClientRole(ClientRole.HSB);
if (isHSB)
{
- var result = _service.Find(filter.GeneratePredicate(), filter.Sort);
+ var result = _service.Find(filter);
return new JsonResult(result.Select(o => new OrganizationModel(o)));
}
else
@@ -78,14 +79,13 @@ public IActionResult Find()
var user = _authorization.GetUser();
if (user == null) return Forbid();
- var result = _service.FindForUser(user.Id, filter.GeneratePredicate(), filter.Sort);
+ var result = _service.FindForUser(user.Id, filter);
return new JsonResult(result.Select(o => new OrganizationModel(o)));
}
}
- // TODO: Limit based on role and tenant.
///
- ///
+ /// Get the organization for the specified 'id'.
///
///
///
@@ -109,7 +109,7 @@ public IActionResult GetForId(int id)
var user = _authorization.GetUser();
if (user == null) return Forbid();
- var entity = _service.FindForUser(user.Id, (o) => o.Id == id, o => o.Id).FirstOrDefault();
+ var entity = _service.FindForUser(user.Id, new HSB.Models.Filters.OrganizationFilter() { Id = id }).FirstOrDefault();
if (entity == null) return Forbid();
return new JsonResult(new OrganizationModel(entity));
}
diff --git a/src/api/Areas/Dashboard/Controllers/ServerItemController.cs b/src/api/Areas/Dashboard/Controllers/ServerItemController.cs
index f605bf79..7d4cf905 100644
--- a/src/api/Areas/Dashboard/Controllers/ServerItemController.cs
+++ b/src/api/Areas/Dashboard/Controllers/ServerItemController.cs
@@ -67,6 +67,7 @@ public ServerItemController(
[Produces(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
[SwaggerOperation(Tags = new[] { "Server Item" })]
+ [ResponseCache(VaryByQueryKeys = new[] { "*" }, Location = ResponseCacheLocation.Client, Duration = 60)]
public IActionResult Find()
{
var uri = new Uri(this.Request.GetDisplayUrl());
diff --git a/src/api/Areas/Dashboard/Controllers/TenantController.cs b/src/api/Areas/Dashboard/Controllers/TenantController.cs
index 6698a1c0..a857de41 100644
--- a/src/api/Areas/Dashboard/Controllers/TenantController.cs
+++ b/src/api/Areas/Dashboard/Controllers/TenantController.cs
@@ -51,7 +51,6 @@ public TenantController(
#endregion
#region Endpoints
- // TODO: Limit based on role and tenant.
///
///
///
@@ -60,6 +59,7 @@ public TenantController(
[Produces(MediaTypeNames.Application.Json)]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
[SwaggerOperation(Tags = new[] { "Tenant" })]
+ [ResponseCache(VaryByQueryKeys = new[] { "*" }, Location = ResponseCacheLocation.Client, Duration = 60)]
public IActionResult Find()
{
var uri = new Uri(this.Request.GetDisplayUrl());
@@ -83,7 +83,6 @@ public IActionResult Find()
}
}
- // TODO: Limit based on role and tenant.
///
///
///
diff --git a/src/api/Program.cs b/src/api/Program.cs
index 6d2734a9..d9993941 100644
--- a/src/api/Program.cs
+++ b/src/api/Program.cs
@@ -72,7 +72,8 @@ public static void Main(string[] args)
.AllowAnyMethod(); ;
});
}
- });
+ })
+ .AddResponseCaching();
var app = builder.Build();
@@ -93,6 +94,7 @@ public static void Main(string[] args)
app.UseCors("CorsPolicy");
app.UseMiddleware(typeof(LogRequestMiddleware));
+ app.UseResponseCaching();
app.UseAuthentication();
app.UseAuthorization();
diff --git a/src/libs/dal/Services/IOrganizationService.cs b/src/libs/dal/Services/IOrganizationService.cs
index bb7358f6..6222e667 100644
--- a/src/libs/dal/Services/IOrganizationService.cs
+++ b/src/libs/dal/Services/IOrganizationService.cs
@@ -4,17 +4,10 @@ namespace HSB.DAL.Services;
public interface IOrganizationService : IBaseService
{
- IEnumerable FindForUser(
- long userId,
- System.Linq.Expressions.Expression> predicate,
- System.Linq.Expressions.Expression>? sort = null,
- int? take = null,
- int? skip = null);
+ IEnumerable Find(
+ Models.Filters.OrganizationFilter filter);
- public IEnumerable FindForUser(
+ IEnumerable FindForUser(
long userId,
- System.Linq.Expressions.Expression> predicate,
- string[] sort,
- int? take = null,
- int? skip = null);
+ Models.Filters.OrganizationFilter filter);
}
diff --git a/src/libs/dal/Services/OrganizationService.cs b/src/libs/dal/Services/OrganizationService.cs
index c34d63d1..b9e946d4 100644
--- a/src/libs/dal/Services/OrganizationService.cs
+++ b/src/libs/dal/Services/OrganizationService.cs
@@ -18,26 +18,21 @@ public OrganizationService(HSBContext dbContext, ClaimsPrincipal principal, ISer
#endregion
#region Methods
- public IEnumerable FindForUser(
- long userId,
- System.Linq.Expressions.Expression> predicate,
- System.Linq.Expressions.Expression>? sort = null,
- int? take = null,
- int? skip = null)
+ public IEnumerable Find(
+ Models.Filters.OrganizationFilter filter)
{
var query = (from org in this.Context.Organizations
- join uo in this.Context.UserOrganizations on org.Id equals uo.OrganizationId
- where uo.UserId == userId
select org)
- .Where(predicate)
+ .Where(filter.GeneratePredicate())
.Distinct();
- if (sort != null)
- query = query.OrderBy(sort);
- if (take.HasValue)
- query = query.Take(take.Value);
- if (skip.HasValue)
- query = query.Skip(skip.Value);
+ if (filter.Sort?.Any() == true)
+ query = query.OrderByProperty(filter.Sort);
+ else query = query.OrderBy(si => si.Name);
+ if (filter.Quantity.HasValue)
+ query = query.Take(filter.Quantity.Value);
+ if (filter.Page.HasValue && filter.Quantity.HasValue && filter.Page > 1)
+ query = query.Skip(filter.Page.Value * filter.Quantity.Value);
return query
.AsNoTracking()
@@ -46,25 +41,29 @@ join uo in this.Context.UserOrganizations on org.Id equals uo.OrganizationId
public IEnumerable FindForUser(
long userId,
- System.Linq.Expressions.Expression> predicate,
- string[] sort,
- int? take = null,
- int? skip = null)
+ Models.Filters.OrganizationFilter filter)
{
+ var userOrganizationQuery = from uo in this.Context.UserOrganizations
+ where uo.UserId == userId
+ select uo.OrganizationId;
+ var tenantOrganizationQuery = from tOrg in this.Context.TenantOrganizations
+ join ut in this.Context.UserTenants on tOrg.TenantId equals ut.TenantId
+ where ut.UserId == userId
+ select tOrg.OrganizationId;
var query = (from org in this.Context.Organizations
- join uo in this.Context.UserOrganizations on org.Id equals uo.OrganizationId
- where uo.UserId == userId
+ where userOrganizationQuery.Contains(org.Id) || tenantOrganizationQuery.Contains(org.Id)
select org)
- .Where(predicate)
+ .Where(filter.GeneratePredicate())
.Distinct();
- if (sort?.Any() == true)
- query = query.OrderByProperty(sort);
- if (take.HasValue)
- query = query.Take(take.Value);
- if (skip.HasValue)
- query = query.Skip(skip.Value);
+ if (filter.Sort?.Any() == true)
+ query = query.OrderByProperty(filter.Sort);
+ else query = query.OrderBy(si => si.Name);
+ if (filter.Quantity.HasValue)
+ query = query.Take(filter.Quantity.Value);
+ if (filter.Page.HasValue && filter.Quantity.HasValue && filter.Page > 1)
+ query = query.Skip(filter.Page.Value * filter.Quantity.Value);
return query
.AsNoTracking()
diff --git a/src/libs/dal/Services/TenantService.cs b/src/libs/dal/Services/TenantService.cs
index 5c2ba1a7..05955944 100644
--- a/src/libs/dal/Services/TenantService.cs
+++ b/src/libs/dal/Services/TenantService.cs
@@ -5,7 +5,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using HSB.DAL.Extensions;
-using System.Linq.Expressions;
namespace HSB.DAL.Services;
@@ -27,8 +26,8 @@ public IEnumerable FindForUser(
int? skip = null)
{
var query = (from t in this.Context.Tenants
- join usert in this.Context.UserTenants on t.Id equals usert.TenantId
- where usert.UserId == userId
+ join ut in this.Context.UserTenants on t.Id equals ut.TenantId
+ where ut.UserId == userId
select t)
.Where(predicate);
@@ -52,8 +51,8 @@ public IEnumerable FindForUser(
int? skip = null)
{
var query = (from t in this.Context.Tenants
- join usert in this.Context.UserTenants on t.Id equals usert.TenantId
- where usert.UserId == userId
+ join ut in this.Context.UserTenants on t.Id equals ut.TenantId
+ where ut.UserId == userId
select t)
.Where(predicate);
diff --git a/src/libs/models/Filters/OrganizationFilter.cs b/src/libs/models/Filters/OrganizationFilter.cs
index a3e47fe0..905d9884 100644
--- a/src/libs/models/Filters/OrganizationFilter.cs
+++ b/src/libs/models/Filters/OrganizationFilter.cs
@@ -7,6 +7,7 @@ namespace HSB.Models.Filters;
public class OrganizationFilter : PageFilter
{
#region Properties
+ public int? Id { get; set; }
public string? Name { get; set; }
public bool? IsEnabled { get; set; }
@@ -29,6 +30,7 @@ public OrganizationFilter(Dictionary(queryParams, StringComparer.OrdinalIgnoreCase);
+ this.Id = filter.GetIntNullValue(nameof(this.Id));
this.Name = filter.GetStringValue(nameof(this.Name));
this.IsEnabled = filter.GetBoolNullValue(nameof(this.IsEnabled));
this.ServiceNowKey = filter.GetStringValue(nameof(this.ServiceNowKey));
@@ -45,6 +47,8 @@ public OrganizationFilter(Dictionary GeneratePredicate()
{
var predicate = PredicateBuilder.New();
+ if (this.Id != null)
+ predicate = predicate.And((u) => u.Id == this.Id);
if (this.Name != null)
predicate = predicate.And((u) => EF.Functions.Like(u.Name, $"%{this.Name}%"));
if (this.IsEnabled != null)