Files
SocialPub/PrivaPub/Federation/Inbox/Handlers/AcceptHandler.cs
T

80 lines
2.6 KiB
C#
Raw Normal View History

using MongoDB.Entities;
using PrivaPub.Domain.Statuses;
using PrivaPub.Federation.Actors;
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 AcceptHandler : IActivityHandler
{
readonly DbEntities _dbEntities;
readonly ILocalActorService _localActors;
readonly IQuoteService _quotes;
public AcceptHandler(DbEntities dbEntities, ILocalActorService localActors, IQuoteService quotes)
{
_dbEntities = dbEntities;
_localActors = localActors;
_quotes = quotes;
}
public virtual string Type => "Accept";
public async Task Handle(JsonNode activity, ForeignAvatar actor, CancellationToken token)
{
if (await _quotes.Answered(activity, actor, accepted: Type == "Accept", token))
2026-10-03 11:04:42 +02:00
{
Arrival.Accept("quote-answer");
return;
2026-10-03 11:04:42 +02:00
}
var following = await FindFollowing(activity["object"], actor, _dbEntities, _localActors, token);
if (following == default)
2026-10-03 11:04:42 +02:00
{
Arrival.Drop("unknown-object");
return;
2026-10-03 11:04:42 +02:00
}
Arrival.About("Follow");
Arrival.Accept("follow-answer");
await Apply(following, token);
}
protected virtual Task Apply(Following following, CancellationToken token) =>
DB.Default.Update<Following>().MatchID(following.ID).Modify(f => f.State, FollowState.Accepted).ExecuteAsync(token);
public static async Task<Following> FindFollowing(JsonNode follow, ForeignAvatar target, DbEntities dbEntities, ILocalActorService localActors,
CancellationToken token)
{
if (follow is JsonObject && Value(follow, "type") is { } type && type != "Follow")
return default;
var followId = Id(follow);
var byId = followId == default
? default
: await dbEntities.Followings.Match(f => f.FollowActivityURI == followId && f.TargetActorURI == target.ActorURI).ExecuteFirstAsync(token);
if (byId != default || follow is not JsonObject)
return byId;
var follower = await localActors.FindByUri(Id(follow["actor"]), token);
return follower == default
? default
: await dbEntities.Followings.Match(f => f.AvatarId == follower.Id && f.TargetActorURI == target.ActorURI).ExecuteFirstAsync(token);
}
}
public class RejectHandler : AcceptHandler
{
public RejectHandler(DbEntities dbEntities, ILocalActorService localActors, IQuoteService quotes) : base(dbEntities, localActors, quotes)
{
}
public override string Type => "Reject";
protected override Task Apply(Following following, CancellationToken token) => DB.Default.DeleteAsync<Following>(following.ID);
}
}