[backend/federation] Enforce note visibility checks in AP controller
This commit is contained in:
parent
c5d773e46a
commit
a1fbe6f9b5
4 changed files with 24 additions and 4 deletions
|
@ -28,7 +28,11 @@ public class ActivityPubController : Controller {
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
|
[ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))]
|
||||||
public async Task<IActionResult> GetNote(string id, [FromServices] DatabaseContext db,
|
public async Task<IActionResult> GetNote(string id, [FromServices] DatabaseContext db,
|
||||||
[FromServices] NoteRenderer noteRenderer) {
|
[FromServices] NoteRenderer noteRenderer) {
|
||||||
var note = await db.Notes.IncludeCommonProperties().FirstOrDefaultAsync(p => p.Id == id);
|
var actor = HttpContext.GetActor();
|
||||||
|
var note = await db.Notes
|
||||||
|
.IncludeCommonProperties()
|
||||||
|
.EnsureVisibleFor(actor)
|
||||||
|
.FirstOrDefaultAsync(p => p.Id == id);
|
||||||
if (note == null) return NotFound();
|
if (note == null) return NotFound();
|
||||||
var rendered = await noteRenderer.RenderAsync(note);
|
var rendered = await noteRenderer.RenderAsync(note);
|
||||||
var compacted = LdHelpers.Compact(rendered);
|
var compacted = LdHelpers.Compact(rendered);
|
||||||
|
|
|
@ -13,8 +13,8 @@ public class NoteRenderer(IOptions<Config.InstanceSection> config, MfmConverter
|
||||||
public async Task<ASNote> RenderAsync(Note note, List<Note.MentionedUser>? mentions = null) {
|
public async Task<ASNote> RenderAsync(Note note, List<Note.MentionedUser>? mentions = null) {
|
||||||
var id = $"https://{config.Value.WebDomain}/notes/{note.Id}";
|
var id = $"https://{config.Value.WebDomain}/notes/{note.Id}";
|
||||||
var userId = $"https://{config.Value.WebDomain}/users/{note.User.Id}";
|
var userId = $"https://{config.Value.WebDomain}/users/{note.User.Id}";
|
||||||
var replyId = note.ReplyId != null
|
var replyId = note.Reply != null
|
||||||
? new ASObjectBase($"https://{config.Value.WebDomain}/notes/{note.ReplyId}")
|
? new ASObjectBase(note.Reply.Uri ?? $"https://{config.Value.WebDomain}/notes/{note.ReplyId}")
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
mentions ??= await db.Users
|
mentions ??= await db.Users
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class AuthenticateAttribute(params string[] scopes) : Attribute {
|
||||||
public readonly string[] Scopes = scopes;
|
public readonly string[] Scopes = scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HttpContextExtensions {
|
public static partial class HttpContextExtensions {
|
||||||
private const string Key = "session";
|
private const string Key = "session";
|
||||||
private const string MastodonKey = "masto-session";
|
private const string MastodonKey = "masto-session";
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Iceshrimp.Backend.Core.Configuration;
|
using Iceshrimp.Backend.Core.Configuration;
|
||||||
using Iceshrimp.Backend.Core.Database;
|
using Iceshrimp.Backend.Core.Database;
|
||||||
|
using Iceshrimp.Backend.Core.Database.Tables;
|
||||||
using Iceshrimp.Backend.Core.Federation.Cryptography;
|
using Iceshrimp.Backend.Core.Federation.Cryptography;
|
||||||
using Iceshrimp.Backend.Core.Services;
|
using Iceshrimp.Backend.Core.Services;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
@ -65,6 +66,8 @@ public class AuthorizedFetchMiddleware(
|
||||||
|
|
||||||
//TODO: re-fetch key once if signature validation fails, to properly support key rotation
|
//TODO: re-fetch key once if signature validation fails, to properly support key rotation
|
||||||
//TODO: Check for LD signature as well
|
//TODO: Check for LD signature as well
|
||||||
|
|
||||||
|
ctx.SetActor(key.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
await next(ctx);
|
await next(ctx);
|
||||||
|
@ -74,3 +77,16 @@ public class AuthorizedFetchMiddleware(
|
||||||
public class AuthorizedFetchAttribute(bool forceBody = false) : Attribute {
|
public class AuthorizedFetchAttribute(bool forceBody = false) : Attribute {
|
||||||
public bool ForceBody { get; } = forceBody;
|
public bool ForceBody { get; } = forceBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static partial class HttpContextExtensions {
|
||||||
|
private const string ActorKey = "auth-fetch-user";
|
||||||
|
|
||||||
|
internal static void SetActor(this HttpContext ctx, User actor) {
|
||||||
|
ctx.Items.Add(ActorKey, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static User? GetActor(this HttpContext ctx) {
|
||||||
|
ctx.Items.TryGetValue(ActorKey, out var actor);
|
||||||
|
return actor as User;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue