diff --git a/AsbCloudInfrastructure/Services/UserRoleService.cs b/AsbCloudInfrastructure/Services/UserRoleService.cs index 221b70f7..775a8b07 100644 --- a/AsbCloudInfrastructure/Services/UserRoleService.cs +++ b/AsbCloudInfrastructure/Services/UserRoleService.cs @@ -15,14 +15,16 @@ namespace AsbCloudInfrastructure.Services public class UserRoleService : IUserRoleService { private readonly CacheTable cacheUserRoles; - private readonly CacheTable cacheUserRolePermissions; + private readonly CacheTable cacheRelationUserRolePermissions; + private readonly CacheTable cacheRelationUserRoleUserRole; public ISet Includes { get; } = new SortedSet(); public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb) { cacheUserRoles = cacheDb.GetCachedTable((AsbCloudDbContext)context, nameof(UserRole.RelationUserRolePermissions), nameof(UserRole.RelationUserRoleUserRoles)); - cacheUserRolePermissions = cacheDb.GetCachedTable((AsbCloudDbContext)context, nameof(RelationUserRolePermission.Permission)); + cacheRelationUserRolePermissions = cacheDb.GetCachedTable((AsbCloudDbContext)context, nameof(RelationUserRolePermission.Permission)); + cacheRelationUserRoleUserRole = cacheDb.GetCachedTable((AsbCloudDbContext)context, nameof(RelationUserRoleUserRole.IncludeRole), nameof(RelationUserRoleUserRole.Role)); } public async Task InsertAsync(UserRoleDto dto, CancellationToken token = default) @@ -32,6 +34,8 @@ namespace AsbCloudInfrastructure.Services .ConfigureAwait(false); dto.Id = updatedEntity.Id; await UpdatePermissionsAsync(dto, token); + await UpdateIncludedRolesAsync(dto, token); + await cacheUserRoles.RefreshAsync(true, token) .ConfigureAwait(false); return updatedEntity?.Id ?? 0; @@ -100,6 +104,7 @@ namespace AsbCloudInfrastructure.Services var entity = Convert(dto); await UpdatePermissionsAsync(dto, token); + await UpdateIncludedRolesAsync(dto, token); await cacheUserRoles.UpsertAsync(entity, token) .ConfigureAwait(false); @@ -129,25 +134,39 @@ namespace AsbCloudInfrastructure.Services return roles; } - private async Task UpdatePermissionsAsync(UserRoleDto roleDto, CancellationToken token) + private async Task UpdatePermissionsAsync(UserRoleDto dto, CancellationToken token) { - if (roleDto?.Permissions is null) + if (dto?.Permissions is null) return; - await cacheUserRolePermissions.RemoveAsync(r => r.IdUserRole == roleDto.Id, token) + await cacheRelationUserRolePermissions.RemoveAsync(r => r.IdUserRole == dto.Id, token) .ConfigureAwait(false); - if (!roleDto.Permissions.Any()) - return; - - var newRelationRoleToPermission = roleDto.Permissions.Select(p => new RelationUserRolePermission + if (dto.Permissions.Any()) { - IdPermission = p.Id, - IdUserRole = roleDto.Id, - }); + var newRelationRoleToPermission = dto.Permissions.Select(p => new RelationUserRolePermission + { + IdPermission = p.Id, + IdUserRole = dto.Id, + }); - await cacheUserRolePermissions.InsertAsync(newRelationRoleToPermission, token) - .ConfigureAwait(false); + await cacheRelationUserRolePermissions.InsertAsync(newRelationRoleToPermission, token) + .ConfigureAwait(false); + } + } + + private async Task UpdateIncludedRolesAsync(UserRoleDto dto, CancellationToken token) + { + if (dto?.Roles is null) + return ; + + await cacheRelationUserRoleUserRole.RemoveAsync(rel => rel.Id == dto.Id, token); + + if (dto.Roles.Any()) + { + var newRelations = dto.Roles.Select(r => new RelationUserRoleUserRole { Id = dto.Id, IdInclude = r.Id }); + await cacheRelationUserRoleUserRole.UpsertAsync(newRelations, token); + } } public Task DeleteAsync(int id, CancellationToken token = default) @@ -158,7 +177,7 @@ namespace AsbCloudInfrastructure.Services public bool HasPermission(IEnumerable rolesIds, string permissionName) { - var permissionInfo = cacheUserRolePermissions + var permissionInfo = cacheRelationUserRolePermissions .FirstOrDefault(p => p.Permission?.Name.ToLower() == permissionName.ToLower()) ?.Permission; @@ -201,10 +220,18 @@ namespace AsbCloudInfrastructure.Services var dto = entity.Adapt(); if(entity.RelationUserRolePermissions?.Any() == true) { - dto.Permissions = cacheUserRolePermissions + dto.Permissions = cacheRelationUserRolePermissions .Where(r => entity.Id == r.IdUserRole) .Select(r => Convert(r.Permission)); } + + if (entity.RelationUserRoleUserRoles?.Any() == true) + { + dto.Roles = entity.RelationUserRoleUserRoles.Select(rel => { + var includedRole = cacheUserRoles.First(r => r.Id == rel.IdInclude); + return Convert(includedRole); + }).ToList(); + } return dto; } diff --git a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj index 6dfd9e78..26215a1a 100644 --- a/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj +++ b/AsbCloudWebApi.Tests/AsbCloudWebApi.Tests.csproj @@ -14,10 +14,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/AsbCloudWebApi.Tests/ServicesTests/UserRoleServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/UserRoleServiceTest.cs index 8c70fc22..ea3095fb 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/UserRoleServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/UserRoleServiceTest.cs @@ -1,8 +1,12 @@ -using AsbCloudDb.Model; +using AsbCloudApp.Data; +using AsbCloudDb.Model; using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services.Cache; +using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace AsbCloudWebApi.Tests.ServicesTests @@ -90,5 +94,94 @@ namespace AsbCloudWebApi.Tests.ServicesTests var result = service.HasPermission(new int[] { 1_000_003 }, "permission 2"); Assert.False(result); } + + [Fact] + public async Task InsertAsync_returns_id() + { + var service = new UserRoleService(context, cacheDb); + var newRole = new UserRoleDto + { + Caption = "new role", + IdType = 0, + }; + var id = await service.InsertAsync(newRole, CancellationToken.None ); + Assert.NotEqual(0, id); + } + + [Fact] + public async Task InsertAsync_updates_relation_to_permission() + { + var service = new UserRoleService(context, cacheDb); + var newRole = new UserRoleDto + { + Caption = "new role", + IdType = 0, + Permissions = new[] { new PermissionDto{ Id = 2_000_001 } }, + }; + var id = await service.InsertAsync(newRole, CancellationToken.None); + var entity = await service.GetAsync(id); + Assert.Equal(newRole.Permissions.Count(), entity.Permissions.Count()); + } + + [Fact] + public async Task InsertAsync_updates_relation_to_role() + { + var service = new UserRoleService(context, cacheDb); + var newRole = new UserRoleDto + { + Caption = "new role", + IdType = 0, + Roles = new [] { new UserRoleDto { Id = 1_000_001 } } + }; + var id = await service.InsertAsync(newRole, CancellationToken.None); + var entity = await service.GetAsync(id); + Assert.Equal(newRole.Roles.Count, entity.Roles.Count); + } + + [Fact] + public async Task UpdateAsync_returns_id() + { + var service = new UserRoleService(context, cacheDb); + const int updateId = 1_000_002; + var modRole = new UserRoleDto + { + Id = updateId, + Caption = "role 2 level 1" + }; + var id = await service.UpdateAsync(1_000_002, modRole, CancellationToken.None); + Assert.Equal(updateId, id); + } + + [Fact] + public async Task UpdateAsync_updates_relation_to_permission() + { + var service = new UserRoleService(context, cacheDb); + const int updateId = 1_000_002; + var modRole = new UserRoleDto + { + Id = updateId, + Caption = "role 2 level 1", + Permissions = new[] { new PermissionDto { Id = 2_000_001 } }, + }; + var id = await service.UpdateAsync(1_000_002, modRole, CancellationToken.None); + var entity = await service.GetAsync(id); + Assert.Equal(modRole.Permissions.Count(), entity.Permissions.Count()); + } + + [Fact] + public async Task UpdateAsync_updates_relation_to_role() + { + var service = new UserRoleService(context, cacheDb); + const int updateId = 1_000_002; + var modRole = new UserRoleDto + { + Id = updateId, + Caption = "role 2 level 1", + Roles = new[] { new UserRoleDto { Id = 1_000_001 } } + }; + var id = await service.UpdateAsync(1_000_002, modRole, CancellationToken.None); + var entity = await service.GetAsync(id); + Assert.Equal(modRole.Roles.Count(), entity.Roles.Count()); + } } }