From d7a733601abc665f2896041168f38c2a5ff4d375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?alir=C4=B1za=20ad=C4=B1yah=C5=9Fi?= Date: Fri, 13 Oct 2017 14:07:05 +0300 Subject: [PATCH] #109 User management page (CRUD) for Identity module. --- .../Abp/Identity/GetIdentityRolesInput.cs | 9 ++++ .../Abp/Identity/GetIdentityUsersInput.cs | 1 - .../Abp/Identity/IIdentityRoleAppService.cs | 8 +-- .../Abp/Identity/IIdentityUserAppService.cs | 2 - ...pDeskApplicationModuleAutoMapperProfile.cs | 5 +- .../Abp/Identity/IdentityRoleAppService.cs | 13 +++-- .../Abp/Identity/IdentityUserAppService.cs | 25 +--------- .../Abp/Identity/IIdentityRoleRepository.cs | 5 +- .../Identity/EfCoreIdentityRoleRepository.cs | 14 +++++- .../Identity/EfCoreIdentityUserRepository.cs | 1 + .../Identity/Controllers/UsersController.cs | 50 ++++++++++++++++--- .../Models/CreateOrUpdateUserViewModel.cs | 8 +++ .../Areas/Identity/Views/Users/_Create.cshtml | 2 +- .../Areas/Identity/Views/Users/_Update.cshtml | 4 +- .../modules/identity/views/users/index.js | 44 ++++++++-------- .../Identity/IdentityRoleAppService_Tests.cs | 2 +- 16 files changed, 121 insertions(+), 72 deletions(-) create mode 100644 src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityRolesInput.cs create mode 100644 src/Volo.Abp.Identity.Web/Areas/Identity/Models/CreateOrUpdateUserViewModel.cs diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityRolesInput.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityRolesInput.cs new file mode 100644 index 0000000000..c5db3405a8 --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityRolesInput.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Application.Dtos; + +namespace Volo.Abp.Identity +{ + public class GetIdentityRolesInput : PagedAndSortedResultRequestDto + { + public string Filter { get; set; } + } +} diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityUsersInput.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityUsersInput.cs index 274800728a..29c6e296e7 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityUsersInput.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/GetIdentityUsersInput.cs @@ -1,5 +1,4 @@ using Volo.Abp.Application.Dtos; -using Volo.Abp.Validation; namespace Volo.Abp.Identity { 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 index 7dfb85a4fd..cc72600e16 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityRoleAppService.cs @@ -1,11 +1,13 @@ using System; -using Volo.Abp.Application.Dtos; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.Application.Services; namespace Volo.Abp.Identity { - public interface IIdentityRoleAppService : IAsyncCrudAppService + public interface IIdentityRoleAppService : IAsyncCrudAppService { - + //TODO: remove after a better design + Task> GetAllListAsync(); } } 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 afe51f01ea..c620ebd917 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 @@ -10,7 +10,5 @@ namespace Volo.Abp.Identity Task> GetRolesAsync(Guid id); Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input); - - Task GetUserForCreateOrUpdateAsync(Guid? id); } } diff --git a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/AbpDeskApplicationModuleAutoMapperProfile.cs b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/AbpDeskApplicationModuleAutoMapperProfile.cs index 6f922c9707..d99da9de7d 100644 --- a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/AbpDeskApplicationModuleAutoMapperProfile.cs +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/AbpDeskApplicationModuleAutoMapperProfile.cs @@ -1,4 +1,5 @@ -using AutoMapper; +using System.Collections.Generic; +using AutoMapper; namespace Volo.Abp.Identity { @@ -8,7 +9,7 @@ namespace Volo.Abp.Identity { CreateMap(); CreateMap(); - CreateMap(); + CreateMap(); } } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs index 6cbbf8ca41..0113ef86ba 100644 --- a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityRoleAppService.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.Identity private readonly IIdentityRoleRepository _roleRepository; public IdentityRoleAppService( - IdentityRoleManager roleManager, + IdentityRoleManager roleManager, IIdentityRoleRepository roleRepository) { _roleManager = roleManager; @@ -26,10 +26,10 @@ namespace Volo.Abp.Identity ); } - public async Task> GetListAsync(PagedAndSortedResultRequestDto input) + public async Task> GetListAsync(GetIdentityRolesInput input) { var count = (int)await _roleRepository.GetCountAsync(); - var list = await _roleRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); + var list = await _roleRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter); return new PagedResultDto( count, @@ -37,6 +37,13 @@ namespace Volo.Abp.Identity ); } + public async Task> GetAllListAsync() + { + var list = await _roleRepository.GetAllListAsync(); + + return ObjectMapper.Map, List>(list); + } + public async Task CreateAsync(IdentityRoleCreateDto input) { var role = new IdentityRole(GuidGenerator.Create(), input.Name); 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 b1912745b0..2558b711c4 100644 --- a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs @@ -13,13 +13,11 @@ namespace Volo.Abp.Identity { private readonly IdentityUserManager _userManager; private readonly IIdentityUserRepository _userRepository; - private readonly IIdentityRoleRepository _roleRepository; - public IdentityUserAppService(IdentityUserManager userManager, IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository) + public IdentityUserAppService(IdentityUserManager userManager, IIdentityUserRepository userRepository) { _userManager = userManager; _userRepository = userRepository; - _roleRepository = roleRepository; } public async Task GetAsync(Guid id) @@ -29,27 +27,6 @@ namespace Volo.Abp.Identity ); } - public async Task GetUserForCreateOrUpdateAsync(Guid? id) - { - var userRoleDtos = ObjectMapper.Map, IdentityUserRoleDto[]>(await _roleRepository.GetListAsync()); - var output = new IdentityUserCreateOrUpdateOutput - { - Roles = userRoleDtos - }; - - if (!id.HasValue) return output; - - var user = await _userManager.GetByIdAsync(id.Value); - output.User = ObjectMapper.Map(user); - - foreach (var userRoleDto in userRoleDtos) - { - userRoleDto.IsAssigned = await _userManager.IsInRoleAsync(user, userRoleDto.Name); - } - - return output; - } - public async Task> GetListAsync(GetIdentityUsersInput input) { var count = (int)await _userRepository.GetCountAsync(); diff --git a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs index 7ff67aba2c..f18ce2edd4 100644 --- a/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs +++ b/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs @@ -9,6 +9,9 @@ namespace Volo.Abp.Identity { Task FindByNormalizedNameAsync(string normalizedRoleName, CancellationToken cancellationToken); - Task> GetListAsync(string sorting, int maxResultCount, int skipCount); + Task> GetListAsync(string sorting, int maxResultCount, int skipCount, string filter); + + //TODO: remove after a better design + Task> GetAllListAsync(); } } \ No newline at end of file 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 fd5e343ee7..40047101c8 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityRoleRepository.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Identity.EntityFrameworkCore; +using System; namespace Volo.Abp.Identity { @@ -22,9 +23,18 @@ namespace Volo.Abp.Identity return DbSet.FirstOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); } - public async Task> GetListAsync(string sorting, int maxResultCount, int skipCount) + public async Task> GetListAsync(string sorting, int maxResultCount, int skipCount, string filter) { - return await this.OrderBy(sorting ?? nameof(IdentityRole.Name)).PageBy(skipCount, maxResultCount).ToListAsync(); + return await this.WhereIf( + !filter.IsNullOrWhiteSpace(), + r => r.Name.Contains(filter) + ).OrderBy(sorting ?? nameof(IdentityRole.Name)) + .PageBy(skipCount, maxResultCount).ToListAsync(); + } + + public async Task> GetAllListAsync() + { + return await GetQueryable().ToListAsync(); } } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs index 65ab54b5a6..70b301e125 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs @@ -99,6 +99,7 @@ namespace Volo.Abp.Identity { var query = from userRole in DbContext.UserRoles join role in DbContext.Roles on userRole.RoleId equals role.Id + where userRole.UserId == userId select role; return await query.ToListAsync(); diff --git a/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs b/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs index b14c3ca582..15437c706b 100644 --- a/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs +++ b/src/Volo.Abp.Identity.Web/Areas/Identity/Controllers/UsersController.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Identity.Web.Areas.Identity.Models; namespace Volo.Abp.Identity.Web.Areas.Identity.Controllers { @@ -11,10 +14,12 @@ namespace Volo.Abp.Identity.Web.Areas.Identity.Controllers public class UsersController : AbpController { private readonly IIdentityUserAppService _identityUserAppService; + private readonly IIdentityRoleAppService _identityRoleAppService; - public UsersController(IIdentityUserAppService identityUserAppService) + public UsersController(IIdentityUserAppService identityUserAppService, IIdentityRoleAppService identityRoleAppService) { _identityUserAppService = identityUserAppService; + _identityRoleAppService = identityRoleAppService; } public async Task Index() @@ -22,18 +27,49 @@ namespace Volo.Abp.Identity.Web.Areas.Identity.Controllers return View(); } - public async Task _Create() + public async Task Create() { - var identityUser = await _identityUserAppService.GetUserForCreateOrUpdateAsync(null); + + var model = await CreateViewModel(null); - return PartialView(identityUser); + return PartialView("_Create", model); } - public async Task _Update(Guid id) + public async Task Update(Guid id) { - var identityUser = await _identityUserAppService.GetUserForCreateOrUpdateAsync(id); + var user = await _identityUserAppService.GetAsync(id); + await _identityRoleAppService.GetAllListAsync(); + var model = await CreateViewModel(user); - return PartialView(identityUser); + return PartialView("_Update", model); + } + + private async Task CreateViewModel(IdentityUserDto user) + { + var allRoles = await _identityRoleAppService.GetAllListAsync(); + + var model = new CreateOrUpdateUserViewModel + { + User = user ?? new IdentityUserDto(), + Roles = ObjectMapper.Map, IdentityUserRoleDto[]>(allRoles) + }; + + var userRoles = new List(); + + if (user != null) + { + userRoles = (await _identityUserAppService.GetRolesAsync(user.Id)).Items.ToList(); + } + + foreach (var role in model.Roles) + { + if (userRoles.Select(x=>x.Name).Contains(role.Name)) + { + role.IsAssigned = true; + } + } + + return model; } } } diff --git a/src/Volo.Abp.Identity.Web/Areas/Identity/Models/CreateOrUpdateUserViewModel.cs b/src/Volo.Abp.Identity.Web/Areas/Identity/Models/CreateOrUpdateUserViewModel.cs new file mode 100644 index 0000000000..5f92205779 --- /dev/null +++ b/src/Volo.Abp.Identity.Web/Areas/Identity/Models/CreateOrUpdateUserViewModel.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.Identity.Web.Areas.Identity.Models +{ + public class CreateOrUpdateUserViewModel + { + public IdentityUserDto User { get; set; } + public IdentityUserRoleDto[] Roles { get; set; } + } +} diff --git a/src/Volo.Abp.Identity.Web/Areas/Identity/Views/Users/_Create.cshtml b/src/Volo.Abp.Identity.Web/Areas/Identity/Views/Users/_Create.cshtml index 3df61db2ab..f48c141f13 100644 --- a/src/Volo.Abp.Identity.Web/Areas/Identity/Views/Users/_Create.cshtml +++ b/src/Volo.Abp.Identity.Web/Areas/Identity/Views/Users/_Create.cshtml @@ -1,4 +1,4 @@ -@model Volo.Abp.Identity.IdentityUserCreateOrUpdateOutput +@model Volo.Abp.Identity.Web.Areas.Identity.Controllers.CreateOrUpdateUserViewModel