FlexibleQueries+GetUsersByRole

This commit is contained in:
OlgunR 2024-09-17 16:54:38 +02:00
parent 556571ae78
commit dc3fb100b1
11 changed files with 94 additions and 79 deletions

View File

@ -29,7 +29,7 @@ namespace UserManagement.API.Controllers
public async Task<IActionResult> Login([FromBody] LoginDto login) public async Task<IActionResult> Login([FromBody] LoginDto login)
{ {
// Validate user // Validate user
var user = await _userService.GetByUsernameAsync(login.Username); var user = await _userService.GetByUsernameAsync(login.Username, includeRoles: true);
if (user is null) if (user is null)
{ {
return Unauthorized(); return Unauthorized();

View File

@ -25,7 +25,7 @@ namespace UserManagement.API.Controllers
[ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)] [ProducesResponseType(StatusCodes.Status500InternalServerError)]
//[Authorize(Roles = "Admin")] [Authorize(Roles = "Admin")]
public async Task<IActionResult> CreateUser([FromBody] CreatingUserDto creatingUserDto) public async Task<IActionResult> CreateUser([FromBody] CreatingUserDto creatingUserDto)
{ {
// Validate incomming model // Validate incomming model
@ -63,9 +63,9 @@ namespace UserManagement.API.Controllers
[HttpGet] [HttpGet]
[SwaggerOperation(Summary = "Get all Users")] [SwaggerOperation(Summary = "Get all Users")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> GetAllUsers() public async Task<IActionResult> GetAllUsers([FromQuery] bool includeRoles = true)
{ {
var users = await _userService.GetUsersAsync(); var users = await _userService.GetUsersAsync(includeRoles);
return Ok(users); return Ok(users);
} }
@ -75,13 +75,13 @@ namespace UserManagement.API.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUserById(int id) public async Task<IActionResult> GetUserById(int id, [FromQuery] bool includeRoles = true)
{ {
if (id <= 0) if (id <= 0)
{ {
return BadRequest("Invalid Id"); return BadRequest("Invalid Id");
} }
var user = await _userService.GetByIdAsync(id); var user = await _userService.GetByIdAsync(id, includeRoles);
if (user == null) if (user == null)
{ {
return NotFound(); return NotFound();
@ -95,13 +95,13 @@ namespace UserManagement.API.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUserByUsername(string username) public async Task<IActionResult> GetUserByUsername(string username, [FromQuery] bool includeRoles = true)
{ {
if (string.IsNullOrEmpty(username)) if (string.IsNullOrEmpty(username))
{ {
return BadRequest("Username connot be empty"); return BadRequest("Username connot be empty");
} }
var user = await _userService.GetByUsernameAsync(username); var user = await _userService.GetByUsernameAsync(username, includeRoles);
if (user == null) if (user == null)
{ {
return NotFound(); return NotFound();
@ -109,6 +109,22 @@ namespace UserManagement.API.Controllers
return Ok(user); return Ok(user);
} }
// READ BY ROLE
[HttpGet("role/{role}", Name = "GetUsersByRole")]
[SwaggerOperation(Summary = "Get Users by Role")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUsersByRole(string role)
{
if (string.IsNullOrEmpty(role))
{
return BadRequest("Role cannot be empty");
}
var users = await _userService.GetByRoleAsync(role);
return Ok(users);
}
// UPDATE // UPDATE
[HttpPut("id/{id}", Name = "UpdateUser")] [HttpPut("id/{id}", Name = "UpdateUser")]
[SwaggerOperation(Summary = "Update User")] [SwaggerOperation(Summary = "Update User")]

View File

@ -3,6 +3,7 @@
public class ReadingUserRolesDto public class ReadingUserRolesDto
{ {
public int RoleId { get; set; } public int RoleId { get; set; }
public string RoleName { get; set; } public string RoleName { get; set; }
} }
} }

View File

@ -10,20 +10,20 @@ namespace UserManagement.Application.Interfaces
Task<User?> AddUserAsync(CreatingUserDto creatingUserDto); Task<User?> AddUserAsync(CreatingUserDto creatingUserDto);
// READ ALL // READ ALL
Task<IEnumerable<ReadingUserDto>> GetUsersAsync(); Task<IEnumerable<ReadingUserDto>> GetUsersAsync(bool includeRoles = true);
// READ BY ID // READ BY ID
Task<ReadingUserDto> GetByIdAsync(int id); Task<ReadingUserDto> GetByIdAsync(int id, bool includeRoles = true);
// READ BY USERNAME // READ BY USERNAME
Task<ReadingUserDto> GetByUsernameAsync(string username); Task<ReadingUserDto> GetByUsernameAsync(string username, bool includeRoles = true);
// READ BY ROLE
Task<IEnumerable<ReadingUserDto>> GetByRoleAsync(string role);
// UPDATE // UPDATE
Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto); Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto);
//// UPDATE USER ROLE
//Task UpdateUserRoleAsync(int userId, int roleId);
// DELETE // DELETE
Task<bool> DeleteUserAsync(int id); Task<bool> DeleteUserAsync(int id);
} }

View File

@ -33,9 +33,9 @@ namespace UserManagement.Application.MappingProfiles
CreateMap<User, ReadingUserDto>() CreateMap<User, ReadingUserDto>()
.ForMember(dest => dest.UserRoles, opt => opt.MapFrom(src => .ForMember(dest => dest.UserRoles, opt => opt.MapFrom(src =>
src.UserRoles.Select(ur => new ReadingRoleDto src.UserRoles!.Select(ur => new ReadingRoleDto
{ {
Id = ur.Role.Id, Id = ur.Role!.Id,
Name = ur.Role.Name Name = ur.Role.Name
}).ToList())); }).ToList()));

View File

@ -15,9 +15,9 @@ namespace UserManagement.Application.Services
// AUTHENTICATE // AUTHENTICATE
public async Task<bool> ValidateAsync(string username, string password) public async Task<bool> ValidateAsync(string username, string password)
{ {
var user = await _userRepository.GetByUsernameAsync(username); var user = await _userRepository.GetByUsernameAsync(username, includeRoles: true);
return BCrypt.Net.BCrypt.Verify(password, user.PasswordHash); return BCrypt.Net.BCrypt.Verify(password, user!.PasswordHash);
} }
} }
} }

View File

@ -50,29 +50,37 @@ namespace UserManagement.Application.Services
} }
// READ ALL // READ ALL
public async Task<IEnumerable<ReadingUserDto>> GetUsersAsync() public async Task<IEnumerable<ReadingUserDto>> GetUsersAsync(bool includeRoles = true)
{ {
var users = await _userRepository.GetAllAsync(); var users = await _userRepository.GetAllAsync(includeRoles);
var readDto = _mapper.Map<IEnumerable<ReadingUserDto>>(users); var readDto = _mapper.Map<IEnumerable<ReadingUserDto>>(users);
return readDto; return readDto;
} }
// READ BY ID // READ BY ID
public async Task<ReadingUserDto> GetByIdAsync(int id) public async Task<ReadingUserDto> GetByIdAsync(int id, bool includeRoles = true)
{ {
var user = await _userRepository.GetByIdAsync(id); var user = await _userRepository.GetByIdAsync(id, includeRoles);
var readDto = _mapper.Map<ReadingUserDto>(user); var readDto = _mapper.Map<ReadingUserDto>(user);
return readDto; return readDto;
} }
// READ BY USERNAME // READ BY USERNAME
public async Task<ReadingUserDto> GetByUsernameAsync(string username) public async Task<ReadingUserDto> GetByUsernameAsync(string username, bool includeRoles = true)
{ {
var user = await _userRepository.GetByUsernameAsync(username); var user = await _userRepository.GetByUsernameAsync(username, includeRoles);
var readDto = _mapper.Map<ReadingUserDto>(user); var readDto = _mapper.Map<ReadingUserDto>(user);
return readDto; return readDto;
} }
// READ BY ROLE
public async Task<IEnumerable<ReadingUserDto>> GetByRoleAsync(string role)
{
var users = await _userRepository.GetByRoleAsync(role);
var readDto = _mapper.Map<IEnumerable<ReadingUserDto>>(users);
return readDto;
}
// UPDATE // UPDATE
public async Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto) public async Task<bool> UpdateUserAsync(UpdatingUserDto updatingUserDto)
{ {
@ -90,7 +98,7 @@ namespace UserManagement.Application.Services
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(updatingUserDto.Password); user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(updatingUserDto.Password);
} }
user.UserRoles.Clear(); user.UserRoles!.Clear();
foreach(var roleId in updatingUserDto.RoleIds) foreach(var roleId in updatingUserDto.RoleIds)
{ {
@ -109,25 +117,6 @@ namespace UserManagement.Application.Services
return isUpdated; return isUpdated;
} }
//// UPDATE USER ROLE -- die Rolle eines Users aktualisieren
//public async Task UpdateUserRoleAsync(int userId, int roleId)
//{
// var user = await _userRepository.GetByIdAsync(userId);
// if (user == null)
// {
// throw new ArgumentException("User not found");
// }
// var role = await _roleRepository.GetByIdAsync(roleId);
// if (role == null)
// {
// throw new ArgumentException("Role not found");
// }
// user.UserRoles = roleId;
// await _userRepository.SaveAsync();
//}
// DELETE // DELETE
public async Task<bool> DeleteUserAsync(int id) public async Task<bool> DeleteUserAsync(int id)
{ {

View File

@ -16,7 +16,7 @@ namespace UserManagement.Domain.Entities
public required string Name { get; set; } public required string Name { get; set; }
[Column("USERS")] [Column("USERS")]
public ICollection<UserRole>? UserRoles { get; init; } = new Collection<UserRole>(); public ICollection<UserRole>? UserRoles { get; set; } = new Collection<UserRole>();
[Required] [Required]
[Column("CREATION_DATE", TypeName = "datetime")] [Column("CREATION_DATE", TypeName = "datetime")]

View File

@ -23,16 +23,10 @@ namespace UserManagement.Domain.Entities
[Column("LAST_NAME")] [Column("LAST_NAME")]
public string LastName { get; set; } public string LastName { get; set; }
//[Obsolete("Use password hash")]
//[Required]
//[Column("PASSWORD")]
//public required string Password { get; set; }
[Required] [Required]
[Column("PASSWORD_HASH")] [Column("PASSWORD_HASH")]
public required string PasswordHash { get; set; } public required string PasswordHash { get; set; }
[Column("ROLES")]
public ICollection<UserRole>? UserRoles { get; set; } = new Collection<UserRole>(); public ICollection<UserRole>? UserRoles { get; set; } = new Collection<UserRole>();
} }
} }

View File

@ -8,21 +8,21 @@ namespace UserManagement.Infrastructure.Interfaces
Task<User?> AddAsync(User user); Task<User?> AddAsync(User user);
// READ ALL // READ ALL
Task<IEnumerable<User>> GetAllAsync(); Task<IEnumerable<User>> GetAllAsync(bool includeRoles = true);
// READ BY ID // READ BY ID
Task<User?> GetByIdAsync(int id); Task<User?> GetByIdAsync(int id, bool includeRoles = true);
// READ BY USERNAME // READ BY USERNAME
Task<User?> GetByUsernameAsync(string username); Task<User?> GetByUsernameAsync(string username, bool includeRoles = true);
// READ BY ROLE
Task<IEnumerable<User>> GetByRoleAsync(string role);
// UPDATE // UPDATE
Task<bool> UpdateAsync(User user); Task<bool> UpdateAsync(User user);
// DELETE // DELETE
Task<bool> DeleteAsync(User user); Task<bool> DeleteAsync(User user);
// SAVE
Task<bool> SaveAsync();
} }
} }

View File

@ -22,30 +22,52 @@ namespace UserManagement.Infrastructure.Repositories
} }
// READ ALL // READ ALL
public async Task<IEnumerable<User>> GetAllAsync() public async Task<IEnumerable<User>> GetAllAsync(bool includeRoles = true)
{ {
return await _context.Users var query = _context.Users.AsNoTracking();
.Include(u => u.UserRoles)
.ThenInclude(ur => ur.Role) if (includeRoles)
.ToListAsync(); query = query.Include(user => user.UserRoles)!.ThenInclude(ur => ur.Role);
return await query.ToListAsync();
} }
// READ BY ID // READ BY ID
public async Task<User?> GetByIdAsync(int id) public async Task<User?> GetByIdAsync(int id, bool includeRoles = true)
{ {
return await _context.Users.Where(user => user.Id == id) var query = _context.Users.AsNoTracking();
.Include(user => user.UserRoles)
.ThenInclude(ur =>ur.Role) if (id > 0)
.FirstAsync(); query = query.Where(u => u.Id == id);
if (includeRoles)
query = query.Include(user => user.UserRoles)!.ThenInclude(ur => ur.Role);
return await query.FirstOrDefaultAsync();
} }
// READ BY USERNAME // READ BY USERNAME
public async Task<User?> GetByUsernameAsync(string username) public async Task<User?> GetByUsernameAsync(string username, bool includeRoles = true)
{
var query = _context.Users.AsNoTracking();
if (!string.IsNullOrEmpty(username))
query = query.Where(u => u.UserName == username);
if (includeRoles)
query = query.Include(user => user.UserRoles)!.ThenInclude(ur => ur.Role);
return await query.FirstOrDefaultAsync();
}
// READ BY ROLE
public async Task<IEnumerable<User>> GetByRoleAsync(string role)
{ {
return await _context.Users return await _context.Users
.Include(user => user.UserRoles) .Include(u => u.UserRoles)!
.ThenInclude(ur => ur.Role) .ThenInclude(ur => ur.Role)
.FirstOrDefaultAsync(u => u.UserName == username); .Where(ur => ur.UserRoles!.Any(r => r.Role!.Name == role))
.ToListAsync();
} }
// UPDATE // UPDATE
@ -63,12 +85,5 @@ namespace UserManagement.Infrastructure.Repositories
var result = await _context.SaveChangesAsync(); var result = await _context.SaveChangesAsync();
return result > 0; return result > 0;
} }
// SAVE
public async Task<bool> SaveAsync()
{
var saved = await _context.SaveChangesAsync();
return saved > 0 ? true : false;
}
} }
} }