Files
SocialPub/PrivaPub/Federation/Inbox/Arrival.cs
T

78 lines
2.5 KiB
C#
Raw Normal View History

2026-10-03 11:04:42 +02:00
using PrivaPub.Federation.Actors;
using PrivaPub.Infrastructure.Statistics;
using PrivaPub.Models.Federation;
using PrivaPub.Models.Post;
namespace PrivaPub.Federation.Inbox
{
public sealed record Arrival(string ActivityId, string ActivityType, string ActorURI, string Inbox, string KeyId, string Algorithm,
IReadOnlyList<string> SignedHeaders, DateTime ReceivedAt, string Context = default)
{
static readonly AsyncLocal<Arrival> current = new();
public static Arrival Current
{
get => current.Value;
set => current.Value = value;
}
2026-10-03 11:04:42 +02:00
public ArrivalVerdict Verdict { get; } = new();
public static void Drop(string reason) => Current?.Verdict.Drop(reason);
public static void Reject(string reason) => Current?.Verdict.Reject(reason);
public static void Accept(string reason) => Current?.Verdict.Accept(reason);
public static void About(string objectType = default, PostVisibility? visibility = default, DateTime? created = default, LocalActor local = default) =>
Current?.Verdict.About(objectType, visibility, created, local);
}
public sealed class ArrivalVerdict
{
public string Outcome { get; private set; }
public string Reason { get; private set; }
public string ObjectType { get; private set; }
public string Audience { get; private set; }
public string LocalKind { get; private set; }
public long? AgeSeconds { get; private set; }
public void Drop(string reason) => Decide(Interactions.Dropped, reason);
public void Reject(string reason) => Decide(Interactions.Rejected, reason);
public void Accept(string reason) => Decide(Interactions.Accepted, reason);
void Decide(string outcome, string reason)
{
if (Outcome != default)
return;
Outcome = outcome;
Reason = reason;
}
public void About(string objectType, PostVisibility? visibility, DateTime? created, LocalActor local)
{
ObjectType = objectType ?? ObjectType;
if (visibility is { } known)
Audience = AudienceOf(known);
if (created is { } at)
AgeSeconds = Math.Max(0, (long)(DateTime.UtcNow - at).TotalSeconds);
if (local != default)
LocalKind = local.Kind switch
{
LocalActorKind.Person => "person",
LocalActorKind.Group when !local.IsCircle => "group",
LocalActorKind.Application => "application",
_ => default
};
}
public static string AudienceOf(PostVisibility visibility) => visibility switch
{
PostVisibility.Public => Interactions.Public,
PostVisibility.Unlisted => Interactions.Unlisted,
_ => Interactions.Private
};
}
}