Allow Users to be disabled/enabled (#3639)

* Allow Users to be disabled/enabled

* rebrand to locked for api

* Update BTCPayServer/Views/UIAccount/Lockout.cshtml

Co-authored-by: d11n <mail@dennisreimann.de>

* fix docker compose and an uneeded check in api handler

* fix

* Add enabled user test

Co-authored-by: d11n <mail@dennisreimann.de>
Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>
This commit is contained in:
Andrew Camilleri
2022-04-26 14:27:35 +02:00
committed by GitHub
parent 261a3ecee3
commit 273bc78db3
16 changed files with 290 additions and 61 deletions

View File

@@ -64,7 +64,8 @@ namespace BTCPayServer.Controllers
Id = u.Id,
Verified = u.EmailConfirmed || !u.RequiresEmailConfirmation,
Created = u.Created,
Roles = u.UserRoles.Select(role => role.RoleId)
Roles = u.UserRoles.Select(role => role.RoleId),
Disabled = u.LockoutEnabled && u.LockoutEnd != null && DateTimeOffset.UtcNow < u.LockoutEnd.Value.UtcDateTime
})
.ToListAsync();
model.Total = await usersQuery.CountAsync();
@@ -217,12 +218,11 @@ namespace BTCPayServer.Controllers
var roles = await _UserManager.GetRolesAsync(user);
if (_userService.IsRoleAdmin(roles))
{
var admins = await _UserManager.GetUsersInRoleAsync(Roles.ServerAdmin);
if (admins.Count == 1)
if (await _userService.IsUserTheOnlyOneAdmin(user))
{
// return
return View("Confirm", new ConfirmModel("Delete admin",
$"Unable to proceed: As the user <strong>{user.Email}</strong> is the last admin, it cannot be removed."));
$"Unable to proceed: As the user <strong>{user.Email}</strong> is the last enabled admin, it cannot be removed."));
}
return View("Confirm", new ConfirmModel("Delete admin",
@@ -245,6 +245,41 @@ namespace BTCPayServer.Controllers
TempData[WellKnownTempData.SuccessMessage] = "User deleted";
return RedirectToAction(nameof(ListUsers));
}
[HttpGet("server/users/{userId}/toggle")]
public async Task<IActionResult> ToggleUser(string userId, bool enable)
{
var user = userId == null ? null : await _UserManager.FindByIdAsync(userId);
if (user == null)
return NotFound();
if (!enable && await _userService.IsUserTheOnlyOneAdmin(user))
{
return View("Confirm", new ConfirmModel("Disable admin",
$"Unable to proceed: As the user <strong>{user.Email}</strong> is the last enabled admin, it cannot be disabled."));
}
return View("Confirm", new ConfirmModel($"{(enable? "Enable" : "Disable")} user", $"The user <strong>{user.Email}</strong> will be {(enable? "enabled" : "disabled")}. Are you sure?", (enable? "Enable" : "Disable")));
}
[HttpPost("server/users/{userId}/toggle")]
public async Task<IActionResult> ToggleUserPost(string userId, bool enable)
{
var user = userId == null ? null : await _UserManager.FindByIdAsync(userId);
if (user == null)
return NotFound();
if (!enable && await _userService.IsUserTheOnlyOneAdmin(user))
{
TempData[WellKnownTempData.SuccessMessage] = $"User was the last enabled admin and could not be disabled.";
return RedirectToAction(nameof(ListUsers));
}
await _userService.ToggleUser(userId, enable? null: DateTimeOffset.MaxValue);
TempData[WellKnownTempData.SuccessMessage] = $"User {(enable? "enabled": "disabled")}";
return RedirectToAction(nameof(ListUsers));
}
}
public class RegisterFromAdminViewModel