75 lines
2.7 KiB
C#
75 lines
2.7 KiB
C#
using MongoDB.Entities;
|
|||
|
|
|
||
|
|
using PrivaPub.Federation.Actors;
|
||
|
|
using PrivaPub.Federation.Outbox;
|
||
|
|
using PrivaPub.Federation.Rendering;
|
||
|
|
using PrivaPub.Models.Social;
|
||
|
|
using PrivaPub.Models.User;
|
||
|
|
using PrivaPub.StaticServices;
|
||
|
|
|
||
|
|
using System.Text.Json.Nodes;
|
||
|
|
|
||
|
|
namespace PrivaPub.Domain.Relationships
|
||
|
|
{
|
||
|
|
public interface IReportService
|
||
|
|
{
|
||
|
|
Task<Report> File(LocalActor reporter, string targetAccountId, IReadOnlyList<string> postIds, string comment, string category, bool forward,
|
||
|
|
CancellationToken token);
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ReportService : IReportService
|
||
|
|
{
|
||
|
|
readonly DbEntities _dbEntities;
|
||
|
|
readonly ILocalActorService _localActors;
|
||
|
|
readonly IDeliveryService _delivery;
|
||
|
|
|
||
|
|
public ReportService(DbEntities dbEntities, ILocalActorService localActors, IDeliveryService delivery)
|
||
|
|
{
|
||
|
|
_dbEntities = dbEntities;
|
||
|
|
_localActors = localActors;
|
||
|
|
_delivery = delivery;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<Report> File(LocalActor reporter, string targetAccountId, IReadOnlyList<string> postIds, string comment, string category,
|
||
|
|
bool forward, CancellationToken token)
|
||
|
|
{
|
||
|
|
var localTarget = await _dbEntities.Avatars.MatchID(targetAccountId).ExecuteFirstAsync(token);
|
||
|
|
var remoteTarget = localTarget == default ? await _dbEntities.ForeignAvatars.MatchID(targetAccountId).ExecuteFirstAsync(token) : default;
|
||
|
|
if (localTarget == default && remoteTarget == default)
|
||
|
|
return default;
|
||
|
|
var targetUri = localTarget != default ? _localActors.FromAvatar(localTarget).Uri : remoteTarget.ActorURI;
|
||
|
|
var posts = postIds.Count == 0
|
||
|
|
? new List<Models.Post.Post>()
|
||
|
|
: await _dbEntities.Posts.Match(p => postIds.Contains(p.ID) && p.ActorURI == targetUri).ExecuteAsync(token);
|
||
|
|
|
||
|
|
var report = new Report
|
||
|
|
{
|
||
|
|
ReporterAvatarId = reporter.Id,
|
||
|
|
TargetAccountId = targetAccountId,
|
||
|
|
TargetActorURI = targetUri,
|
||
|
|
PostIds = posts.Select(p => p.ID).ToList(),
|
||
|
|
ObjectURIs = posts.Select(p => p.ObjectURI).ToList(),
|
||
|
|
Comment = comment?.Trim(),
|
||
|
|
Category = category is "spam" or "legal" or "violation" ? category : "other",
|
||
|
|
Forwarded = forward && remoteTarget != default
|
||
|
|
};
|
||
|
|
await DB.Default.SaveAsync(report, token);
|
||
|
|
|
||
|
|
if (report.Forwarded)
|
||
|
|
{
|
||
|
|
var instance = await _localActors.GetInstanceActor(token);
|
||
|
|
var flag = new JsonObject
|
||
|
|
{
|
||
|
|
["@context"] = ActivityPubRenderer.ActivityStreams,
|
||
|
|
["id"] = instance.ActivityUri($"flag-{report.ID}"),
|
||
|
|
["type"] = "Flag",
|
||
|
|
["actor"] = instance.Uri,
|
||
|
|
["content"] = report.Comment ?? string.Empty,
|
||
|
|
["object"] = new JsonArray(report.ObjectURIs.Prepend(targetUri).Select(u => (JsonNode)u).ToArray())
|
||
|
|
};
|
||
|
|
await _delivery.Enqueue(instance, new[] { remoteTarget.SharedInboxURL ?? remoteTarget.InboxURL }, flag, token);
|
||
|
|
}
|
||
|
|
return report;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|