diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs new file mode 100644 index 0000000000..7dfb85a4fd --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs @@ -0,0 +1,11 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.Identity +{ + public interface IIdentityRoleAppService : IAsyncCrudAppService + { + + } +} diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs index ea61572342..8738265374 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs @@ -9,6 +9,6 @@ namespace Volo.Abp.Identity { Task> GetRolesAsync(Guid id); - Task UpdateRolesAsync(Guid id, UpdateIdentityUserRolesDto input); + Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input); } } diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateDto.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateDto.cs new file mode 100644 index 0000000000..d98edfb638 --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateDto.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Identity +{ + public class IdentityRoleCreateDto : IdentityRoleCreateOrUpdateDtoBase + { + + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs new file mode 100644 index 0000000000..9f164bd651 --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleCreateOrUpdateDtoBase.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Identity +{ + public class IdentityRoleCreateOrUpdateDtoBase + { + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleUpdateDto.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleUpdateDto.cs new file mode 100644 index 0000000000..c569957f23 --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityRoleUpdateDto.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Identity +{ + public class IdentityRoleUpdateDto : IdentityRoleCreateOrUpdateDtoBase + { + + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/UpdateIdentityUserRolesDto.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserUpdateRolesDto.cs similarity index 77% rename from src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/UpdateIdentityUserRolesDto.cs rename to src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserUpdateRolesDto.cs index 772d6f44e4..c6f86669b4 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/UpdateIdentityUserRolesDto.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserUpdateRolesDto.cs @@ -2,7 +2,7 @@ namespace Volo.Abp.Identity { - public class UpdateIdentityUserRolesDto + public class IdentityUserUpdateRolesDto { [Required] public string[] RoleNames { get; set; } diff --git a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs new file mode 100644 index 0000000000..6cbbf8ca41 --- /dev/null +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.Identity +{ + public class IdentityRoleAppService : ApplicationService, IIdentityRoleAppService + { + private readonly IdentityRoleManager _roleManager; + private readonly IIdentityRoleRepository _roleRepository; + + public IdentityRoleAppService( + IdentityRoleManager roleManager, + IIdentityRoleRepository roleRepository) + { + _roleManager = roleManager; + _roleRepository = roleRepository; + } + + public async Task GetAsync(Guid id) + { + return ObjectMapper.Map( + await _roleManager.GetByIdAsync(id) + ); + } + + public async Task> GetListAsync(PagedAndSortedResultRequestDto input) + { + var count = (int)await _roleRepository.GetCountAsync(); + var list = await _roleRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); + + return new PagedResultDto( + count, + ObjectMapper.Map, List>(list) + ); + } + + public async Task CreateAsync(IdentityRoleCreateDto input) + { + var role = new IdentityRole(GuidGenerator.Create(), input.Name); + + await _roleManager.CreateAsync(role); + await CurrentUnitOfWork.SaveChangesAsync(); + + return ObjectMapper.Map(role); + } + + public async Task UpdateAsync(Guid id, IdentityRoleUpdateDto input) + { + var role = await _roleManager.GetByIdAsync(id); + + await _roleManager.SetRoleNameAsync(role, input.Name); + + await _roleManager.UpdateAsync(role); + await CurrentUnitOfWork.SaveChangesAsync(); + + return ObjectMapper.Map(role); + } + + public async Task DeleteAsync(Guid id) + { + var role = await _roleManager.GetByIdAsync(id); + await _roleManager.DeleteAsync(role); + } + } +} diff --git a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs index 6035678f20..fc264b4a60 100644 --- a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs @@ -28,12 +28,12 @@ namespace Volo.Abp.Identity public async Task> GetListAsync(PagedAndSortedResultRequestDto input) { - var userCount = (int)await _userRepository.GetCountAsync(); - var users = await _userRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); + var count = (int)await _userRepository.GetCountAsync(); + var list = await _userRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); return new PagedResultDto( - userCount, - ObjectMapper.Map, List>(users) + count, + ObjectMapper.Map, List>(list) ); } @@ -75,7 +75,7 @@ namespace Volo.Abp.Identity ); } - public async Task UpdateRolesAsync(Guid id, UpdateIdentityUserRolesDto input) + public async Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input) { var user = await _userManager.GetByIdAsync(id); await _userManager.SetRolesAsync(user, input.RoleNames); diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs index 3f9c322f81..fd5e343ee7 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs @@ -1,3 +1,6 @@ +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -18,5 +21,10 @@ namespace Volo.Abp.Identity { return DbSet.FirstOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); } + + public async Task> GetListAsync(string sorting, int maxResultCount, int skipCount) + { + return await this.OrderBy(sorting ?? nameof(IdentityRole.Name)).PageBy(skipCount, maxResultCount).ToListAsync(); + } } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity/Volo/Abp/Identity/IIdentityRoleRepository.cs b/src/Volo.Abp.Identity/Volo/Abp/Identity/IIdentityRoleRepository.cs index 666eecc3a5..7ff67aba2c 100644 --- a/src/Volo.Abp.Identity/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/src/Volo.Abp.Identity/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -7,5 +8,7 @@ namespace Volo.Abp.Identity public interface IIdentityRoleRepository : IRepository { Task FindByNormalizedNameAsync(string normalizedRoleName, CancellationToken cancellationToken); + + Task> GetListAsync(string sorting, int maxResultCount, int skipCount); } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRoleManager.cs b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRoleManager.cs index 5718c95c2e..d1da955666 100644 --- a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRoleManager.cs +++ b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRoleManager.cs @@ -1,6 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; +using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Services; namespace Volo.Abp.Identity @@ -21,5 +24,16 @@ namespace Volo.Abp.Identity logger) { } + + public async Task GetByIdAsync(Guid id) + { + var role = await Store.FindByIdAsync(id.ToString(), CancellationToken); + if (role == null) + { + throw new EntityNotFoundException(typeof(IdentityRole), id); + } + + return role; + } } } diff --git a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityRoleAppService_Tests.cs b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityRoleAppService_Tests.cs new file mode 100644 index 0000000000..f648bfd9b6 --- /dev/null +++ b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityRoleAppService_Tests.cs @@ -0,0 +1,125 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Xunit; +using Shouldly; +using Volo.Abp.Application.Dtos; + +namespace Volo.Abp.Identity +{ + public class IdentityRoleAppService_Tests: AbpIdentityApplicationTestBase + { + private readonly IIdentityRoleAppService _roleAppService; + private readonly IIdentityRoleRepository _roleRepository; + + public IdentityRoleAppService_Tests() + { + _roleAppService = ServiceProvider.GetRequiredService(); + _roleRepository = ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task GetAsync() + { + //Arrange + + var moderator = await GetRoleAsync("moderator"); + + //Act + + var result = await _roleAppService.GetAsync(moderator.Id); + + //Assert + + result.Id.ShouldBe(moderator.Id); + } + + [Fact] + public async Task GetListAsync() + { + //Act + + var result = await _roleAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + + //Assert + + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.Count.ShouldBeGreaterThan(0); + } + + [Fact] + public async Task CreateAsync() + { + //Arrange + + var input = new IdentityRoleCreateDto + { + Name = Guid.NewGuid().ToString("N").Left(8) + }; + + //Act + + var result = await _roleAppService.CreateAsync(input); + + //Assert + + result.Id.ShouldNotBe(Guid.Empty); + result.Name.ShouldBe(input.Name); + + var role = await _roleRepository.GetAsync(result.Id); + role.Name.ShouldBe(input.Name); + } + + [Fact] + public async Task UpdateAsync() + { + //Arrange + + var moderator = await GetRoleAsync("moderator"); + + var input = new IdentityRoleUpdateDto + { + Name = Guid.NewGuid().ToString("N").Left(8) + }; + + //Act + + var result = await _roleAppService.UpdateAsync(moderator.Id, input); + + //Assert + + result.Id.ShouldBe(moderator.Id); + result.Name.ShouldBe(input.Name); + + var updatedRole = await _roleRepository.GetAsync(moderator.Id); + updatedRole.Name.ShouldBe(input.Name); + } + + [Fact] + public async Task DeleteAsync() + { + //Arrange + + var moderator = await GetRoleAsync("moderator"); + + //Act + + await _roleAppService.DeleteAsync(moderator.Id); + + //Assert + + (await FindRoleAsync("moderator")).ShouldBeNull(); + } + + private async Task GetRoleAsync(string roleName) + { + return (await _roleRepository.GetListAsync()).First(u => u.Name == roleName); + } + + private async Task FindRoleAsync(string roleName) + { + return (await _roleRepository.GetListAsync()).FirstOrDefault(u => u.Name == roleName); + } + } +} diff --git a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs index f69028e5f4..a4bbb9af11 100644 --- a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs +++ b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs @@ -10,12 +10,12 @@ namespace Volo.Abp.Identity { public class IdentityUserAppService_Tests : AbpIdentityApplicationTestBase { - private readonly IIdentityUserAppService _identityUserAppService; + private readonly IIdentityUserAppService _userAppService; private readonly IIdentityUserRepository _userRepository; public IdentityUserAppService_Tests() { - _identityUserAppService = ServiceProvider.GetRequiredService(); + _userAppService = ServiceProvider.GetRequiredService(); _userRepository = ServiceProvider.GetRequiredService(); } @@ -28,7 +28,7 @@ namespace Volo.Abp.Identity //Act - var result = await _identityUserAppService.GetAsync(johnNash.Id); + var result = await _userAppService.GetAsync(johnNash.Id); //Assert @@ -44,7 +44,7 @@ namespace Volo.Abp.Identity { //Act - var result = await _identityUserAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + var result = await _userAppService.GetListAsync(new PagedAndSortedResultRequestDto()); //Assert @@ -69,7 +69,7 @@ namespace Volo.Abp.Identity //Act - var result = await _identityUserAppService.CreateAsync(input); + var result = await _userAppService.CreateAsync(input); //Assert @@ -105,7 +105,7 @@ namespace Volo.Abp.Identity //Act - var result = await _identityUserAppService.UpdateAsync(johnNash.Id, input); + var result = await _userAppService.UpdateAsync(johnNash.Id, input); //Assert @@ -132,7 +132,7 @@ namespace Volo.Abp.Identity //Act - await _identityUserAppService.DeleteAsync(johnNash.Id); + await _userAppService.DeleteAsync(johnNash.Id); //Assert @@ -148,7 +148,7 @@ namespace Volo.Abp.Identity //Act - var result = await _identityUserAppService.GetRolesAsync(johnNash.Id); + var result = await _userAppService.GetRolesAsync(johnNash.Id); //Assert @@ -166,9 +166,9 @@ namespace Volo.Abp.Identity //Act - await _identityUserAppService.UpdateRolesAsync( + await _userAppService.UpdateRolesAsync( johnNash.Id, - new UpdateIdentityUserRolesDto + new IdentityUserUpdateRolesDto { RoleNames = new[] {"moderator", "admin"} }