using System.Net; using System.Net.Mime; using Iceshrimp.Backend.Controllers.Mastodon.Attributes; using Iceshrimp.Backend.Controllers.Pleroma.Schemas; using Iceshrimp.Backend.Controllers.Shared.Attributes; using Iceshrimp.Backend.Controllers.Web.Renderers; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; using Microsoft.EntityFrameworkCore; using NoteRenderer = Iceshrimp.Backend.Controllers.Mastodon.Renderers.NoteRenderer; using UserRenderer = Iceshrimp.Backend.Controllers.Mastodon.Renderers.UserRenderer; namespace Iceshrimp.Backend.Controllers.Pleroma; [MastodonApiController] [Authenticate] [EnableCors("mastodon")] [EnableRateLimiting("sliding")] [Produces(MediaTypeNames.Application.Json)] public class AdminController( DatabaseContext db, ReportRenderer reportRenderer, NoteRenderer noteRenderer, UserRenderer userRenderer ) : ControllerBase { [HttpGet("/api/v1/pleroma/admin/reports")] [Authenticate("admin:read:reports")] [ProducesResults(HttpStatusCode.OK)] public async Task GetReports(bool resolved = false) { var user = HttpContext.GetUserOrFail(); var reports = await db.Reports .IncludeCommonProperties() .Where(p => p.Resolved == resolved) .ToListAsync(); var rendered = await reportRenderer.RenderManyAsync(reports); var reportsList = new List(); foreach (var r in rendered) { var reActor = await db.Users .IncludeCommonProperties() .Where(p => p.Id == r.Reporter.Id) .RenderAllForMastodonAsync(userRenderer, user); var reTarget = await db.Users .IncludeCommonProperties() .Where(p => p.Id == r.TargetUser.Id) .RenderAllForMastodonAsync(userRenderer, user); foreach (var n in r.Notes) { var note = await db.Notes .IncludeCommonProperties() .Where(p => p.Id == n.Id) .RenderAllForMastodonAsync(noteRenderer, user); reportsList.Add(new Reports() { Account = reTarget.FirstOrDefault()!, Actor = reActor.FirstOrDefault()!, Id = r.Id, CreatedAt = r.CreatedAt, State = r.Resolved ? "resolved" : "open", Content = r.Comment, Statuses = note, Notes = [] // unsupported }); } } var resps = new ReportsQuery() { Total = reportsList.Count, Reports = reportsList }; return resps; } [HttpPatch("/api/v1/pleroma/admin/reports")] [Authenticate("admin:read:reports")] [ProducesResults(HttpStatusCode.OK)] public void SetReportState(ReportsQuery query) { var user = HttpContext.GetUserOrFail(); foreach (var list in query.Reports) { var report = db.Reports.FirstOrDefault(p => p.Id == list.Id) ?? throw GracefulException.NotFound("Report not found"); report.Resolved = list.State == "closed"; db.SaveChangesAsync(); } } }