[backend/core] Correctly handle remote AP redirects to local notes

This commit is contained in:
Laura Hausmann 2024-06-04 19:31:46 +02:00
parent bcdcce80c9
commit 1ef5be8917
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 24 additions and 8 deletions

View file

@ -87,7 +87,7 @@ public class ActivityFetcherService(
{ {
var requestHost = new Uri(url).Host; var requestHost = new Uri(url).Host;
if (requestHost == config.Value.WebDomain || requestHost == config.Value.AccountDomain) 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)) if (await fedCtrlSvc.ShouldBlockAsync(requestHost))
{ {

View file

@ -201,6 +201,12 @@ public class AuthFetchException(HttpStatusCode statusCode, string message, strin
new(HttpStatusCode.NotFound, HttpStatusCode.NotFound.ToString(), message); 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 public enum ExceptionVerbosity
{ {
[SuppressMessage("ReSharper", "UnusedMember.Global")] [SuppressMessage("ReSharper", "UnusedMember.Global")]

View file

@ -1029,19 +1029,29 @@ public class NoteService(
throw GracefulException.UnprocessableEntity("Refusing to resolve circular threads"); throw GracefulException.UnprocessableEntity("Refusing to resolve circular threads");
_resolverHistory.Add(uri); _resolverHistory.Add(uri);
var note = uri.StartsWith($"https://{config.Value.WebDomain}/notes/") if (uri.StartsWith($"https://{config.Value.WebDomain}/notes/"))
? await db.Notes.IncludeCommonProperties() {
.FirstOrDefaultAsync(p => p.Id == var id = uri[$"https://{config.Value.WebDomain}/notes/".Length..];
uri.Substring($"https://{config.Value.WebDomain}/notes/".Length)) return await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Id == id);
: await db.Notes.IncludeCommonProperties() }
.FirstOrDefaultAsync(p => p.Uri == uri);
var note = await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Uri == uri);
if (note != null) return note; if (note != null) return note;
if (!fetchedNote?.VerifiedFetch ?? false) if (!fetchedNote?.VerifiedFetch ?? false)
fetchedNote = null; 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) if (fetchedNote == null)
{ {