using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; using AsbCloudApp.Services; namespace AsbCloudInfrastructure.Services { public class UserRoleService : CrudServiceBase { private readonly CacheTable cacheUserRoles; private readonly IPermissionService permissionService; public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService) : base(context) { cacheUserRoles = cacheDb.GetCachedTable((AsbCloudDbContext)context); this.permissionService = permissionService; } public override async Task> GetPageAsync(int skip = 0, int take = 32, CancellationToken token = default) { var rolesDtos = await base.GetPageAsync(skip, take, token); return rolesDtos; } public override async Task GetAsync(int id, CancellationToken token = default) { var roleDto = await base.GetAsync(id,token); return roleDto; } public override async Task InsertAsync(UserRoleDto dto, CancellationToken token = default) { var id = await base.InsertAsync(dto, token).ConfigureAwait(false); if (dto.Permissions is not null && dto.Permissions.Any()) { foreach (var permission in dto.Permissions) permission.IdUserRole = id; await permissionService.InsertRangeAsync(dto.Permissions, token).ConfigureAwait(false); } return id; } public override async Task UpdateAsync(int id, UserRoleDto item, CancellationToken token = default) { foreach (var p in item.Permissions) p.IdUserRole = item.Id; var result = await base.UpdateAsync(id, item, token); return result; } private IEnumerable GetNestedPermissions(UserRole role, int counter = 10) { List permissions = role.Permissions.ToList(); if (role.IdParent is not null) { if(counter == 0) { Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested childs"); return permissions; } var parentRole = cacheUserRoles.FirstOrDefault(r => r.Id == role.IdParent); if(parentRole is null) return permissions; var parentPermissions = GetNestedPermissions(parentRole, counter--); Merge(ref permissions, parentPermissions); } return permissions; } private static void Merge(ref List permissions, IEnumerable newPermissions) { foreach (var newPermission in newPermissions) { var permissionIndex = permissions.FindIndex(p => p.IdPermission == newPermission.IdPermission); if (permissionIndex == -1) permissions.Add(newPermission); else { var permission = permissions[permissionIndex]; permissions[permissionIndex] = new Permission { IdPermission = permission.IdPermission, IdUserRole = permission.IdUserRole, PermissionValue = permission.PermissionValue | newPermission.PermissionValue, }; } } } } }