Protect distribution APIs with permissions and scope checks
This commit is contained in:
@@ -1,22 +1,39 @@
|
||||
using Distribution.Infra.Auth;
|
||||
using Distribution.Infra.UoW;
|
||||
|
||||
namespace Distribution.Features.Store;
|
||||
|
||||
public class StoreService(IStoreRepository repo, IUnitOfWork uow)
|
||||
public class StoreService(IStoreRepository repo, IUnitOfWork uow, ICurrentUserService currentUser, IScopeAccessService scopeAccess)
|
||||
{
|
||||
private const int GlobalScopeRoleLevel = 50;
|
||||
|
||||
private static StoreResponse ToResponse(Models.Store s) =>
|
||||
new(s.Id, s.OwnerName, s.StoreName, s.StoreAddress, s.Latitude, s.Longitude, s.OneTimeAmount, s.CreditAmount, s.IsActive, s.CreatedAt);
|
||||
|
||||
public async Task<List<StoreResponse>> GetAllAsync() =>
|
||||
(await repo.GetAllAsync())
|
||||
.Where(s => s.IsActive)
|
||||
.Select(ToResponse)
|
||||
.ToList();
|
||||
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
|
||||
|
||||
private async Task<bool> HasStoreScopeAsync(Guid storeId)
|
||||
{
|
||||
if (HasGlobalScope || currentUser.UserId is null) return HasGlobalScope;
|
||||
return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId);
|
||||
}
|
||||
|
||||
public async Task<List<StoreResponse>> GetAllAsync()
|
||||
{
|
||||
var stores = (await repo.GetAllAsync()).Where(s => s.IsActive).ToList();
|
||||
if (!HasGlobalScope && currentUser.UserId is not null)
|
||||
{
|
||||
var accessibleStoreIds = (await scopeAccess.GetAccessibleStoreIdsAsync(currentUser.UserId.Value)).ToHashSet();
|
||||
stores = stores.Where(s => accessibleStoreIds.Contains(s.Id)).ToList();
|
||||
}
|
||||
return stores.Select(ToResponse).ToList();
|
||||
}
|
||||
|
||||
public async Task<StoreResponse?> GetByIdAsync(Guid id)
|
||||
{
|
||||
var store = await repo.GetByIdAsync(id);
|
||||
if (store is null || !store.IsActive) return null;
|
||||
if (!await HasStoreScopeAsync(id)) return null;
|
||||
return ToResponse(store);
|
||||
}
|
||||
|
||||
@@ -50,6 +67,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow)
|
||||
{
|
||||
var store = await repo.GetByIdAsync(id);
|
||||
if (store is null || !store.IsActive) return null;
|
||||
if (!await HasStoreScopeAsync(id)) return null;
|
||||
store.OwnerName = request.OwnerName;
|
||||
store.StoreName = request.StoreName;
|
||||
store.StoreAddress = request.StoreAddress;
|
||||
@@ -75,6 +93,7 @@ public class StoreService(IStoreRepository repo, IUnitOfWork uow)
|
||||
{
|
||||
var store = await repo.GetByIdAsync(id);
|
||||
if (store is null || !store.IsActive) return false;
|
||||
if (!await HasStoreScopeAsync(id)) return false;
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user