98 lines
3.1 KiB
C#
98 lines
3.1 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Microsoft.JSInterop;
|
|
using RpgRoller.Contracts;
|
|
using RpgRoller.Domain;
|
|
|
|
namespace RpgRoller.Components.Pages;
|
|
|
|
[ExcludeFromCodeCoverage]
|
|
public sealed class WorkspaceAdminCoordinator(WorkspaceState state, WorkspaceFeedbackService feedback, IJSRuntime js, RpgRollerApiClient apiClient, WorkspaceQueryService workspaceQuery, Action clearAuthenticatedState, Func<Task> stopStateEventsAsync, Func<string?, Task> onLoggedOutAsync)
|
|
{
|
|
public async Task EnsureAdminUsersLoadedAsync()
|
|
{
|
|
if (!state.IsCurrentUserAdmin || state.HasLoadedAdminUsers || state.IsAdminDataLoading)
|
|
return;
|
|
|
|
state.IsAdminDataLoading = true;
|
|
try
|
|
{
|
|
await ReloadAdminUsersAsync();
|
|
}
|
|
catch (ApiRequestException ex) when (ex.StatusCode == 401)
|
|
{
|
|
clearAuthenticatedState();
|
|
await stopStateEventsAsync();
|
|
await onLoggedOutAsync("Session expired. Please log in again.");
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
feedback.SetStatus(ex.Message, true);
|
|
}
|
|
finally
|
|
{
|
|
state.IsAdminDataLoading = false;
|
|
}
|
|
}
|
|
|
|
public async Task ToggleAdminRoleAsync(AdminUserSummary user)
|
|
{
|
|
if (state.IsMutating || state.User is null || !state.IsCurrentUserAdmin || user.Id == state.User.Id)
|
|
return;
|
|
|
|
state.IsMutating = true;
|
|
try
|
|
{
|
|
IReadOnlyList<string> roles = HasAdminRole(user) ? Array.Empty<string>() : [UserRoles.Admin];
|
|
_ = await apiClient.RequestAsync<AdminUserSummary>("PUT", $"/api/admin/users/{user.Id}/roles", new UpdateUserRolesRequest(roles));
|
|
|
|
await ReloadAdminUsersAsync();
|
|
feedback.SetStatus("User roles updated.", false);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
feedback.SetStatus(ex.Message, true);
|
|
}
|
|
finally
|
|
{
|
|
state.IsMutating = false;
|
|
}
|
|
}
|
|
|
|
public async Task DeleteUserAsync(AdminUserSummary user)
|
|
{
|
|
if (state.IsMutating || state.User is null || !state.IsCurrentUserAdmin || user.Id == state.User.Id)
|
|
return;
|
|
|
|
var confirmed = await js.InvokeAsync<bool>("confirm", $"Delete user '{user.Username}'?");
|
|
if (!confirmed)
|
|
return;
|
|
|
|
state.IsMutating = true;
|
|
try
|
|
{
|
|
_ = await apiClient.RequestAsync<bool>("DELETE", $"/api/admin/users/{user.Id}");
|
|
await ReloadAdminUsersAsync();
|
|
feedback.SetStatus("User deleted.", false);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
feedback.SetStatus(ex.Message, true);
|
|
}
|
|
finally
|
|
{
|
|
state.IsMutating = false;
|
|
}
|
|
}
|
|
|
|
private async Task ReloadAdminUsersAsync()
|
|
{
|
|
state.AdminUsers = (await workspaceQuery.GetAdminUsersAsync()).OrderBy(user => user.Username, StringComparer.OrdinalIgnoreCase).ToList();
|
|
|
|
state.HasLoadedAdminUsers = true;
|
|
}
|
|
|
|
private static bool HasAdminRole(AdminUserSummary user)
|
|
{
|
|
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
} |