From 3abe4ebfbd737abad8c2395de03a9245e48b763d Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 24 Jul 2026 16:01:34 +0400 Subject: [PATCH] perf(oauth): avoid duplicate user preload --- changelog.d/oauth-user-preload.change | 1 + .../mastodon_api/controllers/status_controller.ex | 5 ++++- lib/pleroma/web/plugs/o_auth_plug.ex | 2 +- test/pleroma/web/plugs/o_auth_plug_test.exs | 12 ++++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 changelog.d/oauth-user-preload.change diff --git a/changelog.d/oauth-user-preload.change b/changelog.d/oauth-user-preload.change new file mode 100644 index 000000000..43f5ea06b --- /dev/null +++ b/changelog.d/oauth-user-preload.change @@ -0,0 +1 @@ +Avoid a duplicate user query during OAuth authentication. diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 26e38aac8..6cd7469f9 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -716,7 +716,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do end end - defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do + defp put_application( + params, + %{assigns: %{token: %Token{} = token, user: %User{} = user}} = _conn + ) do if user.disclose_client do %{client_name: client_name, website: website} = Repo.preload(token, :app).app Map.put(params, :generator, %{type: "Application", name: client_name, url: website}) diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex index 488968691..b59ac9d3e 100644 --- a/lib/pleroma/web/plugs/o_auth_plug.ex +++ b/lib/pleroma/web/plugs/o_auth_plug.ex @@ -52,7 +52,7 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do where: t.token == ^token ) - with %Token{user_id: user_id} = token_record <- Repo.one(token_query) |> Repo.preload(:user), + with %Token{user_id: user_id} = token_record <- Repo.one(token_query), false <- is_nil(user_id), %User{} = user <- User.get_cached_by_id(user_id) do {:ok, user, token_record} diff --git a/test/pleroma/web/plugs/o_auth_plug_test.exs b/test/pleroma/web/plugs/o_auth_plug_test.exs index 8917eadd1..2509e4203 100644 --- a/test/pleroma/web/plugs/o_auth_plug_test.exs +++ b/test/pleroma/web/plugs/o_auth_plug_test.exs @@ -44,6 +44,18 @@ defmodule Pleroma.Web.Plugs.OAuthPlugTest do assert conn.assigns[:user] == opts[:user] end + test "with a valid token, it does not preload the duplicate user association", %{ + conn: conn, + token: token + } do + conn = + conn + |> put_req_header("authorization", "bearer #{token.token}") + |> OAuthPlug.call(%{}) + + assert %Ecto.Association.NotLoaded{} = conn.assigns.token.user + end + test "with valid token (downcase) in url parameters, it assigns the user", opts do conn = :get