59 lines
2.2 KiB
C#
59 lines
2.2 KiB
C#
using MongoDB.Entities;
|
|||
|
|
|
||
|
|
using PrivaPub.Models;
|
||
|
|
using PrivaPub.Models.User;
|
||
|
|
|
||
|
|
namespace PrivaPub.Domain.Moderation
|
||
|
|
{
|
||
|
|
public interface IModerationLog
|
||
|
|
{
|
||
|
|
/// <summary>Keeps one act of the staff (Models/AdminAction.cs). Never throws: an act that was done stays done when
|
||
|
|
/// its entry can't be written, and the failure is logged.</summary>
|
||
|
|
Task Write(string byRootId, string action, string targetKind, string targetId, string targetLabel, string reportId = default, string note = default,
|
||
|
|
CancellationToken token = default);
|
||
|
|
}
|
||
|
|
|
||
|
|
// The staff's log (completion program R5): administrators read all of it, moderators what isn't about a login
|
||
|
|
// (ModeratorController's /clientapi/moderator/log). An entry never holds an IP address, and never pairs a root with its
|
||
|
|
// own personas: an act on a persona that the acting root owns is kept without who acted.
|
||
|
|
public class ModerationLog : IModerationLog
|
||
|
|
{
|
||
|
|
const int MaxLabel = 200;
|
||
|
|
const int MaxNote = 1000;
|
||
|
|
|
||
|
|
readonly ILogger<ModerationLog> _logger;
|
||
|
|
|
||
|
|
public ModerationLog(ILogger<ModerationLog> logger)
|
||
|
|
{
|
||
|
|
_logger = logger;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task Write(string byRootId, string action, string targetKind, string targetId, string targetLabel, string reportId = default,
|
||
|
|
string note = default, CancellationToken token = default)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (targetKind == AdminTargets.Persona && byRootId != default && byRootId != AdminAction.Cli && targetId != default
|
||
|
|
&& await DB.Default.Find<RootToAvatar>().Match(r => r.RootId == byRootId && r.AvatarId == targetId).ExecuteAnyAsync(token))
|
||
|
|
byRootId = default;
|
||
|
|
await DB.Default.SaveAsync(new AdminAction
|
||
|
|
{
|
||
|
|
ByRootId = byRootId,
|
||
|
|
Action = action,
|
||
|
|
TargetKind = targetKind,
|
||
|
|
TargetId = targetId,
|
||
|
|
TargetLabel = Cut(targetLabel, MaxLabel),
|
||
|
|
ReportId = reportId,
|
||
|
|
Note = Cut(note, MaxNote)
|
||
|
|
}, CancellationToken.None);//an act that was done is logged even when its request went away
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
_logger.LogWarning(ex, "The staff's log could not keep a {Action}", action);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static string Cut(string text, int max) =>
|
||
|
|
string.IsNullOrEmpty(text) ? text : text.Length <= max ? text : text[..(max - 1)] + "…";
|
||
|
|
}
|
||
|
|
}
|