Files
Wollmilchsau/Wollmilchsau/Services/Moodle/MoodleService.cs
T
2026-08-24 15:23:53 +02:00

83 lines
3.1 KiB
C#

using System.Net.Http.Json;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Wollmilchsau.Models;
namespace Wollmilchsau.Services.Moodle;
public sealed class MoodleService(HttpClient httpClient, IOptions<MoodleOptions> options) : IMoodleService
{
private readonly MoodleOptions _options = options.Value;
public async Task<IReadOnlyCollection<MoodleUser>> GetAllUsers(CancellationToken cancellationToken = default)
{
var requestUri = QueryHelpers.AddQueryString(
string.Empty,
new Dictionary<string, string?>
{
["wstoken"] = _options.WsToken,
["wsfunction"] = "core_user_get_users",
["moodlewsrestformat"] = "json",
["criteria[0][key]"] = "lastname",
["criteria[0][value]"] = "%"
});
using var response = await httpClient.GetAsync(requestUri, cancellationToken);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<MoodleUserSearchResponse>(cancellationToken);
if (result is null)
{
throw new InvalidOperationException("Moodle returned an empty user search response.");
}
if (!string.IsNullOrWhiteSpace(result.Exception))
{
throw new InvalidOperationException($"Moodle user search failed with {result.ErrorCode ?? "an unspecified error"}: {result.Message ?? result.Exception}.");
}
return result.Users ?? throw new InvalidOperationException("Moodle user search response did not contain users.");
}
public async Task DeleteUsers(IReadOnlyCollection<int> userIds, CancellationToken cancellationToken = default)
{
if (userIds.Count == 0)
{
throw new ArgumentException("At least one Moodle user ID is required.", nameof(userIds));
}
var query = new QueryBuilder
{
{ "wstoken", _options.WsToken },
{ "wsfunction", "core_user_delete_users" },
{ "moodlewsrestformat", "json" }
};
foreach (var (userId, index) in userIds.Distinct().Select((userId, index) => (userId, index)))
{
query.Add($"userids[{index}]", userId.ToString());
}
using var response = await httpClient.GetAsync(query.ToQueryString().Value, cancellationToken);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<MoodleDeletionResponse>(cancellationToken);
if (!string.IsNullOrWhiteSpace(result?.Exception))
{
throw new InvalidOperationException($"Moodle user deletion failed with {result.ErrorCode ?? "an unspecified error"}: {result.Message ?? result.Exception}.");
}
}
private sealed record MoodleUserSearchResponse(
IReadOnlyCollection<MoodleUser>? Users,
string? Exception,
string? ErrorCode,
string? Message);
private sealed record MoodleDeletionResponse(
string? Exception,
string? ErrorCode,
string? Message);
}