From b9cfbe52fc94c45b73d8e6bb13432ffc4dc7e893 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Fri, 2 Feb 2024 20:05:27 +0100 Subject: [PATCH] [backend/masto-client] Add basic timeline endpoints --- .../Mastodon/MastodonTimelineController.cs | 51 +++++++++++++++++++ .../Mastodon/MastodonUserController.cs | 4 +- .../Core/Helpers/QueryHelpers.cs | 17 +++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 Iceshrimp.Backend/Controllers/Mastodon/MastodonTimelineController.cs create mode 100644 Iceshrimp.Backend/Core/Helpers/QueryHelpers.cs diff --git a/Iceshrimp.Backend/Controllers/Mastodon/MastodonTimelineController.cs b/Iceshrimp.Backend/Controllers/Mastodon/MastodonTimelineController.cs new file mode 100644 index 00000000..7bff4e2b --- /dev/null +++ b/Iceshrimp.Backend/Controllers/Mastodon/MastodonTimelineController.cs @@ -0,0 +1,51 @@ +using Iceshrimp.Backend.Controllers.Mastodon.Renderers; +using Iceshrimp.Backend.Controllers.Mastodon.Schemas; +using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities; +using Iceshrimp.Backend.Core.Database; +using Iceshrimp.Backend.Core.Database.Tables; +using Iceshrimp.Backend.Core.Helpers; +using Iceshrimp.Backend.Core.Middleware; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.RateLimiting; +using Microsoft.EntityFrameworkCore; + +namespace Iceshrimp.Backend.Controllers.Mastodon; + +[ApiController] +[Tags("Mastodon")] +[Route("/api/v1/timelines")] +[AuthenticateOauth] +[EnableRateLimiting("sliding")] +[Produces("application/json")] +[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(MastodonErrorResponse))] +[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(MastodonErrorResponse))] +public class MastodonTimelineController(DatabaseContext db, NoteRenderer noteRenderer) : Controller { + [AuthorizeOauth("read:statuses")] + [HttpGet("home")] + [Produces("application/json")] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] + public async Task GetHomeTimeline() { + var user = HttpContext.GetOauthUser() ?? throw new GracefulException("Failed to get user from HttpContext"); + var notes = await db.Notes + .IsFollowedBy(user) + .OrderByIdDesc() + .Take(40) + .ToListAsync(); + + return Ok(notes); + } + + [AuthorizeOauth("read:statuses")] + [HttpGet("public")] + [Produces("application/json")] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] + public async Task GetPublicTimeline() { + var notes = await db.Notes + .HasVisibility(Note.NoteVisibility.Public) + .OrderByIdDesc() + .Take(40) + .ToListAsync(); + + return Ok(notes); + } +} \ No newline at end of file diff --git a/Iceshrimp.Backend/Controllers/Mastodon/MastodonUserController.cs b/Iceshrimp.Backend/Controllers/Mastodon/MastodonUserController.cs index 24fe3149..c38e4736 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/MastodonUserController.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/MastodonUserController.cs @@ -13,13 +13,13 @@ namespace Iceshrimp.Backend.Controllers.Mastodon; [AuthenticateOauth] [EnableRateLimiting("sliding")] [Produces("application/json")] +[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(MastodonErrorResponse))] +[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(MastodonErrorResponse))] public class MastodonUserController(UserRenderer userRenderer) : Controller { [AuthorizeOauth("read:accounts")] [HttpGet("verify_credentials")] [Produces("application/json")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Account))] - [ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(MastodonErrorResponse))] - [ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(MastodonErrorResponse))] public async Task VerifyUserCredentials() { var user = HttpContext.GetOauthUser() ?? throw new GracefulException("Failed to get user from HttpContext"); var res = await userRenderer.RenderAsync(user); diff --git a/Iceshrimp.Backend/Core/Helpers/QueryHelpers.cs b/Iceshrimp.Backend/Core/Helpers/QueryHelpers.cs new file mode 100644 index 00000000..bf58077b --- /dev/null +++ b/Iceshrimp.Backend/Core/Helpers/QueryHelpers.cs @@ -0,0 +1,17 @@ +using Iceshrimp.Backend.Core.Database.Tables; + +namespace Iceshrimp.Backend.Core.Helpers; + +public static class QueryHelpers { + public static IQueryable HasVisibility(this IQueryable query, Note.NoteVisibility visibility) { + return query.Where(note => note.Visibility == visibility); + } + + public static IQueryable IsFollowedBy(this IQueryable query, User user) { + return query.Where(note => note.User.FollowingFollowees.Any(following => following.Follower == user)); + } + + public static IQueryable OrderByIdDesc(this IQueryable query) { + return query.OrderByDescending(note => note.Id); + } +} \ No newline at end of file