using System.Net.Mime; using Iceshrimp.Backend.Controllers.Renderers; using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; using Iceshrimp.Backend.Core.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; using Microsoft.EntityFrameworkCore; namespace Iceshrimp.Backend.Controllers; [ApiController] [EnableRateLimiting("sliding")] [Route("/api/iceshrimp/v1/note")] [Produces(MediaTypeNames.Application.Json)] public class NoteController(DatabaseContext db, NoteService noteSvc) : ControllerBase { [HttpGet("{id}")] [Authenticate] [Produces(MediaTypeNames.Application.Json)] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(NoteResponse))] [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))] public async Task GetNote(string id) { var user = HttpContext.GetUser(); var note = await db.Notes.Where(p => p.Id == id) .IncludeCommonProperties() .EnsureVisibleFor(user) .PrecomputeVisibilities(user) .FirstOrDefaultAsync() ?? throw GracefulException.NotFound("User not found"); return Ok(NoteRenderer.RenderOne(note.EnforceRenoteReplyVisibility())); } [HttpPost] [Authenticate] [Authorize] [Consumes(MediaTypeNames.Application.Json)] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(NoteResponse))] [ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(ErrorResponse))] [ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(ErrorResponse))] public async Task CreateNote(NoteCreateRequest request) { var user = HttpContext.GetUserOrFail(); var reply = request.ReplyId != null ? await db.Notes.Where(p => p.Id == request.ReplyId) .IncludeCommonProperties() .EnsureVisibleFor(user) .FirstOrDefaultAsync() ?? throw GracefulException.BadRequest("Reply target is nonexistent or inaccessible") : null; var note = await noteSvc.CreateNoteAsync(user, Note.NoteVisibility.Public, request.Text, request.Cw, reply); return Ok(NoteRenderer.RenderOne(note)); } }