diff --git a/UserManagement.API/Controllers/AuthController.cs b/UserManagement.API/Controllers/AuthController.cs index 7f5d23e..5fdca72 100644 --- a/UserManagement.API/Controllers/AuthController.cs +++ b/UserManagement.API/Controllers/AuthController.cs @@ -29,7 +29,7 @@ namespace UserManagement.API.Controllers public async Task Login([FromBody] LoginDto login) { // Validate user - var user = await _userService.GetByUsernameAsync(login.Username, includeRoles: true); + var user = await _userService.GetUserByUsernameAsync(login.Username, includeRoles: true); if (user is null) { return Unauthorized("Benutzername und Passwort stimmen nicht überein!"); diff --git a/UserManagement.API/Controllers/RoleController.cs b/UserManagement.API/Controllers/RoleController.cs index d9b01a0..fc6d4ae 100644 --- a/UserManagement.API/Controllers/RoleController.cs +++ b/UserManagement.API/Controllers/RoleController.cs @@ -13,9 +13,11 @@ namespace UserManagement.API.Controllers { // CTOR private readonly IRoleService _roleService; - public RoleController(IRoleService roleService) + private readonly ILogger _logger; + public RoleController(IRoleService roleService, ILogger logger) { _roleService = roleService; + _logger = logger; } // CREATE @@ -26,7 +28,6 @@ namespace UserManagement.API.Controllers [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task CreateRole([FromBody] CreatingRoleDto creatingRoleDto) { - // Validate incomming model if (!ModelState.IsValid) { return BadRequest(ModelState); @@ -34,25 +35,20 @@ namespace UserManagement.API.Controllers try { - // Try to add role asynchronously - var result = await _roleService.AddRoleAsync(creatingRoleDto); + var createdRole = await _roleService.AddRoleAsync(creatingRoleDto); - // If role is successfully created, return a CreatedAtAction response with the created resource - if (result is not null) + if (createdRole is not null) { - var id = result.Id; - var createdResource = new { Id = id }; - var actionName = nameof(GetRoleById); - var routeValue = new { id = createdResource.Id }; - return CreatedAtAction(actionName, routeValue, createdResource); + return CreatedAtAction(nameof(GetRoleById), new { id = createdRole.Id }, createdRole); } else { - return BadRequest("geht nix"); + return BadRequest("Erstellung der Rolle fehlgeschlagen!"); } } catch (Exception ex) { + _logger.LogError(ex, ex.Message); return StatusCode(StatusCodes.Status500InternalServerError, ex.Message); } } @@ -61,95 +57,145 @@ namespace UserManagement.API.Controllers [HttpGet] [SwaggerOperation(Summary = "Get all Roles")] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task GetRoles() + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetAllRoles() { - var roles = await _roleService.GetAllAsync(); - return Ok(roles); + try + { + var roles = await _roleService.GetAllRolesAsync(); + return Ok(roles); + } + catch (KeyNotFoundException ex) + { + return NotFound(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } // READ BY ID - [HttpGet("id/{id}", Name = "GetRoleById")] + [HttpGet("roleId/{id}", Name = "GetRoleById")] [SwaggerOperation(Summary = "Get Role by Id")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetRoleById(int id) + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetRoleById([FromRoute] int id) { - if (id <= 0) + try { - return BadRequest("Invalid Id"); + var role = await _roleService.GetRoleByIdAsync(id); + return Ok(role); } - var role = await _roleService.GetByIdAsync(id); - if (role == null) + catch (ArgumentException ex) { - return NotFound(); + return BadRequest(ex.Message); + } + catch (KeyNotFoundException ex) + { + return NotFound(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } - return Ok(role); } // READ BY NAME - [HttpGet("name/{name}", Name = "GetRoleByName")] + [HttpGet("rolename/{name}", Name = "GetRoleByName")] [SwaggerOperation(Summary = "Get Role by Name")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetRoleByName(string name) + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetRoleByName([FromRoute] string name) { - if (string.IsNullOrEmpty(name)) + try { - return BadRequest("Name cannot be empty"); + var role = await _roleService.GetRoleByNameAsync(name); + return Ok(role); } - var role = await _roleService.GetByNameAsync(name); - if (role == null) + catch (ArgumentException ex) { - return NotFound(); + return BadRequest(ex.Message); + } + catch (KeyNotFoundException ex) + { + return NotFound(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } - return Ok(role); } // UPDATE - [HttpPut("id/{id}", Name = "UpdateRole")] + [HttpPut("roleId/{id}", Name = "UpdateRole")] [SwaggerOperation(Summary = "Update Role")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task UpdateRole(int id, UpdatingRoleDto updatingRoleDto) + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task UpdateRole([FromRoute] int id,[FromBody] UpdatingRoleDto updatingRoleDto) { - if (id <= 0) + if (!ModelState.IsValid) { - return BadRequest("Invalid Id"); + return BadRequest(ModelState); } - var updated = await _roleService.UpdateRoleAsync(updatingRoleDto); - - if (!updated) + try { - return BadRequest("Update failed"); + var updated = await _roleService.UpdateRoleAsync(updatingRoleDto); + return NoContent(); + } + catch (ArgumentException ex) + { + return BadRequest(ex.Message); + } + catch (KeyNotFoundException ex) + { + return NotFound(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } - - return Ok(updated); } // DELETE - [HttpDelete("id/{id}", Name = "DeleteRole")] + [HttpDelete("roleId/{id}", Name = "DeleteRole")] [SwaggerOperation(Summary = "Delete Role")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task DeleteRole([FromRoute] int id) { - if (id <= 0) + try { - return BadRequest("Invalid Id"); + var deleted = await _roleService.DeleteRoleAsync(id); + return NoContent(); } - - var deleted = await _roleService.DeleteRoleAsync(id); - - if (!deleted) + catch (ArgumentException ex) { - return BadRequest("Deletion failed"); + return BadRequest(ex.Message); + } + catch (KeyNotFoundException ex) + { + return NotFound(ex.Message); + } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } - - return Ok(); } } } diff --git a/UserManagement.API/Controllers/UserController.cs b/UserManagement.API/Controllers/UserController.cs index 5314c41..99031bf 100644 --- a/UserManagement.API/Controllers/UserController.cs +++ b/UserManagement.API/Controllers/UserController.cs @@ -26,7 +26,6 @@ namespace UserManagement.API.Controllers [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - [Authorize(Roles = "Admin")] public async Task CreateUser([FromBody] CreatingUserDto creatingUserDto) { if (!ModelState.IsValid) @@ -49,7 +48,8 @@ namespace UserManagement.API.Controllers } catch (Exception ex) { - return StatusCode(StatusCodes.Status500InternalServerError, ex.Message); + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } } @@ -58,30 +58,37 @@ namespace UserManagement.API.Controllers [SwaggerOperation(Summary = "Get all Users")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task GetAllUsers([FromQuery] bool includeRoles = true) { try { - var users = await _userService.GetUsersAsync(includeRoles); + var users = await _userService.GetAllUsersAsync(includeRoles); return Ok(users); } catch (KeyNotFoundException ex) { return NotFound(ex.Message); } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } // READ BY ID - [HttpGet("id/{id}", Name = "GetUserById")] + [HttpGet("userId/{id}", Name = "GetUserById")] [SwaggerOperation(Summary = "Get User by Id")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetUserById(int id, [FromQuery] bool includeRoles = true) + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetUserById([FromRoute] int id, [FromQuery] bool includeRoles = true) { try { - var user = await _userService.GetByIdAsync(id, includeRoles); + var user = await _userService.GetUserByIdAsync(id, includeRoles); return Ok(user); } catch (ArgumentException ex) @@ -92,6 +99,11 @@ namespace UserManagement.API.Controllers { return NotFound(ex.Message); } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } // READ BY USERNAME @@ -100,11 +112,12 @@ namespace UserManagement.API.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetUserByUsername(string username, [FromQuery] bool includeRoles = true) + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetUserByUsername([FromRoute] string username, [FromQuery] bool includeRoles = true) { try { - var user = await _userService.GetByUsernameAsync(username, includeRoles); + var user = await _userService.GetUserByUsernameAsync(username, includeRoles); return Ok(user); } catch (ArgumentException ex) @@ -115,6 +128,11 @@ namespace UserManagement.API.Controllers { return NotFound(ex.Message); } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } // READ BY ROLE @@ -123,11 +141,12 @@ namespace UserManagement.API.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task GetUsersByRole(string role) + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task GetUsersByRole([FromRoute] string role) { try { - var users = await _userService.GetByRoleAsync(role); + var users = await _userService.GetUsersByRoleAsync(role); return Ok(users); } catch (ArgumentException ex) @@ -138,20 +157,31 @@ namespace UserManagement.API.Controllers { return NotFound(ex.Message); } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } // UPDATE - [HttpPut("id/{id}", Name = "UpdateUser")] + [HttpPut("userId/{id}", Name = "UpdateUser")] [SwaggerOperation(Summary = "Update User")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task UpdateUser(int id, UpdatingUserDto updatingUserDto) + public async Task UpdateUser([FromRoute] int id, [FromBody] UpdatingUserDto updatingUserDto) { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + try { var updated = await _userService.UpdateUserAsync(updatingUserDto); - return Ok(updated); + return NoContent(); } catch (ArgumentException ex) { @@ -169,17 +199,18 @@ namespace UserManagement.API.Controllers } // DELETE - [HttpDelete("id/{id}", Name = "DeleteUser")] + [HttpDelete("userId/{id}", Name = "DeleteUser")] [SwaggerOperation(Summary = "Delete User")] [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task DeleteUser([FromBody] int id) + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task DeleteUser([FromRoute] int id) { try { var deleted = await _userService.DeleteUserAsync(id); - return Ok(deleted); + return NoContent(); } catch (ArgumentException ex) { @@ -189,6 +220,11 @@ namespace UserManagement.API.Controllers { return NotFound(ex.Message); } + catch (Exception ex) + { + _logger.LogError(ex, ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } } } } diff --git a/UserManagement.App/Interfaces/IRoleService.cs b/UserManagement.App/Interfaces/IRoleService.cs index 282f00f..17fc532 100644 --- a/UserManagement.App/Interfaces/IRoleService.cs +++ b/UserManagement.App/Interfaces/IRoleService.cs @@ -10,13 +10,13 @@ namespace UserManagement.Application.Interfaces Task AddRoleAsync(CreatingRoleDto creatingRoleDto); // READ ALL - Task> GetAllAsync(); + Task> GetAllRolesAsync(); // READ BY ID - Task GetByIdAsync(int id); + Task GetRoleByIdAsync(int id); // READ BY NAME - Task GetByNameAsync(string name); + Task GetRoleByNameAsync(string name); // UPDATE Task UpdateRoleAsync(UpdatingRoleDto updatingRoleDto); diff --git a/UserManagement.App/Interfaces/IUserService.cs b/UserManagement.App/Interfaces/IUserService.cs index 3e7b3fd..e3c4b50 100644 --- a/UserManagement.App/Interfaces/IUserService.cs +++ b/UserManagement.App/Interfaces/IUserService.cs @@ -10,16 +10,16 @@ namespace UserManagement.Application.Interfaces Task AddUserAsync(CreatingUserDto creatingUserDto); // READ ALL - Task> GetUsersAsync(bool includeRoles = true); + Task> GetAllUsersAsync(bool includeRoles = true); // READ BY ID - Task GetByIdAsync(int id, bool includeRoles = true); + Task GetUserByIdAsync(int id, bool includeRoles = true); // READ BY USERNAME - Task GetByUsernameAsync(string username, bool includeRoles = true); + Task GetUserByUsernameAsync(string username, bool includeRoles = true); // READ BY ROLE - Task> GetByRoleAsync(string role); + Task> GetUsersByRoleAsync(string role); // UPDATE Task UpdateUserAsync(UpdatingUserDto updatingUserDto); diff --git a/UserManagement.App/Services/RoleService.cs b/UserManagement.App/Services/RoleService.cs index e5d5c19..45d8b85 100644 --- a/UserManagement.App/Services/RoleService.cs +++ b/UserManagement.App/Services/RoleService.cs @@ -22,51 +22,103 @@ namespace UserManagement.Application.Services public async Task AddRoleAsync(CreatingRoleDto creatingRoleDto) { var role = _mapper.Map(creatingRoleDto); + var created = await _roleRepository.AddAsync(role); + return created; } // READ ALL - public async Task> GetAllAsync() + public async Task> GetAllRolesAsync() { var roles = await _roleRepository.GetAllAsync(); + + if (roles == null) + { + throw new KeyNotFoundException("Keine Rollen gefunden!"); + } + var readDto = _mapper.Map>(roles); + return readDto; } // READ BY ID - public async Task GetByIdAsync(int id) + public async Task GetRoleByIdAsync(int id) { + if (id <= 0) + { + throw new ArgumentException("Ungültige Id!"); + } + var role = await _roleRepository.GetByIdAsync(id); + + if (role == null) + { + throw new KeyNotFoundException("Rolle nicht gefunden!"); + } + var readDto = _mapper.Map(role); return readDto; } // READ BY NAME - public async Task GetByNameAsync(string name) + public async Task GetRoleByNameAsync(string name) { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentException("Ungültiger Rollenname!"); + } + var role = await _roleRepository.GetByNameAsync(name); + + if (role == null) + { + throw new KeyNotFoundException("Rolle nicht gefunden!"); + } + var readDto = _mapper.Map(role); + return readDto; } // UPDATE public async Task UpdateRoleAsync(UpdatingRoleDto updatingRoleDto) { + if (updatingRoleDto.Id <= 0) + { + throw new ArgumentException("Ungültige Id!"); + } + var role = _mapper.Map(updatingRoleDto); + + if (role == null) + { + throw new KeyNotFoundException("Rolle nicht gefunden!"); + } + bool isUpdated = await _roleRepository.UpdateAsync(role); + return isUpdated; } // DELETE public async Task DeleteRoleAsync(int id) { - Role? role = await _roleRepository.GetByIdAsync(id); + if (id <= 0) + { + throw new ArgumentException("Ungültige Id!"); + } - if (role is null) - return false; + var role = await _roleRepository.GetByIdAsync(id); + + if (role == null) + { + throw new KeyNotFoundException("Rolle nicht gefunden!"); + } bool isDeleted = await _roleRepository.DeleteAsync(role); + return isDeleted; } } diff --git a/UserManagement.App/Services/UserService.cs b/UserManagement.App/Services/UserService.cs index 1440691..6f6d3f1 100644 --- a/UserManagement.App/Services/UserService.cs +++ b/UserManagement.App/Services/UserService.cs @@ -36,7 +36,7 @@ namespace UserManagement.Application.Services } // READ ALL - public async Task> GetUsersAsync(bool includeRoles = true) + public async Task> GetAllUsersAsync(bool includeRoles = true) { var users = await _userRepository.GetAllAsync(includeRoles); @@ -51,7 +51,7 @@ namespace UserManagement.Application.Services } // READ BY ID - public async Task GetByIdAsync(int id, bool includeRoles = true) + public async Task GetUserByIdAsync(int id, bool includeRoles = true) { if (id <= 0) { @@ -71,7 +71,7 @@ namespace UserManagement.Application.Services } // READ BY USERNAME - public async Task GetByUsernameAsync(string username, bool includeRoles = true) + public async Task GetUserByUsernameAsync(string username, bool includeRoles = true) { if (string.IsNullOrEmpty(username)) { @@ -91,7 +91,7 @@ namespace UserManagement.Application.Services } // READ BY ROLE - public async Task> GetByRoleAsync(string role) + public async Task> GetUsersByRoleAsync(string role) { if (string.IsNullOrEmpty(role)) { diff --git a/UserManagement.Infrastructure/Repositories/RoleRepository.cs b/UserManagement.Infrastructure/Repositories/RoleRepository.cs index 4017010..c81cad9 100644 --- a/UserManagement.Infrastructure/Repositories/RoleRepository.cs +++ b/UserManagement.Infrastructure/Repositories/RoleRepository.cs @@ -24,19 +24,25 @@ namespace UserManagement.Infrastructure.Repositories // READ ALL public async Task> GetAllAsync() { - return await _context.Roles.ToListAsync(); + return await _context.Roles + .AsNoTracking() + .ToListAsync(); } // READ BY ID public async Task GetByIdAsync(int id) { - return await _context.Roles.FindAsync(id); + return await _context.Roles + .AsNoTracking() + .FirstOrDefaultAsync(r => r.Id == id); } // READ BY NAME public async Task GetByNameAsync(string name) { - return await _context.Roles.FirstOrDefaultAsync(n => n.Name == name); + return await _context.Roles + .AsNoTracking() + .FirstOrDefaultAsync(n => n.Name == name); } // UPDATE diff --git a/UserManagement.Infrastructure/Repositories/UserRepository.cs b/UserManagement.Infrastructure/Repositories/UserRepository.cs index 4307617..7ba0fb7 100644 --- a/UserManagement.Infrastructure/Repositories/UserRepository.cs +++ b/UserManagement.Infrastructure/Repositories/UserRepository.cs @@ -37,13 +37,10 @@ namespace UserManagement.Infrastructure.Repositories { var query = _context.Users.AsNoTracking(); - if (id > 0) - query = query.Where(u => u.Id == id); - if (includeRoles) query = query.Include(user => user.UserRoles)!.ThenInclude(ur => ur.Role); - return await query.FirstOrDefaultAsync(); + return await query.FirstOrDefaultAsync(u => u.Id == id); } // READ BY USERNAME @@ -51,13 +48,10 @@ namespace UserManagement.Infrastructure.Repositories { 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(); + return await query.FirstOrDefaultAsync(u => u.UserName == username); } // READ BY ROLE @@ -68,8 +62,6 @@ namespace UserManagement.Infrastructure.Repositories .ThenInclude(ur => ur.Role) .Where(ur => ur.UserRoles!.Any(r => r.Role!.Name == role)); - var sql = query.ToQueryString(); - return await query.ToListAsync(); }