DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/UserService.cs

194 lines
7.1 KiB
C#
Raw Normal View History

using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class UserService : IUserService
{
private readonly CacheTable<User> cacheUsers;
private readonly CacheTable<RelationUserUserRole> cacheRelationUserToRoles;
2021-12-22 11:41:18 +05:00
public ISet<string> Includes { get; } = new SortedSet<string>();
public IUserRoleService RoleService { get; }
private static readonly TypeAdapterConfig userTypeAdapterConfig = TypeAdapterConfig<UserExtendedDto, User>
.NewConfig()
.Ignore(dst => dst.Company,
dst => dst.FileMarks,
dst => dst.Files,
dst => dst.RelationUsersUserRoles)
.Config;
public UserService(IAsbCloudDbContext context, CacheDb cacheDb, IUserRoleService roleService)
{
var db = (AsbCloudDbContext)context;
cacheUsers = cacheDb.GetCachedTable<User>(
db,
new[] {
nameof(User.RelationUsersUserRoles),
nameof(User.Company),
});
cacheRelationUserToRoles = cacheDb.GetCachedTable<RelationUserUserRole>(
db,
new[] {
nameof(RelationUserUserRole.User),
nameof(RelationUserUserRole.UserRole),
});
RoleService = roleService;
}
public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token = default)
{
var entity = Convert(dto);
var updatedEntity = await cacheUsers.InsertAsync(entity, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync((int)updatedEntity.Id, dto.RoleNames, token);
return updatedEntity?.Id ?? 0;
}
public Task<int> InsertRangeAsync(IEnumerable<UserExtendedDto> newItems, CancellationToken token = default)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token = default)
{
var entities = (await cacheUsers.WhereAsync(token).ConfigureAwait(false))
.ToList();
if (entities.Count == 0)
return null;
var dtos = entities.Select(Convert).ToList();
for (var i = 0; i < dtos.Count; i++)
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
return dtos;
}
public async Task<UserExtendedDto> GetAsync(int id, CancellationToken token = default)
{
var entity = await cacheUsers.FirstOrDefaultAsync(u=>u.Id == id, token).ConfigureAwait(false);
var dto = Convert(entity);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
public async Task<int> UpdateAsync(int id, UserExtendedDto dto, CancellationToken token = default)
{
var entity = Convert(dto);
await UpdateRolesCacheForUserAsync(id, dto.RoleNames, token);
var result = await cacheUsers.UpsertAsync(entity, token)
.ConfigureAwait(false);
return result;
}
public Task<int> DeleteAsync(int id, CancellationToken token = default)
=> cacheUsers.RemoveAsync(r => r.Id == id, token);
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
=> cacheUsers.RemoveAsync(r => ids.Contains(r.Id), token);
private IEnumerable<string> GetRolesNamesByIdUser(int idUser)
=> GetRolesByIdUser(idUser)
?.Select(r => r.Caption)
.Distinct();
public IEnumerable<UserRoleDto> GetRolesByIdUser(int idUser)
{
var roles = cacheRelationUserToRoles.Where(r => r.IdUser == idUser);
if (roles?.Any() != true)
return null;
return roles.SelectMany(r => RoleService.GetNestedById(r.IdUserRole));
}
2021-12-20 15:17:09 +05:00
public IEnumerable<PermissionDto> GetNestedPermissions(int idUser)
{
var roles = GetRolesByIdUser(idUser);
2021-12-21 11:52:53 +05:00
if(roles?.Any() != true)
return null;
var permissions = roles
.Where(r => r.Permissions is not null)
.SelectMany(r => r.Permissions);
return permissions;
}
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<string> newRoleNames, CancellationToken token)
{
if (newRoleNames?.Any() != true)
return;
var relatrions = new List<RelationUserUserRole>(newRoleNames.Count());
foreach (var roleName in newRoleNames)
{
var role = await RoleService.GetByNameAsync(roleName, token)
.ConfigureAwait(false);
if (role != null)
relatrions.Add(new()
{
IdUser = idUser,
IdUserRole = role.Id,
});
}
await cacheRelationUserToRoles.RemoveAsync(r => r.IdUser == idUser, token)
.ConfigureAwait(false);
await cacheRelationUserToRoles.InsertAsync(relatrions, token)
.ConfigureAwait(false);
}
public bool HasAnyRoleOf(int idUser, IEnumerable<string> roleNames)
{
if(!roleNames.Any())
return true;
var userRoleNames = GetRolesNamesByIdUser(idUser);
foreach (var roleName in userRoleNames)
if (roleNames.Contains(roleName))
return true;
return false;
}
public bool HasAnyRoleOf(int idUser, IEnumerable<int> roleIds)
{
if (!roleIds.Any())
return true;
var userRoles = GetRolesByIdUser(idUser);
foreach (var role in userRoles)
if (roleIds.Contains(role.Id))
return true;
return false;
}
public bool HasPermission(int idUser, string permissionName)
{
var relationsToRoles = cacheRelationUserToRoles.Where(r=>r.IdUser == idUser);
if (relationsToRoles is null)
return false;
return RoleService.HasPermission(relationsToRoles.Select(r => r.IdUserRole),
permissionName);
}
protected virtual User Convert(UserExtendedDto dto)
{
var entity = dto.Adapt<User>(userTypeAdapterConfig);
var oldUser = new Lazy<User>(() => cacheUsers.FirstOrDefault(u => u.Id == dto.Id));
if (string.IsNullOrEmpty(entity.PasswordHash))
entity.PasswordHash = oldUser.Value.PasswordHash;
return entity;
}
protected virtual UserExtendedDto Convert(User entity)
{
var dto = entity.Adapt<UserExtendedDto>();
return dto;
}
}
}