[backend/masto-client] Resolve notes with user keypair

This commit is contained in:
Laura Hausmann 2024-02-23 03:34:56 +01:00
parent 8f03cb0768
commit 78705b8a5d
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 16 additions and 4 deletions

View file

@ -157,7 +157,7 @@ public class SearchController(
//TODO: figure out whether there is a more efficient way to get this information (in one query)
if (note == null && !await db.Notes.AnyAsync(p => p.Uri == search.Query || p.Url == search.Query))
{
var tmpNote = await noteSvc.ResolveNoteAsync(search.Query);
var tmpNote = await noteSvc.ResolveNoteAsync(search.Query, user: user);
// We need to re-fetch the note to capture the includes
if (tmpNote != null)

View file

@ -1,10 +1,12 @@
using System.Net;
using System.Net.Http.Headers;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Federation.ActivityStreams;
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
using Iceshrimp.Backend.Core.Middleware;
using Iceshrimp.Backend.Core.Services;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -14,6 +16,7 @@ public class ActivityFetcherService(
HttpClient client,
HttpRequestService httpRqSvc,
SystemUserService systemUserSvc,
DatabaseContext db,
ILogger<ActivityFetcherService> logger
)
{
@ -99,6 +102,14 @@ public class ActivityFetcherService(
return activity.OfType<ASNote>().FirstOrDefault();
}
public async Task<ASNote?> FetchNoteAsync(string uri, User actor)
{
var keypair = await db.UserKeypairs.FirstOrDefaultAsync(p => p.User == actor) ??
throw new Exception("User has no keypair");
var activity = await FetchActivityAsync(uri, actor, keypair);
return activity.OfType<ASNote>().FirstOrDefault();
}
public async Task<ASNote?> FetchNoteAsync(string uri)
{
var (actor, keypair) = await systemUserSvc.GetInstanceActorWithKeypairAsync();

View file

@ -345,7 +345,7 @@ public class NoteService(
Reply = note.InReplyTo?.Id != null ? await ResolveNoteAsync(note.InReplyTo.Id) : null,
Renote = quoteUrl != null ? await ResolveNoteAsync(quoteUrl) : null
};
if (dbNote.Renote?.IsPureRenote ?? false)
throw GracefulException.UnprocessableEntity("Cannot renote or quote a pure renote");
@ -581,7 +581,7 @@ public class NoteService(
return result.Where(p => p != null).Cast<DriveFile>().ToList();
}
public async Task<Note?> ResolveNoteAsync(string uri, ASNote? fetchedNote = null)
public async Task<Note?> ResolveNoteAsync(string uri, ASNote? fetchedNote = null, User? user = null)
{
//TODO: is this enough to prevent DoS attacks?
if (_recursionLimit-- <= 0)
@ -600,7 +600,8 @@ public class NoteService(
if (note != null) return note;
//TODO: should we fall back to a regular user's keypair if fetching with instance actor fails & a local user is following the actor?
fetchedNote ??= await fetchSvc.FetchNoteAsync(uri);
fetchedNote ??= user != null ? await fetchSvc.FetchNoteAsync(uri, user) : await fetchSvc.FetchNoteAsync(uri);
if (fetchedNote == null)
{
logger.LogDebug("Failed to fetch note, skipping");