perf(oauth): avoid duplicate user preload

This commit is contained in:
Lain Soykaf 2026-07-24 16:01:34 +04:00
commit 3abe4ebfbd
No known key found for this signature in database
4 changed files with 18 additions and 2 deletions

View file

@ -0,0 +1 @@
Avoid a duplicate user query during OAuth authentication.

View file

@ -716,7 +716,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
end end
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 if user.disclose_client do
%{client_name: client_name, website: website} = Repo.preload(token, :app).app %{client_name: client_name, website: website} = Repo.preload(token, :app).app
Map.put(params, :generator, %{type: "Application", name: client_name, url: website}) Map.put(params, :generator, %{type: "Application", name: client_name, url: website})

View file

@ -52,7 +52,7 @@ defmodule Pleroma.Web.Plugs.OAuthPlug do
where: t.token == ^token 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), false <- is_nil(user_id),
%User{} = user <- User.get_cached_by_id(user_id) do %User{} = user <- User.get_cached_by_id(user_id) do
{:ok, user, token_record} {:ok, user, token_record}

View file

@ -44,6 +44,18 @@ defmodule Pleroma.Web.Plugs.OAuthPlugTest do
assert conn.assigns[:user] == opts[:user] assert conn.assigns[:user] == opts[:user]
end 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 test "with valid token (downcase) in url parameters, it assigns the user", opts do
conn = conn =
:get :get