From 1ef5be89173ac728cc6f9dd4f8f6d041fc068a31 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Tue, 4 Jun 2024 19:31:46 +0200 Subject: [PATCH] [backend/core] Correctly handle remote AP redirects to local notes --- .../ActivityPub/ActivityFetcherService.cs | 2 +- .../Core/Middleware/ErrorHandlerMiddleware.cs | 6 +++++ .../Core/Services/NoteService.cs | 24 +++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs index 9f98eae2..13724278 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs @@ -87,7 +87,7 @@ public class ActivityFetcherService( { var requestHost = new Uri(url).Host; if (requestHost == config.Value.WebDomain || requestHost == config.Value.AccountDomain) - throw GracefulException.UnprocessableEntity("Refusing to fetch activity from local domain"); + throw new LocalFetchException(url); if (await fedCtrlSvc.ShouldBlockAsync(requestHost)) { diff --git a/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs b/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs index 5d193337..a42a3e1e 100644 --- a/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs +++ b/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs @@ -201,6 +201,12 @@ public class AuthFetchException(HttpStatusCode statusCode, string message, strin new(HttpStatusCode.NotFound, HttpStatusCode.NotFound.ToString(), message); } +public class LocalFetchException(string uri) + : GracefulException(HttpStatusCode.UnprocessableEntity, "Refusing to fetch activity from local domain") +{ + public string Uri => uri; +} + public enum ExceptionVerbosity { [SuppressMessage("ReSharper", "UnusedMember.Global")] diff --git a/Iceshrimp.Backend/Core/Services/NoteService.cs b/Iceshrimp.Backend/Core/Services/NoteService.cs index b183fcfd..2197f982 100644 --- a/Iceshrimp.Backend/Core/Services/NoteService.cs +++ b/Iceshrimp.Backend/Core/Services/NoteService.cs @@ -1029,19 +1029,29 @@ public class NoteService( throw GracefulException.UnprocessableEntity("Refusing to resolve circular threads"); _resolverHistory.Add(uri); - var note = uri.StartsWith($"https://{config.Value.WebDomain}/notes/") - ? await db.Notes.IncludeCommonProperties() - .FirstOrDefaultAsync(p => p.Id == - uri.Substring($"https://{config.Value.WebDomain}/notes/".Length)) - : await db.Notes.IncludeCommonProperties() - .FirstOrDefaultAsync(p => p.Uri == uri); + if (uri.StartsWith($"https://{config.Value.WebDomain}/notes/")) + { + var id = uri[$"https://{config.Value.WebDomain}/notes/".Length..]; + return await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Id == id); + } + + var note = await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Uri == uri); if (note != null) return note; if (!fetchedNote?.VerifiedFetch ?? false) fetchedNote = null; - fetchedNote ??= user != null ? await fetchSvc.FetchNoteAsync(uri, user) : await fetchSvc.FetchNoteAsync(uri); + try + { + fetchedNote ??= + user != null ? await fetchSvc.FetchNoteAsync(uri, user) : await fetchSvc.FetchNoteAsync(uri); + } + catch (LocalFetchException e) when (e.Uri.StartsWith($"https://{config.Value.WebDomain}/notes/")) + { + var id = e.Uri[$"https://{config.Value.WebDomain}/notes/".Length..]; + return await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Id == id); + } if (fetchedNote == null) {