using MongoDB.Entities; using PrivaPub.Federation.Actors; using PrivaPub.Models.Federation; 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 { public class FlagHandler : IActivityHandler { readonly DbEntities _dbEntities; readonly ILocalActorService _localActors; public FlagHandler(DbEntities dbEntities, ILocalActorService localActors) { _dbEntities = dbEntities; _localActors = localActors; } public string Type => "Flag"; public async Task Handle(JsonNode activity, ForeignAvatar actor, CancellationToken token) { var objects = activity["object"] switch { JsonArray array => array.Select(Id).Where(i => i != default).ToList(), JsonNode single when Id(single) is { } id => new List { id }, _ => new List() }; LocalActor target = default; var postUris = new List(); foreach (var uri in objects.Take(50)) { var local = await _localActors.FindByUri(uri, token); if (local is { Kind: LocalActorKind.Person } && uri.TrimEnd('/') == local.Uri) target ??= local; else postUris.Add(uri); } var posts = postUris.Count == 0 ? new List() : await _dbEntities.Posts.Match(p => postUris.Contains(p.ObjectURI) && !p.IsFederatedCopy).ExecuteAsync(token); if (target == default && posts.Count > 0) target = await _localActors.FindById(LocalActorKind.Person, posts[0].GroupUserId, token); if (target == default) { Arrival.Drop("unknown-object"); return; } Arrival.Accept("reported"); await DB.Default.SaveAsync(new Report { ReporterActorURI = actor.ActorURI, TargetAccountId = target.Id, TargetActorURI = target.Uri, PostIds = posts.Where(p => p.GroupUserId == target.Id).Select(p => p.ID).ToList(), ObjectURIs = posts.Where(p => p.GroupUserId == target.Id).Select(p => p.ObjectURI).ToList(), Comment = Value(activity, "content") }, token); } } }