Files

66 lines
2.3 KiB
C#
Raw Permalink Normal View History

2026-10-07 21:10:58 +02:00
using MongoDB.Entities;
using PrivaPub.Federation.Actors;
using PrivaPub.Federation.Objects;
using PrivaPub.Models.Social;
using PrivaPub.Models.User;
using PrivaPub.StaticServices;
using System.Text.Json.Nodes;
using static PrivaPub.Federation.Objects.ActivityJson;
namespace PrivaPub.Federation.Inbox.Handlers
{
// Lemmy 1.0 tells a report's sender that it was dealt with: Resolve{Flag}, the Flag being one we sent
// (`/grunts/flag-<report id>`). It is believed from the server holding what was reported, or the community it was
// reported to, and kept on the report beside our own moderators' resolution, which it never replaces.
public class ResolveHandler : IActivityHandler
{
const string FlagMarker = "/grunts/flag-";
readonly DbEntities _dbEntities;
readonly ILocalActorService _localActors;
public ResolveHandler(DbEntities dbEntities, ILocalActorService localActors)
{
_dbEntities = dbEntities;
_localActors = localActors;
}
public string Type => "Resolve";
public async Task Handle(JsonNode activity, ForeignAvatar actor, CancellationToken token)
{
var flag = activity["object"];
var flagId = Id(flag);
var marker = flagId?.IndexOf(FlagMarker, StringComparison.Ordinal) ?? -1;
if (flag is JsonObject && Value(flag, "type") != "Flag" || marker < 0
|| !flagId.StartsWith(_localActors.BaseAddress + "/", StringComparison.OrdinalIgnoreCase))
{
Arrival.Drop("not-ours");
return;
}
var reportId = flagId[(marker + FlagMarker.Length)..].Split('-')[0];
var report = await DB.Default.Find<Report>().MatchID(reportId).ExecuteFirstAsync(token);
if (report == default)
{
Arrival.Drop("unknown-object");
return;
}
var concerned = new List<string>(report.ObjectURIs) { report.TargetActorURI };
foreach (var post in report.PostIds.Count == 0 ? new List<Models.Post.Post>() : await _dbEntities.Posts.Match(p => report.PostIds.Contains(p.ID)).ExecuteAsync(token))
concerned.Add(await Communities.Of(post, _dbEntities, token));
if (!concerned.Any(uri => Origin.Same(uri, actor.ActorURI)))
{
Arrival.Drop("misattributed");
return;
}
await DB.Default.Update<Report>().MatchID(report.ID)
.Modify(r => r.RemoteResolvedAt, DateTime.UtcNow)
.Modify(r => r.RemoteResolvedBy, actor.ActorURI)
.ExecuteAsync(token);
Arrival.Accept("resolved");
}
}
}