fix UserService

This commit is contained in:
Фролов 2021-12-23 18:07:20 +05:00
parent a8e1c4bd06
commit dfacd04b47
4 changed files with 46 additions and 26 deletions

View File

@ -8,6 +8,7 @@ namespace AsbCloudApp.Services
public interface IUserRoleService : ICrudService<UserRoleDto>
{
Task<UserRoleDto> GetByNameAsync(string name, CancellationToken token = default);
Task<IEnumerable<UserRoleDto>> GetByNamesAsync(IEnumerable<string> names, CancellationToken token = default);
List<UserRoleDto> GetNestedById(int id, int counter = 10);
bool HasPermission(IEnumerable<int> rolesIds, string permissionName);
}

View File

@ -71,6 +71,18 @@ namespace AsbCloudInfrastructure.Services
return dto;
}
public async Task<IEnumerable<UserRoleDto>> GetByNamesAsync(IEnumerable<string> names, CancellationToken token = default)
{
if (names?.Any() != true)
return null;
var entities = await cacheUserRoles.WhereAsync(r => names.Contains(r.Caption), token)
.ConfigureAwait(false);
if (entities?.Count() != names.Count())
throw new ArgumentException("Invalid role names", nameof(names));
var dtos = entities.Select(Convert);
return dtos;
}
public async Task<int> UpdateAsync(int id, UserRoleDto dto, CancellationToken token = default)
{
if (dto.Id != id)

View File

@ -47,11 +47,21 @@ namespace AsbCloudInfrastructure.Services
public async Task<int> InsertAsync(UserExtendedDto dto, CancellationToken token = default)
{
var entity = Convert(dto);
await AssertLoginAsync(dto.Login, token);
var userRoles = await RoleService.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
var updatedEntity = await cacheUsers.InsertAsync(entity, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync((int)updatedEntity.Id, dto.RoleNames, token);
if (userRoles?.Any() == true)
await UpdateRolesCacheForUserAsync(updatedEntity.Id, userRoles, token);
return updatedEntity?.Id ?? 0;
}
private async Task AssertLoginAsync(string login, CancellationToken token = default)
{
var existingUser = await cacheUsers.FirstOrDefaultAsync(u => u.Login.ToLower() == login.ToLower(), token);
if (existingUser is not null)
throw new ArgumentException($"Login {login} is busy by {existingUser.MakeDisplayName()}, id{existingUser.Id}", nameof(login));
}
public Task<int> InsertRangeAsync(IEnumerable<UserExtendedDto> newItems, CancellationToken token = default)
{
throw new NotImplementedException();
@ -66,7 +76,6 @@ namespace AsbCloudInfrastructure.Services
var dtos = entities.Select(Convert).ToList();
for (var i = 0; i < dtos.Count; i++)
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
return dtos;
}
@ -80,12 +89,21 @@ namespace AsbCloudInfrastructure.Services
public async Task<int> UpdateAsync(int id, UserExtendedDto dto, CancellationToken token = default)
{
var oldUser = await cacheUsers.FirstOrDefaultAsync(u=>u.Id == id, token);
if(oldUser.Login != dto.Login)
await AssertLoginAsync(dto.Login, token);
var userRoles = await RoleService.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync(id, userRoles, token);
var entity = Convert(dto);
await UpdateRolesCacheForUserAsync(id, dto.RoleNames, token);
if (dto.Id == 0)
entity.Id = id;
else if (dto.Id != id)
throw new ArgumentException($"Invalid userDto.id it mast be 0 or {id}", nameof(dto));
var result = await cacheUsers.UpsertAsync(entity, token)
.ConfigureAwait(false);
return result;
}
@ -120,27 +138,17 @@ namespace AsbCloudInfrastructure.Services
return permissions;
}
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<string> newRoleNames, CancellationToken token)
private async Task UpdateRolesCacheForUserAsync(int idUser, IEnumerable<UserRoleDto> newRoles, 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);
if (newRoles?.Any() == true)
await cacheRelationUserToRoles.InsertAsync(newRoles.Select(role => new RelationUserUserRole
{
IdUser = idUser,
IdUserRole = role.Id
}), token).ConfigureAwait(false);
}
public bool HasAnyRoleOf(int idUser, IEnumerable<string> roleNames)
@ -178,9 +186,8 @@ namespace AsbCloudInfrastructure.Services
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;
entity.PasswordHash = cacheUsers.FirstOrDefault(u => u.Id == dto.Id)?.PasswordHash;
return entity;
}

View File

@ -42,7 +42,7 @@ namespace AsbCloudWebApi.Middlewares
}
}
private string MakeJsonBody(ArgumentException ex)
private static string MakeJsonBody(ArgumentException ex)
{
object error = new { name = ex.ParamName, errors = new string[] { ex.Message } };
var buffer = System.Text.Json.JsonSerializer.Serialize(error);