2021-12-02 13:35:15 +05:00
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Collections.Generic;
|
2021-11-29 12:39:28 +05:00
|
|
|
using System.Linq;
|
2021-11-24 17:38:40 +05:00
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using AsbCloudApp.Data;
|
|
|
|
using AsbCloudDb.Model;
|
|
|
|
using AsbCloudInfrastructure.Services.Cache;
|
|
|
|
using Mapster;
|
2021-12-03 09:44:10 +05:00
|
|
|
using AsbCloudApp.Services;
|
2021-12-11 16:46:04 +05:00
|
|
|
using System;
|
2021-11-24 17:38:40 +05:00
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
|
|
{
|
2021-12-03 15:03:33 +05:00
|
|
|
public class UserRoleService : IUserRoleService
|
2021-11-24 17:38:40 +05:00
|
|
|
{
|
|
|
|
private readonly CacheTable<UserRole> cacheUserRoles;
|
2021-12-15 16:21:52 +05:00
|
|
|
private readonly CacheTable<Permission> cachePermission;
|
2021-12-03 09:44:10 +05:00
|
|
|
private readonly IPermissionService permissionService;
|
2021-12-07 18:27:52 +05:00
|
|
|
public List<string> Includes { get; } = new();
|
2021-12-03 15:03:33 +05:00
|
|
|
|
|
|
|
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService)
|
2021-11-24 17:38:40 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, new [] { nameof(UserRole.RelationUserRolePermissions) });
|
|
|
|
cachePermission = cacheDb.GetCachedTable<Permission>((AsbCloudDbContext)context);
|
2021-12-03 09:44:10 +05:00
|
|
|
this.permissionService = permissionService;
|
2021-11-24 17:38:40 +05:00
|
|
|
}
|
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
|
|
|
{
|
|
|
|
var entity = dto.Adapt<UserRole>();
|
|
|
|
var updatedEntity = await cacheUserRoles.InsertAsync(entity, token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
await UpdatePermissionsAsync(dto, token);
|
|
|
|
await cacheUserRoles.RefreshAsync(true, token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
return updatedEntity?.Id ?? 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Task<int> InsertRangeAsync(IEnumerable<UserRoleDto> dtos, CancellationToken token = default)
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
//var entities = dtos.Adapt<UserRole>();
|
|
|
|
//return await cacheUserRoles.InsertAsync(entities, token).ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
|
2021-12-03 15:03:33 +05:00
|
|
|
public async Task<IEnumerable<UserRoleDto>> GetAllAsync(CancellationToken token = default)
|
2021-11-24 17:38:40 +05:00
|
|
|
{
|
2021-12-03 15:03:33 +05:00
|
|
|
var entities = await cacheUserRoles.WhereAsync(token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
var dtos = entities.Adapt<UserRoleDto>();
|
|
|
|
return dtos;
|
2021-11-24 17:38:40 +05:00
|
|
|
}
|
|
|
|
|
2021-12-03 15:03:33 +05:00
|
|
|
public async Task<UserRoleDto> GetAsync(int id, CancellationToken token = default)
|
2021-11-24 17:38:40 +05:00
|
|
|
{
|
2021-12-03 15:03:33 +05:00
|
|
|
var entity = await cacheUserRoles.FirstOrDefaultAsync(r=>r.Id == id, token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
var dto = entity?.Adapt<UserRoleDto>();
|
|
|
|
return dto;
|
2021-11-24 17:38:40 +05:00
|
|
|
}
|
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
public async Task<UserRoleDto> GetByNameAsync(string name, CancellationToken token = default)
|
2021-12-02 13:35:15 +05:00
|
|
|
{
|
2021-12-11 16:46:04 +05:00
|
|
|
var entity = await cacheUserRoles.FirstOrDefaultAsync(r => r.Caption == name, token)
|
2021-12-07 18:27:52 +05:00
|
|
|
.ConfigureAwait(false);
|
2021-12-11 16:46:04 +05:00
|
|
|
var dto = entity?.Adapt<UserRoleDto>();
|
|
|
|
return dto;
|
2021-12-03 15:03:33 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<int> UpdateAsync(int id, UserRoleDto dto, CancellationToken token = default)
|
|
|
|
{
|
2021-12-11 16:46:04 +05:00
|
|
|
dto.Id = id;
|
2021-12-03 15:03:33 +05:00
|
|
|
var entity = dto.Adapt<UserRole>();
|
2021-12-11 16:46:04 +05:00
|
|
|
await UpdatePermissionsAsync(dto, token);
|
|
|
|
|
2021-12-03 15:03:33 +05:00
|
|
|
await cacheUserRoles.UpsertAsync(entity, token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
return id;
|
|
|
|
}
|
2021-12-03 15:03:33 +05:00
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
public List<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
|
|
|
|
{
|
|
|
|
var role = cacheUserRoles.FirstOrDefault(r => r.Id == id);
|
|
|
|
if (role is null)
|
|
|
|
return null;
|
|
|
|
var dto = role.Adapt<UserRoleDto>();
|
|
|
|
if (role.IdParent is null || recursionLevel == 0)
|
|
|
|
return new List<UserRoleDto> { dto };
|
|
|
|
var parentRoles = GetNestedById((int)role.IdParent, --recursionLevel) ??
|
|
|
|
new List<UserRoleDto>();
|
|
|
|
parentRoles.Add(dto);
|
|
|
|
return parentRoles;
|
|
|
|
}
|
2021-12-03 15:03:33 +05:00
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
public IEnumerable<PermissionBaseDto> GetNestedPermissions(IEnumerable<UserRoleDto> roles)
|
|
|
|
{
|
|
|
|
var permissions = new Dictionary<int, PermissionBaseDto>(16);
|
|
|
|
foreach (var roleDto in roles)
|
|
|
|
{
|
|
|
|
var role = cacheUserRoles.FirstOrDefault(r => r.Id == roleDto.Id);
|
|
|
|
var rolePermissions = GetNestedPermissions(role, 10);
|
|
|
|
if ((rolePermissions?.Any()) != true)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
foreach (var newPermission in rolePermissions)
|
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
if (permissions.ContainsKey(newPermission.Id))
|
2021-12-11 16:46:04 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
permissions[newPermission.Id] = newPermission.Adapt<PermissionBaseDto>();
|
2021-12-11 16:46:04 +05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
permissions.Add(newPermission.Id,
|
2021-12-11 16:46:04 +05:00
|
|
|
new PermissionBaseDto
|
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
Id = newPermission.Id,
|
2021-12-16 16:00:47 +05:00
|
|
|
Name = newPermission.Name ??
|
2021-12-15 16:21:52 +05:00
|
|
|
cachePermission.FirstOrDefault(p => p.Id == newPermission.Id).Name
|
2021-12-11 16:46:04 +05:00
|
|
|
});
|
|
|
|
}
|
2021-12-03 15:03:33 +05:00
|
|
|
}
|
|
|
|
}
|
2021-11-24 17:38:40 +05:00
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
return permissions.Values;
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task UpdatePermissionsAsync(UserRoleDto roleDto, CancellationToken token)
|
|
|
|
{
|
|
|
|
await permissionService.DeleteAllByRoleAsync(roleDto.Id, token)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
if (!roleDto.Permissions.Any())
|
|
|
|
return;
|
|
|
|
|
|
|
|
var newPermissions = roleDto.Permissions.Select(p => new PermissionDto
|
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
Id = p.Id,
|
2021-12-11 16:46:04 +05:00
|
|
|
IdUserRole = roleDto.Id,
|
2021-12-16 16:00:47 +05:00
|
|
|
Name = p.Name
|
2021-12-11 16:46:04 +05:00
|
|
|
});
|
|
|
|
|
|
|
|
await permissionService.InsertRangeAsync(newPermissions, token)
|
|
|
|
.ConfigureAwait(false);
|
2021-11-29 12:39:28 +05:00
|
|
|
}
|
2021-11-26 17:05:41 +05:00
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
private IEnumerable<Permission> GetNestedPermissions(UserRole role, int recursionLevel = 7)
|
2021-11-29 12:39:28 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
var permissionRelations = role.RelationUserRolePermissions.ToList();
|
|
|
|
var permissionIds = permissionRelations.Select(p => p.IdPermission);
|
2021-12-07 18:27:52 +05:00
|
|
|
if (role.IdParent is null)
|
2021-12-15 16:21:52 +05:00
|
|
|
return cachePermission.Where(c => permissionIds.Contains(c.Id));
|
2021-12-11 16:46:04 +05:00
|
|
|
if (recursionLevel == 0)
|
2021-12-03 09:44:10 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested children");
|
|
|
|
cachePermission.Where(c => permissionIds.Contains(c.Id));
|
2021-12-07 18:27:52 +05:00
|
|
|
}
|
|
|
|
var parentRole = cacheUserRoles.FirstOrDefault(r => r.Id == role.IdParent);
|
2021-12-03 15:03:33 +05:00
|
|
|
|
2021-12-07 18:27:52 +05:00
|
|
|
if (parentRole is null)
|
2021-12-15 16:21:52 +05:00
|
|
|
return cachePermission.Where(c => permissionIds.Contains(c.Id));
|
2021-12-03 09:44:10 +05:00
|
|
|
|
2021-12-11 16:46:04 +05:00
|
|
|
var parentPermissions = GetNestedPermissions(parentRole, --recursionLevel);
|
|
|
|
|
2021-12-15 16:21:52 +05:00
|
|
|
return cachePermission.Where(c => permissionIds.Contains(c.Id)).Union(parentPermissions);
|
2021-12-02 13:35:15 +05:00
|
|
|
}
|
2021-12-03 15:03:33 +05:00
|
|
|
|
|
|
|
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
|
|
|
=> cacheUserRoles.RemoveAsync(r => r.Id == id, token);
|
|
|
|
|
|
|
|
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
|
|
|
=> cacheUserRoles.RemoveAsync(r => ids.Contains(r.Id), token);
|
2021-12-11 16:46:04 +05:00
|
|
|
|
2021-12-16 16:00:47 +05:00
|
|
|
public bool HasPermission(IEnumerable<int> rolesIds, string permissionName)
|
2021-12-11 16:46:04 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
var permissionInfo = cachePermission.FirstOrDefault(p => p.Name.ToLower() == permissionName.ToLower());
|
2021-12-11 16:46:04 +05:00
|
|
|
|
|
|
|
if (permissionInfo is null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
var idPermissionInfo = permissionInfo.Id;
|
|
|
|
var roles = cacheUserRoles.Where(r => rolesIds.Contains(r.Id));
|
|
|
|
foreach (var role in roles)
|
2021-12-16 16:00:47 +05:00
|
|
|
if (HasPermission(role, idPermissionInfo))
|
2021-12-11 16:46:04 +05:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-12-15 16:21:52 +05:00
|
|
|
private bool HasPermission(UserRole userRole, int idPermission, int recursionLevel = 7)
|
2021-12-11 16:46:04 +05:00
|
|
|
{
|
2021-12-15 16:21:52 +05:00
|
|
|
if (userRole.RelationUserRolePermissions.Any(p => p.IdPermission == idPermission))
|
2021-12-11 16:46:04 +05:00
|
|
|
return true;
|
|
|
|
if (userRole.IdParent is not null && recursionLevel > 0)
|
|
|
|
{
|
|
|
|
var parentRole = cacheUserRoles.FirstOrDefault(p => p.Id == userRole.IdParent);
|
2021-12-15 16:21:52 +05:00
|
|
|
return HasPermission(parentRole, idPermission, --recursionLevel);
|
2021-12-11 16:46:04 +05:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2021-11-24 17:38:40 +05:00
|
|
|
}
|
|
|
|
}
|