[backend/federation] Enforce matching activity actor & auth fetch signature user
This commit is contained in:
parent
0d5f987a8d
commit
69610a61d1
3 changed files with 19 additions and 3 deletions
|
@ -65,7 +65,11 @@ public class ActivityPubController : Controller {
|
||||||
using var reader = new StreamReader(Request.Body, Encoding.UTF8, true, 1024, true);
|
using var reader = new StreamReader(Request.Body, Encoding.UTF8, true, 1024, true);
|
||||||
var body = await reader.ReadToEndAsync();
|
var body = await reader.ReadToEndAsync();
|
||||||
Request.Body.Position = 0;
|
Request.Body.Position = 0;
|
||||||
await queues.InboxQueue.EnqueueAsync(new InboxJob { Body = body, InboxUserId = id });
|
await queues.InboxQueue.EnqueueAsync(new InboxJob {
|
||||||
|
Body = body,
|
||||||
|
InboxUserId = id,
|
||||||
|
AuthFetchUserId = HttpContext.GetActor()?.Id
|
||||||
|
});
|
||||||
return Accepted();
|
return Accepted();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,17 +18,19 @@ namespace Iceshrimp.Backend.Core.Federation.ActivityPub;
|
||||||
public class ActivityHandlerService(
|
public class ActivityHandlerService(
|
||||||
ILogger<ActivityHandlerService> logger,
|
ILogger<ActivityHandlerService> logger,
|
||||||
NoteService noteSvc,
|
NoteService noteSvc,
|
||||||
|
UserService userSvc,
|
||||||
UserResolver userResolver,
|
UserResolver userResolver,
|
||||||
DatabaseContext db,
|
DatabaseContext db,
|
||||||
QueueService queueService,
|
QueueService queueService,
|
||||||
ActivityRenderer activityRenderer,
|
ActivityRenderer activityRenderer,
|
||||||
IOptions<Config.InstanceSection> config,
|
IOptions<Config.InstanceSection> config,
|
||||||
|
IOptions<Config.SecuritySection> security,
|
||||||
FederationControlService federationCtrl,
|
FederationControlService federationCtrl,
|
||||||
ObjectResolver resolver,
|
ObjectResolver resolver,
|
||||||
NotificationService notificationSvc,
|
NotificationService notificationSvc,
|
||||||
ActivityDeliverService deliverSvc
|
ActivityDeliverService deliverSvc
|
||||||
) {
|
) {
|
||||||
public async Task PerformActivityAsync(ASActivity activity, string? inboxUserId) {
|
public async Task PerformActivityAsync(ASActivity activity, string? inboxUserId, string? authFetchUserId) {
|
||||||
logger.LogDebug("Processing activity: {activity}", activity.Id);
|
logger.LogDebug("Processing activity: {activity}", activity.Id);
|
||||||
if (activity.Actor == null)
|
if (activity.Actor == null)
|
||||||
throw GracefulException.UnprocessableEntity("Cannot perform activity as actor 'null'");
|
throw GracefulException.UnprocessableEntity("Cannot perform activity as actor 'null'");
|
||||||
|
@ -37,6 +39,15 @@ public class ActivityHandlerService(
|
||||||
if (activity.Object == null)
|
if (activity.Object == null)
|
||||||
throw GracefulException.UnprocessableEntity("Activity object is null");
|
throw GracefulException.UnprocessableEntity("Activity object is null");
|
||||||
|
|
||||||
|
var resolvedActor = await userResolver.ResolveAsync(activity.Actor.Id);
|
||||||
|
|
||||||
|
if (security.Value.AuthorizedFetch && authFetchUserId == null)
|
||||||
|
throw GracefulException
|
||||||
|
.UnprocessableEntity("Refusing to process activity without authFetchUserId in authorized fetch mode");
|
||||||
|
if (resolvedActor.Id != authFetchUserId && authFetchUserId != null)
|
||||||
|
throw GracefulException
|
||||||
|
.UnprocessableEntity($"Authorized fetch user id {authFetchUserId} doesn't match resolved actor id {resolvedActor.Id}");
|
||||||
|
|
||||||
// Resolve object & children
|
// Resolve object & children
|
||||||
activity.Object = await resolver.ResolveObject(activity.Object) ??
|
activity.Object = await resolver.ResolveObject(activity.Object) ??
|
||||||
throw GracefulException.UnprocessableEntity("Failed to resolve activity object");
|
throw GracefulException.UnprocessableEntity("Failed to resolve activity object");
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class InboxQueue {
|
||||||
var logger = scope.GetRequiredService<ILogger<InboxQueue>>();
|
var logger = scope.GetRequiredService<ILogger<InboxQueue>>();
|
||||||
|
|
||||||
logger.LogTrace("Preparation took {ms} ms", job.Duration);
|
logger.LogTrace("Preparation took {ms} ms", job.Duration);
|
||||||
await apHandler.PerformActivityAsync(activity, job.InboxUserId);
|
await apHandler.PerformActivityAsync(activity, job.InboxUserId, job.AuthFetchUserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,4 +38,5 @@ public class InboxQueue {
|
||||||
public class InboxJob : Job {
|
public class InboxJob : Job {
|
||||||
[ProtoMember(1)] public required string Body;
|
[ProtoMember(1)] public required string Body;
|
||||||
[ProtoMember(2)] public required string? InboxUserId;
|
[ProtoMember(2)] public required string? InboxUserId;
|
||||||
|
[ProtoMember(3)] public required string? AuthFetchUserId;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue