Ajoute une zone d'administration des utilisateurs
This commit is contained in:
@@ -106,6 +106,23 @@ public sealed class MySqlUserProfileStore(
|
||||
LIMIT 1;
|
||||
""";
|
||||
|
||||
private const string SelectAllProfilesSql = """
|
||||
SELECT
|
||||
subject,
|
||||
username,
|
||||
email,
|
||||
display_name,
|
||||
club,
|
||||
city,
|
||||
preferred_format,
|
||||
favorite_cube,
|
||||
bio,
|
||||
created_utc,
|
||||
updated_utc
|
||||
FROM site_users
|
||||
ORDER BY updated_utc DESC, created_utc DESC, username ASC;
|
||||
""";
|
||||
|
||||
private readonly SiteDataOptions _options = options.Value;
|
||||
private readonly ILogger<MySqlUserProfileStore> _logger = logger;
|
||||
|
||||
@@ -198,9 +215,82 @@ public sealed class MySqlUserProfileStore(
|
||||
return await ReadProfileAsync(connection, user.Subject, cancellationToken);
|
||||
}
|
||||
|
||||
private static UserProfileInput NormalizeInput(AuthenticatedSiteUser user, UpdateUserProfileRequest request)
|
||||
public void ValidateAdminUpdate(string fallbackDisplayName, UpdateUserProfileRequest request)
|
||||
=> _ = NormalizeInput(fallbackDisplayName, request);
|
||||
|
||||
public async Task<IReadOnlyList<UserProfileResponse>> ListAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var displayName = NormalizeOptionalValue(request.DisplayName, "nom affiche", 120) ?? user.DisplayName;
|
||||
await using var connection = new MySqlConnection(_options.BuildConnectionString());
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = SelectAllProfilesSql;
|
||||
|
||||
var profiles = new List<UserProfileResponse>();
|
||||
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
||||
while (await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
profiles.Add(MapProfile(reader));
|
||||
}
|
||||
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public async Task<UserProfileResponse?> FindBySubjectAsync(string subject, CancellationToken cancellationToken)
|
||||
{
|
||||
await using var connection = new MySqlConnection(_options.BuildConnectionString());
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = SelectProfileSql;
|
||||
command.Parameters.AddWithValue("@subject", subject);
|
||||
|
||||
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
||||
return await reader.ReadAsync(cancellationToken)
|
||||
? MapProfile(reader)
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task<UserProfileResponse> AdminUpsertAsync(
|
||||
string subject,
|
||||
string username,
|
||||
string? email,
|
||||
string fallbackDisplayName,
|
||||
UpdateUserProfileRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var input = NormalizeInput(fallbackDisplayName, request);
|
||||
await using var connection = new MySqlConnection(_options.BuildConnectionString());
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
var nowUtc = DateTime.UtcNow;
|
||||
|
||||
await using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = UpsertProfileSql;
|
||||
command.Parameters.AddWithValue("@subject", subject);
|
||||
command.Parameters.AddWithValue("@username", username);
|
||||
command.Parameters.AddWithValue("@email", (object?)email ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@displayName", input.DisplayName);
|
||||
command.Parameters.AddWithValue("@club", (object?)input.Club ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@city", (object?)input.City ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@preferredFormat", (object?)input.PreferredFormat ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@favoriteCube", (object?)input.FavoriteCube ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@bio", (object?)input.Bio ?? DBNull.Value);
|
||||
command.Parameters.AddWithValue("@createdUtc", nowUtc);
|
||||
command.Parameters.AddWithValue("@updatedUtc", nowUtc);
|
||||
await command.ExecuteNonQueryAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return await ReadProfileAsync(connection, subject, cancellationToken);
|
||||
}
|
||||
|
||||
private static UserProfileInput NormalizeInput(AuthenticatedSiteUser user, UpdateUserProfileRequest request)
|
||||
=> NormalizeInput(user.DisplayName, request);
|
||||
|
||||
private static UserProfileInput NormalizeInput(string fallbackDisplayName, UpdateUserProfileRequest request)
|
||||
{
|
||||
var displayName = NormalizeOptionalValue(request.DisplayName, "nom affiche", 120) ?? fallbackDisplayName;
|
||||
var club = NormalizeOptionalValue(request.Club, "club", 120);
|
||||
var city = NormalizeOptionalValue(request.City, "ville", 120);
|
||||
var favoriteCube = NormalizeOptionalValue(request.FavoriteCube, "cube favori", 120);
|
||||
@@ -258,6 +348,11 @@ public sealed class MySqlUserProfileStore(
|
||||
throw new InvalidOperationException("Le profil utilisateur n'a pas pu etre charge.");
|
||||
}
|
||||
|
||||
return MapProfile(reader);
|
||||
}
|
||||
|
||||
private static UserProfileResponse MapProfile(MySqlDataReader reader)
|
||||
{
|
||||
var subjectOrdinal = reader.GetOrdinal("subject");
|
||||
var usernameOrdinal = reader.GetOrdinal("username");
|
||||
var emailOrdinal = reader.GetOrdinal("email");
|
||||
|
||||
Reference in New Issue
Block a user