Add user update endpoint and DTO

Introduce ChangeUserRequest DTO (UserName, IsActive) and add UpdateAppUser action to AppUserController. The new endpoint allows updating a user's username and active state, trims and validates the username, checks for duplicates, updates the Identity security stamp when deactivating to invalidate sessions, and returns appropriate success or error responses.
This commit is contained in:
Jonas
2026-05-01 15:22:42 +02:00
parent 7e2ca4c9e2
commit b29d174141
2 changed files with 66 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
namespace API.Contracts.Auth
{
public class ChangeUserRequest
{
public string? UserName { get; set; }
public bool? IsActive { get; set; }
}
}
+58
View File
@@ -35,5 +35,63 @@ namespace API.Controllers.Auth
return Ok(await user.ToCurrentUserResponseAsync(userManager));
}
[HttpPost("{id:guid")]
public async Task<IActionResult> UpdateAppUser([FromRoute] Guid id, [FromBody] ChangeUserRequest changeDto)
{
var user = await userManager.Users.FirstOrDefaultAsync(x => x.Id == id);
if (user is null)
{
return NotFound(new { message = "Benutzer wurde nicht gefunden." });
}
if (changeDto.IsActive != null)
{
user.IsActive = changeDto.IsActive.Value;
if (!changeDto.IsActive.Value)
{
var stampResult = await userManager.UpdateSecurityStampAsync(user);
if (!stampResult.Succeeded)
{
return StatusCode(500, new { message = "Benutzer wurde auf geändert, aber Sessions konnten nicht invalidiert werden. " +
"Er könnte also immer noch Angemeldet sein!" });
}
}
}
if (changeDto.UserName != null)
{
var newUserName = changeDto.UserName.Trim();
if (string.IsNullOrEmpty(newUserName))
{
return BadRequest(new { message = "Benutzername darf nicht leer sein." });
}
if (!string.Equals(newUserName, user.UserName, StringComparison.OrdinalIgnoreCase))
{
var existing = await userManager.FindByNameAsync(newUserName);
if (existing is not null && existing.Id != user.Id)
{
return Conflict(new { message = "Benutzername ist bereits vergeben." });
}
var setNameResult = await userManager.SetUserNameAsync(user, newUserName);
if (!setNameResult.Succeeded)
{
if (setNameResult.Errors.Any(e => e.Code == nameof(IdentityErrorDescriber.DuplicateUserName)))
{
return Conflict(new { message = "Benutzername ist bereits vergeben." });
}
return BadRequest(new { message = "Benutzername konnte nicht geändert werden.", errors = setNameResult.Errors.Select(e => e.Description) });
}
}
}
return Ok(await user.ToCurrentUserResponseAsync(userManager));
}
}
}