CS2-142 Изменить UserRole

This commit is contained in:
Фролов 2022-01-13 14:36:27 +05:00
parent f3803c0622
commit 0109e529f6
6 changed files with 144 additions and 74 deletions

View File

@ -0,0 +1,24 @@
using AsbCloudApp.Data;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace AsbCloudApp.Comparators
{
public class ComparerIId : IComparer<IId>, IEqualityComparer<IId>
{
private static readonly ComparerIId instance = new ComparerIId();
private ComparerIId(){}
public static ComparerIId GetInstance() => instance;
public int Compare(IId x, IId y) =>
x.Id.CompareTo(y.Id);
public bool Equals(IId x, IId y) =>
x.Id == y.Id;
public int GetHashCode([DisallowNull] IId obj) =>
obj.GetHashCode();
}
}

View File

@ -9,7 +9,7 @@ namespace AsbCloudApp.Services
{
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);
IEnumerable<UserRoleDto> GetNestedById(int id, int counter = 10);
bool HasPermission(IEnumerable<int> rolesIds, string permissionName);
}
}

View File

@ -8,6 +8,7 @@ using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using AsbCloudApp.Services;
using System;
using AsbCloudApp.Comparators;
namespace AsbCloudInfrastructure.Services
{
@ -20,7 +21,7 @@ namespace AsbCloudInfrastructure.Services
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb)
{
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, nameof(UserRole.RelationUserRolePermissions));
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, nameof(UserRole.RelationUserRolePermissions), nameof(UserRole.RelationUserRoleUserRoles));
cacheUserRolePermissions = cacheDb.GetCachedTable<RelationUserRolePermission>((AsbCloudDbContext)context, nameof(RelationUserRolePermission.Permission));
}
@ -106,18 +107,26 @@ namespace AsbCloudInfrastructure.Services
return dto.Id;
}
public List<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
public IEnumerable<UserRoleDto> GetNestedById(int id, int recursionLevel = 7)
{
var role = cacheUserRoles.FirstOrDefault(r => r.Id == id);
if (role is null)
return null;
var dto = Convert(role);
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;
var roles = new SortedSet<UserRoleDto>(ComparerIId.GetInstance()) { dto };
if (recursionLevel <= 0 || role.RelationUserRoleUserRoles?.Any() != true)
return roles;
foreach (var relation in role.RelationUserRoleUserRoles)
{
var nestedRoles = GetNestedById(relation.IdInclude, --recursionLevel);
if (nestedRoles?.Any() != true)
continue;
foreach (var nestedRole in nestedRoles)
roles.Add(nestedRole);
}
return roles;
}
private async Task UpdatePermissionsAsync(UserRoleDto roleDto, CancellationToken token)
@ -168,10 +177,15 @@ namespace AsbCloudInfrastructure.Services
{
if (userRole.RelationUserRolePermissions.Any(p => p.IdPermission == idPermission))
return true;
if (userRole.IdParent is not null && recursionLevel > 0)
if (recursionLevel <= 0 || userRole.RelationUserRoleUserRoles?.Any() != true)
return false;
foreach (var relation in userRole.RelationUserRoleUserRoles)
{
var parentRole = cacheUserRoles.FirstOrDefault(p => p.Id == userRole.IdParent);
return HasPermission(parentRole, idPermission, --recursionLevel);
var includedRole = cacheUserRoles.First(p => p.Id == relation.IdInclude);
if (HasPermission(includedRole, idPermission, --recursionLevel))
return true;
}
return false;
}

View File

@ -0,0 +1,94 @@
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Cache;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace AsbCloudWebApi.Tests.ServicesTests
{
public class UserRoleServiceTest
{
private readonly AsbCloudDbContext context;
private readonly CacheDb cacheDb;
private readonly List<UserRole> roles = new() {
new UserRole { Id = 1_000_001, Caption = "role 1 level 0" },
new UserRole { Id = 1_000_002, Caption = "role 2 level 1" },
new UserRole { Id = 1_000_003, Caption = "role 3 level 1" },
new UserRole { Id = 1_000_004, Caption = "role 4 level 2" },
};
private readonly List<RelationUserRoleUserRole> relationRoleRole = new()
{
new RelationUserRoleUserRole { Id = 1_000_002, IdInclude = 1_000_001 },
new RelationUserRoleUserRole { Id = 1_000_003, IdInclude = 1_000_001 },
new RelationUserRoleUserRole { Id = 1_000_004, IdInclude = 1_000_002 },
new RelationUserRoleUserRole { Id = 1_000_004, IdInclude = 1_000_003 },
};
private readonly List<Permission> permissions = new()
{
new Permission { Id = 2_000_001, Name = "permission 1" },
new Permission { Id = 2_000_002, Name = "permission 2" },
new Permission { Id = 2_000_003, Name = "permission 3" },
new Permission { Id = 2_000_004, Name = "permission 4" },
};
private readonly List<RelationUserRolePermission> relationRolePermission = new()
{
new RelationUserRolePermission { IdUserRole = 1_000_001, IdPermission = 2_000_001 },
new RelationUserRolePermission { IdUserRole = 1_000_002, IdPermission = 2_000_002 },
new RelationUserRolePermission { IdUserRole = 1_000_003, IdPermission = 2_000_003 },
new RelationUserRolePermission { IdUserRole = 1_000_004, IdPermission = 2_000_004 },
};
public UserRoleServiceTest()
{
cacheDb = new CacheDb();
context = TestHelpter.MakeTestContext();
context.UserRoles.RemoveRange(roles);
context.Permissions.RemoveRange(permissions);
context.SaveChanges();
context.UserRoles.AddRange(roles);
context.Permissions.AddRange(permissions);
context.SaveChanges();
context.RelationUserRoleUserRoles.AddRange(relationRoleRole);
context.RelationUserRolePermissions.AddRange(relationRolePermission);
context.SaveChanges();
}
~UserRoleServiceTest(){
context.UserRoles.RemoveRange(roles);
context.Permissions.RemoveRange(permissions);
context.RelationUserRoleUserRoles.RemoveRange(relationRoleRole);
context.RelationUserRolePermissions.RemoveRange(relationRolePermission);
context.SaveChanges();
context.Dispose();
}
[Fact]
public void GetNestedById_return_4_items()
{
var service = new UserRoleService(context, cacheDb);
var nestedRoles = service.GetNestedById(1_000_004);
Assert.Equal(roles.Count, nestedRoles.Count());
}
[Fact]
public void HasPermission_return_true()
{
var service = new UserRoleService(context, cacheDb);
var result = service.HasPermission(new int[] { 1_000_004 }, "permission 1");
Assert.True(result);
}
[Fact]
public void HasPermission_return_false()
{
var service = new UserRoleService(context, cacheDb);
var result = service.HasPermission(new int[] { 1_000_003 }, "permission 2");
Assert.False(result);
}
}
}

View File

@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AsbCloudApp\AsbCloudApp.csproj" />
<ProjectReference Include="..\AsbCloudDb\AsbCloudDb.csproj" />
</ItemGroup>
</Project>

View File

@ -1,47 +0,0 @@
using AsbCloudApp.Data;
using AsbCloudDb.Model;
using Microsoft.EntityFrameworkCore;
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=experiments;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True")
.Options;
var context = new AsbCloudDbContext(options);
var rels = context.RelationUserRoleUserRoles.Include(r=>r.Role).Include(r => r.IncludeRole);
IEnumerable<UserRoleDto> GetIncludedRole(int id)
{
var res = context.UserRoles
.Include(r=>r.RelationUserRoleUserRoles)
.Where(r=>r.Id == id)
.SelectMany(r=>r.);
return rels.Where(r => r.Id == id).;
}
UserRoleDto Convert(UserRole role)
{
if (role is null)
return null;
var res = new UserRoleDto
{
Id = role.Id,
Caption = role.Caption,
IdType = role.IdType,
Permissions = role.RelationUserRolePermissions?.Select(r => r.Permission).ToList(),
};
}
PermissionDto Convert(Permission permission)
{
if (permission is null)
return null;
return new PermissionDto
{
Name = permission.Name,
Id = permission.Id,
Description = permission.Description
};
}
Console.WriteLine("Hello, World!");