Protect distribution APIs with permissions and scope checks

This commit is contained in:
2026-08-18 15:44:10 +05:30
parent be51351f74
commit 42f709d6ee
8 changed files with 99 additions and 12 deletions
+25 -6
View File
@@ -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
{