LANCommander/LANCommander.Server/UI/Pages/Settings/Users/Index.razor

204 lines
6.9 KiB
Text

@page "/Settings/Users"
@using LANCommander.Server.UI.Pages.Settings.Users.Components
@inject DatabaseServiceFactory DatabaseServiceFactory
@inject ModalService ModalService
@inject IMessageService MessageService
@inject NavigationManager NavigationManager
@attribute [Authorize(Roles = RoleService.AdministratorRoleName)]
<PageHeader Title="Users" />
<div style="padding: 0 24px;">
<Table TItem="UserViewModel" DataSource="@UserList" Loading="@(Loading)" Responsive>
<PropertyColumn Property="u => u.UserName" Title="Username" />
<PropertyColumn Property="u => u.Roles">
@String.Join(", ", context.Roles)
</PropertyColumn>
<PropertyColumn Property="u => u.SavesSize" Title="Saves">
@ByteSizeLib.ByteSize.FromBytes(context.SavesSize)
</PropertyColumn>
<ActionColumn>
<Space Style="display: flex; justify-content: end">
@if (Settings.Authentication.RequireApproval && !context.Approved)
{
<SpaceItem>
<Button OnClick="() => ApproveUser(context)" Type="@ButtonType.Primary">Approve</Button>
</SpaceItem>
}
<SpaceItem>
<Button OnClick="() => ManageRoles(context)" Type="@ButtonType.Primary">Roles</Button>
</SpaceItem>
<SpaceItem>
<Button Icon="@IconType.Outline.Edit" Type="@ButtonType.Text" OnClick="@(() => NavigationManager.NavigateTo($"/Settings/Users/{context.UserName}"))" />
</SpaceItem>
<SpaceItem>
<Tooltip Title="Change Password">
<Button Icon="@IconType.Outline.Lock" Type="@ButtonType.Text" OnClick="() => ChangePassword(context)" />
</Tooltip>
</SpaceItem>
<SpaceItem>
@if (!context.Roles.Any(r => r == RoleService.AdministratorRoleName))
{
<Popconfirm OnConfirm="() => DeleteUser(context)" Title="Are you sure you want to delete this user?">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
</Popconfirm>
}
else
{
<Tooltip Title="Admins cannot be deleted. They must be demoted first.">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Disabled />
</Tooltip>
}
</SpaceItem>
</Space>
</ActionColumn>
</Table>
</div>
@code {
ICollection<UserViewModel> UserList { get; set; } = new List<UserViewModel>();
Settings Settings = SettingService.GetSettings();
bool Loading = true;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await RefreshUserList();
}
private async Task RefreshUserList()
{
UserList = new List<UserViewModel>();
using (var userService = DatabaseServiceFactory.Create<UserService>())
{
foreach (var user in await userService.GetAsync())
{
var savePath = user.GetGameSaveUploadPath();
long saveSize = 0;
if (Directory.Exists(savePath))
saveSize = new DirectoryInfo(savePath).EnumerateFiles("*", SearchOption.AllDirectories).Sum(f => f.Length);
var roles = await userService.GetRolesAsync(user.UserName);
UserList.Add(new UserViewModel()
{
Id = user.Id,
UserName = user.UserName,
Roles = roles.Select(r => r.Name).ToList(),
SavesSize = saveSize,
Approved = user.Approved
});
}
}
Loading = false;
StateHasChanged();
}
private async Task ApproveUser(UserViewModel user)
{
using (var userService = DatabaseServiceFactory.Create<UserService>())
{
var dbUser = await userService.GetAsync(user.Id);
if (dbUser != null)
{
dbUser.Approved = true;
dbUser.ApprovedOn = DateTime.UtcNow;
await userService.UpdateAsync(dbUser);
user.Approved = true;
await MessageService.Success($"Approved {user.UserName}!");
}
}
}
private async Task PromoteUser(UserViewModel user)
{
using (var userService = DatabaseServiceFactory.Create<UserService>())
{
var dbUser = await userService.GetAsync(user.Id);
await userService.AddToRoleAsync(dbUser.UserName, RoleService.AdministratorRoleName);
await MessageService.Success($"Promoted {user.UserName}!");
}
await RefreshUserList();
}
private async Task DemoteUser(UserViewModel user)
{
using (var userService = DatabaseServiceFactory.Create<UserService>())
{
var dbUser = await userService.GetAsync(user.Id);
if (UserList.SelectMany(u => u.Roles).Count(r => r == RoleService.AdministratorRoleName) == 1)
{
MessageService.Error("Cannot demote the only administrator!");
}
else
{
await userService.RemoveFromRole(dbUser.UserName, RoleService.AdministratorRoleName);
await RefreshUserList();
}
}
}
private async Task DeleteUser(UserViewModel user)
{
using (var userService = DatabaseServiceFactory.Create<UserService>())
{
var dbUser = await userService.GetAsync(user.Id);
if (UserList.SelectMany(u => u.Roles).Count(r => r == RoleService.AdministratorRoleName) == 1 && user.Roles.Contains(RoleService.AdministratorRoleName))
{
MessageService.Error("Cannot delete the only administrator!");
}
else
{
await userService.DeleteAsync(dbUser);
await RefreshUserList();
MessageService.Success($"Deleted {user.UserName}!");
}
}
}
private void ChangePassword(UserViewModel user)
{
NavigationManager.NavigateTo($"/Settings/Users/{user.Id}/ChangePassword", true);
}
private async Task ManageRoles(UserViewModel user)
{
var modalOptions = new ModalOptions()
{
Title = "ManageRoles",
Maximizable = false,
DefaultMaximized = false,
Closable = true,
Draggable = true,
OkText = "Update Roles"
};
var modalRef = await ModalService.CreateModalAsync<ManageRolesDialog, Guid, Guid>(modalOptions, user.Id);
modalRef.OnOk = async (Guid) =>
{
await RefreshUserList();
};
}
}