From 6519732045596b1f0b0e83c365db516afba913d9 Mon Sep 17 00:00:00 2001 From: Sean King Date: Wed, 25 Aug 2021 21:01:04 -0600 Subject: [PATCH 01/36] GET /api/v1/apps endpoint --- .../web/api_spec/operations/app_operation.ex | 39 +++++++++++++++++++ .../controllers/app_controller.ex | 10 +++++ .../web/mastodon_api/views/app_view.ex | 4 ++ lib/pleroma/web/o_auth/app.ex | 9 +++++ lib/pleroma/web/router.ex | 2 + .../20210818023112_add_user_id_to_apps.exs | 9 +++++ 6 files changed, 73 insertions(+) create mode 100644 priv/repo/migrations/20210818023112_add_user_id_to_apps.exs diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index dfb1c7170..72032a4e0 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -13,6 +13,19 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do apply(__MODULE__, operation, []) end + @spec index_operation() :: Operation.t() + def index_operation do + %Operation{ + tags: ["Applications"], + summary: "List applications", + description: "List the OAuth applications for the current user", + operationId: "AppController.index", + responses: %{ + 200 => Operation.response("App", "application/json", index_response()), + } + } + end + @spec create_operation() :: Operation.t() def create_operation do %Operation{ @@ -145,4 +158,30 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do } } end + + defp index_response do + %Schema{ + title: "AppIndexResponse", + description: "Response schema for GET /api/v1/apps", + type: :object, + properties: [%{ + id: %Schema{type: :string}, + name: %Schema{type: :string}, + client_id: %Schema{type: :string}, + client_secret: %Schema{type: :string}, + redirect_uri: %Schema{type: :string}, + vapid_key: %Schema{type: :string}, + website: %Schema{type: :string, nullable: true} + }], + example: [%{ + "id" => "123", + "name" => "My App", + "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", + "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", + "vapid_key" => + "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", + "website" => "https://myapp.com/" + }] + } + end end diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index a95cc52fd..38073c29a 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -14,17 +14,27 @@ defmodule Pleroma.Web.MastodonAPI.AppController do alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token + alias Pleroma.Web.Plugs.OAuthScopesPlug action_fallback(Pleroma.Web.MastodonAPI.FallbackController) plug(:skip_auth when action in [:create, :verify_credentials]) + plug(:skip_plug, OAuthScopesPlug when action in [:index]) + plug(Pleroma.Web.ApiSpec.CastAndValidate) @local_mastodon_name "Mastodon-Local" defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation + @doc "GET /api/v1/apps" + def index(%{assigns: %{user: user}} = conn, _params) do + with apps <- App.get_user_apps(user) do + render(conn, "index.json", %{apps: apps}) + end + end + @doc "POST /api/v1/apps" def create(%{body_params: params} = conn, _params) do scopes = Scopes.fetch_scopes(params, ["read"]) diff --git a/lib/pleroma/web/mastodon_api/views/app_view.ex b/lib/pleroma/web/mastodon_api/views/app_view.ex index c406b5a27..450943aee 100644 --- a/lib/pleroma/web/mastodon_api/views/app_view.ex +++ b/lib/pleroma/web/mastodon_api/views/app_view.ex @@ -15,6 +15,10 @@ defmodule Pleroma.Web.MastodonAPI.AppView do } end + def render("index.json", %{apps: apps}) do + render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json") + end + def render("show.json", %{admin: true, app: %App{} = app} = assigns) do "show.json" |> render(Map.delete(assigns, :admin)) diff --git a/lib/pleroma/web/o_auth/app.ex b/lib/pleroma/web/o_auth/app.ex index 382750010..94b0e41f0 100644 --- a/lib/pleroma/web/o_auth/app.ex +++ b/lib/pleroma/web/o_auth/app.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.OAuth.App do import Ecto.Changeset import Ecto.Query alias Pleroma.Repo + alias Pleroma.User @type t :: %__MODULE__{} @@ -19,6 +20,8 @@ defmodule Pleroma.Web.OAuth.App do field(:client_secret, :string) field(:trusted, :boolean, default: false) + belongs_to(:user, User, type: FlakeId.Ecto.CompatType) + has_many(:oauth_authorizations, Pleroma.Web.OAuth.Authorization, on_delete: :delete_all) has_many(:oauth_tokens, Pleroma.Web.OAuth.Token, on_delete: :delete_all) @@ -129,6 +132,12 @@ defmodule Pleroma.Web.OAuth.App do {:ok, Repo.all(query), count} end + @spec get_user_apps(User.t()) :: {:ok, [t()], non_neg_integer()} + def get_user_apps(%User{id: user_id}) do + from(a in __MODULE__, where: a.user_id == ^user_id) + |> Repo.all() + end + @spec destroy(pos_integer()) :: {:ok, t()} | {:error, Ecto.Changeset.t()} def destroy(id) do with %__MODULE__{} = app <- Repo.get(__MODULE__, id) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 74ee23c06..904439564 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -444,6 +444,8 @@ defmodule Pleroma.Web.Router do scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:authenticated_api) + get("/apps", AppController, :index) + get("/accounts/verify_credentials", AccountController, :verify_credentials) patch("/accounts/update_credentials", AccountController, :update_credentials) diff --git a/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs b/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs new file mode 100644 index 000000000..39e7fbef5 --- /dev/null +++ b/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs @@ -0,0 +1,9 @@ +defmodule Pleroma.Repo.Migrations.AddUserIdToApps do + use Ecto.Migration + + def change do + alter table(:apps) do + add(:user_id, references(:users, type: :uuid, on_delete: :delete_all)) + end + end +end From ba6914f90a3e39dd75e7775fd37cfbb6ad3d2f3b Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 26 Aug 2021 11:11:37 -0600 Subject: [PATCH 02/36] Fix formatting in app_operation.ex --- .../web/api_spec/operations/app_operation.ex | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index 72032a4e0..c2221ac98 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -21,7 +21,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do description: "List the OAuth applications for the current user", operationId: "AppController.index", responses: %{ - 200 => Operation.response("App", "application/json", index_response()), + 200 => Operation.response("App", "application/json", index_response()) } } end @@ -164,24 +164,28 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do title: "AppIndexResponse", description: "Response schema for GET /api/v1/apps", type: :object, - properties: [%{ - id: %Schema{type: :string}, - name: %Schema{type: :string}, - client_id: %Schema{type: :string}, - client_secret: %Schema{type: :string}, - redirect_uri: %Schema{type: :string}, - vapid_key: %Schema{type: :string}, - website: %Schema{type: :string, nullable: true} - }], - example: [%{ - "id" => "123", - "name" => "My App", - "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", - "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", - "vapid_key" => - "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", - "website" => "https://myapp.com/" - }] + properties: [ + %{ + id: %Schema{type: :string}, + name: %Schema{type: :string}, + client_id: %Schema{type: :string}, + client_secret: %Schema{type: :string}, + redirect_uri: %Schema{type: :string}, + vapid_key: %Schema{type: :string}, + website: %Schema{type: :string, nullable: true} + } + ], + example: [ + %{ + "id" => "123", + "name" => "My App", + "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", + "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", + "vapid_key" => + "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", + "website" => "https://myapp.com/" + } + ] } end end From baa8196fc910cfdbaefd6059bdb1a8445d83f563 Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 26 Aug 2021 11:55:43 -0600 Subject: [PATCH 03/36] Fix API spec, add app schema --- .../web/api_spec/operations/app_operation.ex | 33 +++---------------- lib/pleroma/web/api_spec/schemas/app.ex | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 lib/pleroma/web/api_spec/schemas/app.ex diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index c2221ac98..71d7b9ee8 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do alias OpenApiSpex.Operation alias OpenApiSpex.Schema alias Pleroma.Web.ApiSpec.Helpers + alias Pleroma.Web.ApiSpec.Schemas.App @spec open_api_operation(atom) :: Operation.t() def open_api_operation(action) do @@ -21,7 +22,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do description: "List the OAuth applications for the current user", operationId: "AppController.index", responses: %{ - 200 => Operation.response("App", "application/json", index_response()) + 200 => Operation.response("Array of App", "application/json", array_of_apps()) } } end @@ -159,33 +160,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do } end - defp index_response do - %Schema{ - title: "AppIndexResponse", - description: "Response schema for GET /api/v1/apps", - type: :object, - properties: [ - %{ - id: %Schema{type: :string}, - name: %Schema{type: :string}, - client_id: %Schema{type: :string}, - client_secret: %Schema{type: :string}, - redirect_uri: %Schema{type: :string}, - vapid_key: %Schema{type: :string}, - website: %Schema{type: :string, nullable: true} - } - ], - example: [ - %{ - "id" => "123", - "name" => "My App", - "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", - "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", - "vapid_key" => - "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", - "website" => "https://myapp.com/" - } - ] - } + defp array_of_apps do + %Schema{type: :array, items: App, example: [App.schema().example]} end end diff --git a/lib/pleroma/web/api_spec/schemas/app.ex b/lib/pleroma/web/api_spec/schemas/app.ex new file mode 100644 index 000000000..c3d1af3be --- /dev/null +++ b/lib/pleroma/web/api_spec/schemas/app.ex @@ -0,0 +1,33 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.Schemas.App do + alias OpenApiSpex.Schema + + require OpenApiSpex + + OpenApiSpex.schema(%{ + title: "App", + description: "Response schema for an app", + type: :object, + properties: %{ + id: %Schema{type: :string}, + name: %Schema{type: :string}, + client_id: %Schema{type: :string}, + client_secret: %Schema{type: :string}, + redirect_uri: %Schema{type: :string}, + vapid_key: %Schema{type: :string}, + website: %Schema{type: :string, nullable: true} + }, + example: %{ + "id" => "123", + "name" => "My App", + "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", + "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", + "vapid_key" => + "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", + "website" => "https://myapp.com/" + } + }) +end From eab6291094314846425339ec51fffbc94cab5501 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 28 Aug 2021 11:13:25 -0600 Subject: [PATCH 04/36] Require follow and read OAuth scopes for GET /api/v1/apps --- .../web/api_spec/operations/app_operation.ex | 26 ++----------------- .../controllers/app_controller.ex | 2 +- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index 71d7b9ee8..217609b01 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -36,7 +36,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do operationId: "AppController.create", requestBody: Helpers.request_body("Parameters", create_request(), required: true), responses: %{ - 200 => Operation.response("App", "application/json", create_response()), + 200 => create_response(), 422 => Operation.response( "Unprocessable Entity", @@ -135,29 +135,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do end defp create_response do - %Schema{ - title: "AppCreateResponse", - description: "Response schema for an app", - type: :object, - properties: %{ - id: %Schema{type: :string}, - name: %Schema{type: :string}, - client_id: %Schema{type: :string}, - client_secret: %Schema{type: :string}, - redirect_uri: %Schema{type: :string}, - vapid_key: %Schema{type: :string}, - website: %Schema{type: :string, nullable: true} - }, - example: %{ - "id" => "123", - "name" => "My App", - "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", - "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", - "vapid_key" => - "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=", - "website" => "https://myapp.com/" - } - } + Operation.response("App", "application/json", App) end defp array_of_apps do diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index 38073c29a..e44c4340e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.AppController do plug(:skip_auth when action in [:create, :verify_credentials]) - plug(:skip_plug, OAuthScopesPlug when action in [:index]) + plug(OAuthScopesPlug, %{scopes: ["follow", "read"]} when action in [:index]) plug(Pleroma.Web.ApiSpec.CastAndValidate) From a14e1c0003285adce3c995f1b19a02179a556fd0 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 28 Aug 2021 18:02:36 -0600 Subject: [PATCH 05/36] Move GET /api/v1/apps to GET /api/v1/pleroma/apps --- .../web/api_spec/operations/app_operation.ex | 17 ---------- .../operations/pleroma_app_operation.ex | 31 +++++++++++++++++++ .../controllers/app_controller.ex | 10 ------ .../web/mastodon_api/views/app_view.ex | 4 --- .../pleroma_api/controllers/app_controller.ex | 23 ++++++++++++++ lib/pleroma/web/pleroma_api/views/app_view.ex | 11 +++++++ lib/pleroma/web/router.ex | 3 +- 7 files changed, 66 insertions(+), 33 deletions(-) create mode 100644 lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex create mode 100644 lib/pleroma/web/pleroma_api/controllers/app_controller.ex create mode 100644 lib/pleroma/web/pleroma_api/views/app_view.ex diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index 217609b01..5e72c4824 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -14,19 +14,6 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do apply(__MODULE__, operation, []) end - @spec index_operation() :: Operation.t() - def index_operation do - %Operation{ - tags: ["Applications"], - summary: "List applications", - description: "List the OAuth applications for the current user", - operationId: "AppController.index", - responses: %{ - 200 => Operation.response("Array of App", "application/json", array_of_apps()) - } - } - end - @spec create_operation() :: Operation.t() def create_operation do %Operation{ @@ -137,8 +124,4 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do defp create_response do Operation.response("App", "application/json", App) end - - defp array_of_apps do - %Schema{type: :array, items: App, example: [App.schema().example]} - end end diff --git a/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex new file mode 100644 index 000000000..efaf81af0 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex @@ -0,0 +1,31 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.PleromaAppOperation do + alias OpenApiSpex.Operation + alias OpenApiSpex.Schema + alias Pleroma.Web.ApiSpec.Schemas.App + + def open_api_operation(action) do + operation = String.to_existing_atom("#{action}_operation") + apply(__MODULE__, operation, []) + end + + @spec index_operation() :: Operation.t() + def index_operation do + %Operation{ + tags: ["Applications"], + summary: "List applications", + description: "List the OAuth applications for the current user", + operationId: "AppController.index", + responses: %{ + 200 => Operation.response("Array of App", "application/json", array_of_apps()) + } + } + end + + defp array_of_apps do + %Schema{type: :array, items: App, example: [App.schema().example]} + end +end \ No newline at end of file diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index e44c4340e..a95cc52fd 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -14,27 +14,17 @@ defmodule Pleroma.Web.MastodonAPI.AppController do alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token - alias Pleroma.Web.Plugs.OAuthScopesPlug action_fallback(Pleroma.Web.MastodonAPI.FallbackController) plug(:skip_auth when action in [:create, :verify_credentials]) - plug(OAuthScopesPlug, %{scopes: ["follow", "read"]} when action in [:index]) - plug(Pleroma.Web.ApiSpec.CastAndValidate) @local_mastodon_name "Mastodon-Local" defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation - @doc "GET /api/v1/apps" - def index(%{assigns: %{user: user}} = conn, _params) do - with apps <- App.get_user_apps(user) do - render(conn, "index.json", %{apps: apps}) - end - end - @doc "POST /api/v1/apps" def create(%{body_params: params} = conn, _params) do scopes = Scopes.fetch_scopes(params, ["read"]) diff --git a/lib/pleroma/web/mastodon_api/views/app_view.ex b/lib/pleroma/web/mastodon_api/views/app_view.ex index 450943aee..c406b5a27 100644 --- a/lib/pleroma/web/mastodon_api/views/app_view.ex +++ b/lib/pleroma/web/mastodon_api/views/app_view.ex @@ -15,10 +15,6 @@ defmodule Pleroma.Web.MastodonAPI.AppView do } end - def render("index.json", %{apps: apps}) do - render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json") - end - def render("show.json", %{admin: true, app: %App{} = app} = assigns) do "show.json" |> render(Map.delete(assigns, :admin)) diff --git a/lib/pleroma/web/pleroma_api/controllers/app_controller.ex b/lib/pleroma/web/pleroma_api/controllers/app_controller.ex new file mode 100644 index 000000000..6d46d917c --- /dev/null +++ b/lib/pleroma/web/pleroma_api/controllers/app_controller.ex @@ -0,0 +1,23 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.AppController do + use Pleroma.Web, :controller + + alias Pleroma.Web.OAuth.App + alias Pleroma.Web.Plugs.OAuthScopesPlug + + plug(OAuthScopesPlug, %{scopes: ["follow", "read"]} when action in [:index]) + + plug(Pleroma.Web.ApiSpec.CastAndValidate) + + defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAppOperation + + @doc "GET /api/v1/pleroma/apps" + def index(%{assigns: %{user: user}} = conn, _params) do + with apps <- App.get_user_apps(user) do + render(conn, "index.json", %{apps: apps}) + end + end +end \ No newline at end of file diff --git a/lib/pleroma/web/pleroma_api/views/app_view.ex b/lib/pleroma/web/pleroma_api/views/app_view.ex new file mode 100644 index 000000000..7dd560f8f --- /dev/null +++ b/lib/pleroma/web/pleroma_api/views/app_view.ex @@ -0,0 +1,11 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.AppView do + use Pleroma.Web, :view + + def render("index.json", %{apps: apps}) do + render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json") + end +end \ No newline at end of file diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 904439564..2dba21978 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -372,6 +372,7 @@ defmodule Pleroma.Web.Router do scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do pipe_through(:api) + get("/apps", AppController, :index) get("/statuses/:id/reactions/:emoji", EmojiReactionController, :index) get("/statuses/:id/reactions", EmojiReactionController, :index) end @@ -444,8 +445,6 @@ defmodule Pleroma.Web.Router do scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:authenticated_api) - get("/apps", AppController, :index) - get("/accounts/verify_credentials", AccountController, :verify_credentials) patch("/accounts/update_credentials", AccountController, :update_credentials) From d02cf7b0cd550bc182e7307b90f077e159b5637f Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 28 Aug 2021 18:17:09 -0600 Subject: [PATCH 06/36] Fix lint --- lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex | 2 +- lib/pleroma/web/pleroma_api/controllers/app_controller.ex | 2 +- lib/pleroma/web/pleroma_api/views/app_view.ex | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex index efaf81af0..582a169ee 100644 --- a/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/pleroma_app_operation.ex @@ -28,4 +28,4 @@ defmodule Pleroma.Web.ApiSpec.PleromaAppOperation do defp array_of_apps do %Schema{type: :array, items: App, example: [App.schema().example]} end -end \ No newline at end of file +end diff --git a/lib/pleroma/web/pleroma_api/controllers/app_controller.ex b/lib/pleroma/web/pleroma_api/controllers/app_controller.ex index 6d46d917c..d857f424f 100644 --- a/lib/pleroma/web/pleroma_api/controllers/app_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/app_controller.ex @@ -20,4 +20,4 @@ defmodule Pleroma.Web.PleromaAPI.AppController do render(conn, "index.json", %{apps: apps}) end end -end \ No newline at end of file +end diff --git a/lib/pleroma/web/pleroma_api/views/app_view.ex b/lib/pleroma/web/pleroma_api/views/app_view.ex index 7dd560f8f..6b5d838f5 100644 --- a/lib/pleroma/web/pleroma_api/views/app_view.ex +++ b/lib/pleroma/web/pleroma_api/views/app_view.ex @@ -8,4 +8,4 @@ defmodule Pleroma.Web.PleromaAPI.AppView do def render("index.json", %{apps: apps}) do render_many(apps, Pleroma.Web.MastodonAPI.AppView, "show.json") end -end \ No newline at end of file +end From 33f063204edb63344628bdfa72ff11f81ded62a9 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 28 Aug 2021 23:18:12 -0600 Subject: [PATCH 07/36] Add unit test for Pleroma API app controller --- .../controllers/app_controller.ex | 14 ++++- lib/pleroma/web/o_auth/app.ex | 2 +- .../controllers/app_controller_test.exs | 53 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 test/pleroma/web/pleroma_api/controllers/app_controller_test.exs diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index a95cc52fd..466508137 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -10,11 +10,15 @@ defmodule Pleroma.Web.MastodonAPI.AppController do use Pleroma.Web, :controller + alias Pleroma.Maps + alias Pleroma.User alias Pleroma.Repo alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token + require Logger + action_fallback(Pleroma.Web.MastodonAPI.FallbackController) plug(:skip_auth when action in [:create, :verify_credentials]) @@ -26,13 +30,21 @@ defmodule Pleroma.Web.MastodonAPI.AppController do defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation @doc "POST /api/v1/apps" - def create(%{body_params: params} = conn, _params) do + def create(%{assigns: %{user: user}, body_params: params} = conn, _params) do scopes = Scopes.fetch_scopes(params, ["read"]) + user_id = + with %User{id: id} <- user do + id + else + _ -> nil + end + app_attrs = params |> Map.take([:client_name, :redirect_uris, :website]) |> Map.put(:scopes, scopes) + |> Maps.put_if_present(:user_id, user_id) with cs <- App.register_changeset(%App{}, app_attrs), false <- cs.changes[:client_name] == @local_mastodon_name, diff --git a/lib/pleroma/web/o_auth/app.ex b/lib/pleroma/web/o_auth/app.ex index 94b0e41f0..dacfbadc8 100644 --- a/lib/pleroma/web/o_auth/app.ex +++ b/lib/pleroma/web/o_auth/app.ex @@ -30,7 +30,7 @@ defmodule Pleroma.Web.OAuth.App do @spec changeset(t(), map()) :: Ecto.Changeset.t() def changeset(struct, params) do - cast(struct, params, [:client_name, :redirect_uris, :scopes, :website, :trusted]) + cast(struct, params, [:client_name, :redirect_uris, :scopes, :website, :trusted, :user_id]) end @spec register_changeset(t(), map()) :: Ecto.Changeset.t() diff --git a/test/pleroma/web/pleroma_api/controllers/app_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/app_controller_test.exs new file mode 100644 index 000000000..5e24e18a8 --- /dev/null +++ b/test/pleroma/web/pleroma_api/controllers/app_controller_test.exs @@ -0,0 +1,53 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.AppControllerTest do + use Pleroma.Web.ConnCase, async: true + + alias Pleroma.Web.OAuth.App + alias Pleroma.Web.Push + + import Pleroma.Factory + + test "apps", %{conn: conn} do + user = insert(:user) + app_attrs = build(:oauth_app) + + creation = + conn + |> put_req_header("content-type", "application/json") + |> assign(:user, user) + |> post("/api/v1/apps", %{ + client_name: app_attrs.client_name, + redirect_uris: app_attrs.redirect_uris + }) + + [app] = App.get_user_apps(user) + + expected = %{ + "name" => app.client_name, + "website" => app.website, + "client_id" => app.client_id, + "client_secret" => app.client_secret, + "id" => app.id |> to_string(), + "redirect_uri" => app.redirect_uris, + "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) + } + + assert expected == json_response_and_validate_schema(creation, 200) + + response = + conn + |> put_req_header("content-type", "application/json") + |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["read", "follow"])) + |> get("/api/v1/pleroma/apps") + |> json_response_and_validate_schema(200) + + [apps] = response + + assert length(response) == 1 + assert apps["client_id"] == app.client_id + end +end From 2e59cdd80f3e3d14c59aeba1fde2f8f9b8305e1f Mon Sep 17 00:00:00 2001 From: Sean King Date: Sun, 29 Aug 2021 07:22:03 -0600 Subject: [PATCH 08/36] Fix aliases sorting --- lib/pleroma/web/mastodon_api/controllers/app_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index 466508137..d2a35dce2 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -11,8 +11,8 @@ defmodule Pleroma.Web.MastodonAPI.AppController do use Pleroma.Web, :controller alias Pleroma.Maps - alias Pleroma.User alias Pleroma.Repo + alias Pleroma.User alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token From 3117c6099733207b7f2a777f8cb8b5b3b839ebe8 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sun, 29 Aug 2021 07:25:54 -0600 Subject: [PATCH 09/36] Make suggested change for create_response --- lib/pleroma/web/api_spec/operations/app_operation.ex | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/app_operation.ex b/lib/pleroma/web/api_spec/operations/app_operation.ex index 5e72c4824..2284ac127 100644 --- a/lib/pleroma/web/api_spec/operations/app_operation.ex +++ b/lib/pleroma/web/api_spec/operations/app_operation.ex @@ -23,7 +23,7 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do operationId: "AppController.create", requestBody: Helpers.request_body("Parameters", create_request(), required: true), responses: %{ - 200 => create_response(), + 200 => Operation.response("App", "application/json", App), 422 => Operation.response( "Unprocessable Entity", @@ -120,8 +120,4 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do } } end - - defp create_response do - Operation.response("App", "application/json", App) - end end From 949a53e327fa2d4ca2099cd4ca6fa2e3fd9e789a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 5 Dec 2021 17:46:56 -0500 Subject: [PATCH 10/36] Log Ecto queries > 500ms --- lib/pleroma/telemetry/logger.ex | 45 +++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/telemetry/logger.ex b/lib/pleroma/telemetry/logger.ex index 44d2f48dc..1dea13acd 100644 --- a/lib/pleroma/telemetry/logger.ex +++ b/lib/pleroma/telemetry/logger.ex @@ -12,10 +12,16 @@ defmodule Pleroma.Telemetry.Logger do [:pleroma, :connection_pool, :reclaim, :stop], [:pleroma, :connection_pool, :provision_failure], [:pleroma, :connection_pool, :client, :dead], - [:pleroma, :connection_pool, :client, :add] + [:pleroma, :connection_pool, :client, :add], + [:pleroma, :repo, :query] ] def attach do - :telemetry.attach_many("pleroma-logger", @events, &handle_event/4, []) + :telemetry.attach_many( + "pleroma-logger", + @events, + &Pleroma.Telemetry.Logger.handle_event/4, + [] + ) end # Passing anonymous functions instead of strings to logger is intentional, @@ -91,4 +97,39 @@ defmodule Pleroma.Telemetry.Logger do end def handle_event([:pleroma, :connection_pool, :client, :add], _, _, _), do: :ok + + def handle_event( + [:pleroma, :repo, :query] = _name, + %{query_time: query_time} = _measurements, + %{source: source, query: query} = _metadata, + _config + ) + when query_time > 500_000 and source not in [nil, "oban_jobs"] do + {:current_stacktrace, stacktrace} = Process.info(self(), :current_stacktrace) + + stacktrace = + Enum.filter(stacktrace, fn + {__MODULE__, _, _, _} -> + false + + {mod, _, _, _} -> + mod + |> to_string() + |> String.starts_with?("Elixir.Pleroma.") + end) + + Logger.warn(fn -> + """ + Query took longer than 500ms! + + Total time: #{query_time / 1_000}ms + + #{inspect(query)} + + #{inspect(stacktrace, pretty: true)} + """ + end) + end + + def handle_event([:pleroma, :repo, :query], _measurements, _metadata, _config), do: :ok end From abb62dd8863a3fde0d329e2d529bca8346e9b177 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Wed, 15 Dec 2021 13:53:09 -0500 Subject: [PATCH 11/36] Application, dependencies: prepare for finch --- lib/pleroma/application.ex | 4 ++++ mix.exs | 5 ++--- mix.lock | 9 ++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 9824e0a4a..34eaed181 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -61,6 +61,10 @@ defmodule Pleroma.Application do adapter = Application.get_env(:tesla, :adapter) + if adapter == Tesla.Adapter.Finch do + Finch.start_link(name: MyFinch) + end + if adapter == Tesla.Adapter.Gun do if version = Pleroma.OTPVersion.version() do [major, minor] = diff --git a/mix.exs b/mix.exs index e69c737dd..581b07f67 100644 --- a/mix.exs +++ b/mix.exs @@ -137,6 +137,7 @@ defmodule Pleroma.Mixfile do {:castore, "~> 0.1"}, {:cowlib, "~> 2.9", override: true}, {:gun, "~> 2.0.0-rc.1", override: true}, + {:finch, "~> 0.10.0"}, {:jason, "~> 1.2"}, {:mogrify, "~> 0.9.1"}, {:ex_aws, "~> 2.1.6"}, @@ -192,9 +193,7 @@ defmodule Pleroma.Mixfile do git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"}, {:restarter, path: "./restarter"}, - {:majic, - git: "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", - ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"}, + {:majic, "~> 1.0"}, {:eblurhash, "~> 1.1.0"}, {:open_api_spex, "~> 3.10"}, diff --git a/mix.lock b/mix.lock index 18d5e3bea..f9646d7ac 100644 --- a/mix.lock +++ b/mix.lock @@ -45,9 +45,10 @@ "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, "excoveralls": {:hex, :excoveralls, "0.12.3", "2142be7cb978a3ae78385487edda6d1aff0e482ffc6123877bb7270a8ffbcfe0", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "568a3e616c264283f5dea5b020783ae40eef3f7ee2163f7a67cbd7b35bcadada"}, - "fast_html": {:hex, :fast_html, "2.0.4", "4910ee49f2f6b19692e3bf30bf97f1b6b7dac489cd6b0f34cd0fe3042c56ba30", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "3bb49d541dfc02ad5e425904f53376d758c09f89e521afc7d2b174b3227761ea"}, + "fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"}, "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "finch": {:hex, :finch, "0.10.0", "8e5e6101ae98e7f1ef830594f774411a2f9cbce4f92d8179502da69fbbff52bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80324ba22edbdebca6fac05c8517e7457b79dfe101e3bf6b2f7c5c65c93a9077"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, "floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"}, @@ -68,7 +69,7 @@ "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, "linkify": {:hex, :linkify, "0.5.1", "6dc415cbc948b2f6ecec7cb226aab7ba9d3a1815bb501ae33e042334d707ecee", [:mix], [], "hexpm", "a3128c7e22fada4aa7214009501d8131e1fa3faf2f0a68b33dba379dc84ff944"}, - "majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "289cda1b6d0d70ccb2ba508a2b0bd24638db2880", [ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"]}, + "majic": {:hex, :majic, "1.0.0", "f493c28a9f38338b5f0abae4a9f31b6a9bdaffe8b1cc62742a7fedf9290dd182", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "03d7c48087da15039c5273bfb85da990b3fb08d2f541612fc9222dbae4bd7adc"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, @@ -76,13 +77,15 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"}, "mox": {:hex, :mox, "1.0.0", "4b3c7005173f47ff30641ba044eb0fe67287743eec9bd9545e37f3002b0a9f8b", [:mix], [], "hexpm", "201b0a20b7abdaaab083e9cf97884950f8a30a1350a1da403b3145e213c6f4df"}, "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]}, + "nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"}, - "nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"}, + "nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"}, "open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"}, From 4e98ba3c3a96548fe6d7fa8705898c660b788fea Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Wed, 15 Dec 2021 15:42:37 -0500 Subject: [PATCH 12/36] Application: Actually start finch if it's needed --- lib/pleroma/application.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 34eaed181..952579c7f 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -61,7 +61,8 @@ defmodule Pleroma.Application do adapter = Application.get_env(:tesla, :adapter) - if adapter == Tesla.Adapter.Finch do + if match?({Tesla.Adapter.Finch, _}, adapter) do + Logger.info("Starting Finch") Finch.start_link(name: MyFinch) end From 5660bee2dcfd200c726c7d7ce40b1f6b8d5048f2 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Thu, 16 Dec 2021 11:36:58 -0600 Subject: [PATCH 13/36] Dirty hack to make mediaproxy functional by relying on Hackney for that part --- lib/pleroma/reverse_proxy/client/wrapper.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pleroma/reverse_proxy/client/wrapper.ex b/lib/pleroma/reverse_proxy/client/wrapper.ex index 06dd29fea..ce144559f 100644 --- a/lib/pleroma/reverse_proxy/client/wrapper.ex +++ b/lib/pleroma/reverse_proxy/client/wrapper.ex @@ -25,5 +25,6 @@ defmodule Pleroma.ReverseProxy.Client.Wrapper do defp client(Tesla.Adapter.Hackney), do: Pleroma.ReverseProxy.Client.Hackney defp client(Tesla.Adapter.Gun), do: Pleroma.ReverseProxy.Client.Tesla + defp client({Tesla.Adapter.Finch, _}), do: Pleroma.ReverseProxy.Client.Hackney defp client(_), do: Pleroma.Config.get!(Pleroma.ReverseProxy.Client) end From e009950845c6d1e7864bb68ea1258c58438ee3aa Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sun, 19 Dec 2021 20:35:00 +0300 Subject: [PATCH 14/36] Slow queries logging improvements: added EXPLAIN results, listed params, improved stacktrace. --- lib/pleroma/telemetry/logger.ex | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/telemetry/logger.ex b/lib/pleroma/telemetry/logger.ex index 1dea13acd..c079f34f2 100644 --- a/lib/pleroma/telemetry/logger.ex +++ b/lib/pleroma/telemetry/logger.ex @@ -101,13 +101,19 @@ defmodule Pleroma.Telemetry.Logger do def handle_event( [:pleroma, :repo, :query] = _name, %{query_time: query_time} = _measurements, - %{source: source, query: query} = _metadata, + %{source: source, query: query, params: query_params, repo: repo} = _metadata, _config ) when query_time > 500_000 and source not in [nil, "oban_jobs"] do {:current_stacktrace, stacktrace} = Process.info(self(), :current_stacktrace) - stacktrace = + sql_explain = + with {:ok, %{rows: explain_result_rows}} <- + repo.query("EXPLAIN " <> query, query_params, log: false) do + Enum.map_join(explain_result_rows, "\n", & &1) + end + + pleroma_stacktrace = Enum.filter(stacktrace, fn {__MODULE__, _, _, _} -> false @@ -120,13 +126,17 @@ defmodule Pleroma.Telemetry.Logger do Logger.warn(fn -> """ - Query took longer than 500ms! + Slow query! Total time: #{query_time / 1_000}ms - #{inspect(query)} + #{query} - #{inspect(stacktrace, pretty: true)} + #{inspect(query_params)} + + #{sql_explain} + + #{Exception.format_stacktrace(pleroma_stacktrace)} """ end) end From 7ed22589798f7282f12d6b7026da940d14a9351e Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Sun, 26 Dec 2021 17:00:09 +0100 Subject: [PATCH 15/36] Update changelog --- CHANGELOG.md | 1 + mix.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee9e04568..18f6b1c81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - `activeMonth` and `activeHalfyear` fields in NodeInfo usage.users object +- Experimental support for Finch. Put `config :tesla, :adapter, {Tesla.Adapter.Finch, name: MyFinch}` in your secrets file to use it. Reverse Proxy will still use Hackney. ### Fixed - Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies diff --git a/mix.lock b/mix.lock index e9b1ed619..f371a6e41 100644 --- a/mix.lock +++ b/mix.lock @@ -70,7 +70,7 @@ "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, "linkify": {:hex, :linkify, "0.5.1", "6dc415cbc948b2f6ecec7cb226aab7ba9d3a1815bb501ae33e042334d707ecee", [:mix], [], "hexpm", "a3128c7e22fada4aa7214009501d8131e1fa3faf2f0a68b33dba379dc84ff944"}, - "majic": {:hex, :majic, "1.0.0", "f493c28a9f38338b5f0abae4a9f31b6a9bdaffe8b1cc62742a7fedf9290dd182", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "03d7c48087da15039c5273bfb85da990b3fb08d2f541612fc9222dbae4bd7adc"}, + "majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, From 3e9e7178bc90754ad6f5414417079f6484b421e9 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sun, 26 Dec 2021 22:49:00 +0300 Subject: [PATCH 16/36] Configurability of slow queries logging ([:pleroma, :telemetry, :slow_queries_logging]). Adjusted log messages truncation to 65 kb (was default: 8 kb). Non-truncated logging of slow query params. --- config/config.exs | 5 +++++ lib/pleroma/telemetry/logger.ex | 33 +++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/config/config.exs b/config/config.exs index b50c910b1..656778007 100644 --- a/config/config.exs +++ b/config/config.exs @@ -148,6 +148,8 @@ config :pleroma, Pleroma.Web.Endpoint, ] # Configures Elixir's Logger +config :logger, truncate: 65536 + config :logger, :console, level: :debug, format: "\n$time $metadata[$level] $message\n", @@ -852,6 +854,9 @@ config :pleroma, ConcurrentLimiter, [ {Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy, [max_running: 5, max_waiting: 5]} ] +config :pleroma, :telemetry, + slow_queries_logging: [exclude_sources: [nil, "oban_jobs"], min_duration: 500_000] + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/lib/pleroma/telemetry/logger.ex b/lib/pleroma/telemetry/logger.ex index c079f34f2..0f73ecc02 100644 --- a/lib/pleroma/telemetry/logger.ex +++ b/lib/pleroma/telemetry/logger.ex @@ -100,19 +100,34 @@ defmodule Pleroma.Telemetry.Logger do def handle_event( [:pleroma, :repo, :query] = _name, - %{query_time: query_time} = _measurements, - %{source: source, query: query, params: query_params, repo: repo} = _metadata, - _config - ) - when query_time > 500_000 and source not in [nil, "oban_jobs"] do - {:current_stacktrace, stacktrace} = Process.info(self(), :current_stacktrace) + %{query_time: query_time} = measurements, + %{source: source} = metadata, + config + ) do + logging_config = Pleroma.Config.get([:telemetry, :slow_queries_logging], []) + if logging_config[:min_duration] && query_time > logging_config[:min_duration] and + (is_nil(logging_config[:exclude_sources]) or + source not in logging_config[:exclude_sources]) do + log_slow_query(measurements, metadata, config) + else + :ok + end + end + + defp log_slow_query( + %{query_time: query_time} = _measurements, + %{source: _source, query: query, params: query_params, repo: repo} = _metadata, + _config + ) do sql_explain = with {:ok, %{rows: explain_result_rows}} <- repo.query("EXPLAIN " <> query, query_params, log: false) do Enum.map_join(explain_result_rows, "\n", & &1) end + {:current_stacktrace, stacktrace} = Process.info(self(), :current_stacktrace) + pleroma_stacktrace = Enum.filter(stacktrace, fn {__MODULE__, _, _, _} -> @@ -128,11 +143,11 @@ defmodule Pleroma.Telemetry.Logger do """ Slow query! - Total time: #{query_time / 1_000}ms + Total time: #{round(query_time / 1_000)} ms #{query} - #{inspect(query_params)} + #{inspect(query_params, limit: :infinity)} #{sql_explain} @@ -140,6 +155,4 @@ defmodule Pleroma.Telemetry.Logger do """ end) end - - def handle_event([:pleroma, :repo, :query], _measurements, _metadata, _config), do: :ok end From cd1041c3a413b9b3ba4c763308b5fd77a53d7c3c Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 27 Dec 2021 02:27:48 +0300 Subject: [PATCH 17/36] API: optionally restrict moderators from accessing sensitive data --- CHANGELOG.md | 3 +- config/config.exs | 3 +- config/description.exs | 5 +++ .../web/plugs/ensure_staff_privileged.ex | 31 +++++++++++++++++++ lib/pleroma/web/router.ex | 31 +++++++++++++------ 5 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 lib/pleroma/web/plugs/ensure_staff_privileged.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index ee9e04568..79fe674a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - `activeMonth` and `activeHalfyear` fields in NodeInfo usage.users object +- AdminAPI: allow moderators to manage reports, users, invites, and custom emojis +- AdminAPI: restrict moderators to access sensitive data: change user credentials, get password reset token, read private statuses and chats, etc ### Fixed - Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies @@ -67,7 +69,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Attachment dimensions and blurhashes are federated when available. - Mastodon API: support `poll` notification. - Pinned posts federation -- AdminAPI: allow moderators to manage reports, users, invites, and custom emojis ### Fixed - Don't crash so hard when email settings are invalid. diff --git a/config/config.exs b/config/config.exs index 23c41eddd..ec242cadc 100644 --- a/config/config.exs +++ b/config/config.exs @@ -255,7 +255,8 @@ config :pleroma, :instance, ], show_reactions: true, password_reset_token_validity: 60 * 60 * 24, - profile_directory: true + profile_directory: true, + privileged_staff: false config :pleroma, :welcome, direct_message: [ diff --git a/config/description.exs b/config/description.exs index 517077acf..a8fbd4d73 100644 --- a/config/description.exs +++ b/config/description.exs @@ -941,6 +941,11 @@ config :pleroma, :config_description, [ key: :profile_directory, type: :boolean, description: "Enable profile directory." + }, + %{ + key: :privileged_staff, + type: :boolean, + description: "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" } ] }, diff --git a/lib/pleroma/web/plugs/ensure_staff_privileged.ex b/lib/pleroma/web/plugs/ensure_staff_privileged.ex new file mode 100644 index 000000000..b15ddfc56 --- /dev/null +++ b/lib/pleroma/web/plugs/ensure_staff_privileged.ex @@ -0,0 +1,31 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug do + @moduledoc """ + Ensures if staff are privileged enough to do certain tasks + """ + + import Pleroma.Web.TranslationHelpers + import Plug.Conn + + alias Pleroma.User + alias Pleroma.Config + + def init(options) do + options + end + + def call(%{assigns: %{user: %User{is_admin: true}}} = conn, _), do: conn + + def call(conn, _) do + if Config.get!([:instance, :privileged_staff]) do + conn + else + conn + |> render_error(:forbidden, "User is not an admin.") + |> halt() + end + end +end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index b2ca09784..7ba72994b 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -101,6 +101,10 @@ defmodule Pleroma.Web.Router do plug(Pleroma.Web.Plugs.IdempotencyPlug) end + pipeline :require_privileged_staff do + plug(Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug) + end + pipeline :require_admin do plug(Pleroma.Web.Plugs.UserIsAdminPlug) end @@ -228,6 +232,24 @@ defmodule Pleroma.Web.Router do post("/backups", AdminAPIController, :create_backup) end + # AdminAPI: admins and mods (staff) can perform these actions (if enabled by config) + scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do + pipe_through([:admin_api, :require_privileged_staff]) + + delete("/users", UserController, :delete) + + get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) + patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) + + get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses) + get("/users/:nickname/chats", AdminAPIController, :list_user_chats) + + get("/statuses", StatusController, :index) + + get("/chats/:id", ChatController, :show) + get("/chats/:id/messages", ChatController, :messages) + end + # AdminAPI: admins and mods (staff) can perform these actions scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do pipe_through(:admin_api) @@ -240,22 +262,16 @@ defmodule Pleroma.Web.Router do patch("/users/deactivate", UserController, :deactivate) patch("/users/approve", UserController, :approve) - delete("/users", UserController, :delete) - post("/users/invite_token", InviteController, :create) get("/users/invites", InviteController, :index) post("/users/revoke_invite", InviteController, :revoke) post("/users/email_invite", InviteController, :email) - get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) patch("/users/force_password_reset", AdminAPIController, :force_password_reset) get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials) - patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) get("/users", UserController, :index) get("/users/:nickname", UserController, :show) - get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses) - get("/users/:nickname/chats", AdminAPIController, :list_user_chats) get("/instances/:instance/statuses", InstanceController, :list_statuses) delete("/instances/:instance", InstanceController, :delete) @@ -269,15 +285,12 @@ defmodule Pleroma.Web.Router do get("/statuses/:id", StatusController, :show) put("/statuses/:id", StatusController, :update) delete("/statuses/:id", StatusController, :delete) - get("/statuses", StatusController, :index) get("/moderation_log", AdminAPIController, :list_log) post("/reload_emoji", AdminAPIController, :reload_emoji) get("/stats", AdminAPIController, :stats) - get("/chats/:id", ChatController, :show) - get("/chats/:id/messages", ChatController, :messages) delete("/chats/:id/messages/:message_id", ChatController, :delete_message) end From 1c223331fc7276a7e5946b6dbd5d2b713cd6c1e8 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 27 Dec 2021 02:28:09 +0300 Subject: [PATCH 18/36] API: show info about privileged staff in instance metadata --- lib/pleroma/web/mastodon_api/views/instance_view.ex | 3 ++- lib/pleroma/web/nodeinfo/nodeinfo.ex | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index 7072d5d61..8e657ee0f 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -45,7 +45,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do features: features(), federation: federation(), fields_limits: fields_limits(), - post_formats: Config.get([:instance, :allowed_post_formats]) + post_formats: Config.get([:instance, :allowed_post_formats]), + privileged_staff: Config.get([:instance, :privileged_staff]) }, stats: %{mau: Pleroma.User.active_user_count()}, vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) diff --git a/lib/pleroma/web/nodeinfo/nodeinfo.ex b/lib/pleroma/web/nodeinfo/nodeinfo.ex index 3781781c8..80a2ce676 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo.ex @@ -69,7 +69,8 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false), features: features, restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]), - skipThreadContainment: Config.get([:instance, :skip_thread_containment], false) + skipThreadContainment: Config.get([:instance, :skip_thread_containment], false), + privilegedStaff: Config.get([:instance, :privileged_staff]) } } end From f66675f349a6e6b8111280e1abd23871688f6179 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 27 Dec 2021 02:57:54 +0300 Subject: [PATCH 19/36] API: fix duplicate :get_password_token route --- lib/pleroma/web/router.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 7ba72994b..5473cd93d 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -199,7 +199,6 @@ defmodule Pleroma.Web.Router do post("/relay", RelayController, :follow) delete("/relay", RelayController, :unfollow) - get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) patch("/users/force_password_reset", AdminAPIController, :force_password_reset) get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials) patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) From f02715c4b2bfe5b1f055e44d8fece2047d85b611 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 27 Dec 2021 03:12:32 +0300 Subject: [PATCH 20/36] Fix lint errors --- config/description.exs | 3 ++- ...ure_staff_privileged.ex => ensure_staff_privileged_plug.ex} | 2 +- lib/pleroma/web/router.ex | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename lib/pleroma/web/plugs/{ensure_staff_privileged.ex => ensure_staff_privileged_plug.ex} (100%) diff --git a/config/description.exs b/config/description.exs index a8fbd4d73..ea3f34abe 100644 --- a/config/description.exs +++ b/config/description.exs @@ -945,7 +945,8 @@ config :pleroma, :config_description, [ %{ key: :privileged_staff, type: :boolean, - description: "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" + description: + "Let moderators access sensitive data (e.g. updating user credentials, get password reset token, delete users, index and read private statuses and chats)" } ] }, diff --git a/lib/pleroma/web/plugs/ensure_staff_privileged.ex b/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex similarity index 100% rename from lib/pleroma/web/plugs/ensure_staff_privileged.ex rename to lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex index b15ddfc56..fe0a11dec 100644 --- a/lib/pleroma/web/plugs/ensure_staff_privileged.ex +++ b/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex @@ -10,8 +10,8 @@ defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug do import Pleroma.Web.TranslationHelpers import Plug.Conn - alias Pleroma.User alias Pleroma.Config + alias Pleroma.User def init(options) do options diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 5473cd93d..02ca8d70a 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -238,7 +238,7 @@ defmodule Pleroma.Web.Router do delete("/users", UserController, :delete) get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) - patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) + patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses) get("/users/:nickname/chats", AdminAPIController, :list_user_chats) From 08c0f09bad040ea713893be822342867f589efbe Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 27 Dec 2021 09:13:31 +0300 Subject: [PATCH 21/36] Made slow queries logging disabled by default. --- config/config.exs | 6 +++++- lib/pleroma/telemetry/logger.ex | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/config.exs b/config/config.exs index 656778007..30113a2e3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -855,7 +855,11 @@ config :pleroma, ConcurrentLimiter, [ ] config :pleroma, :telemetry, - slow_queries_logging: [exclude_sources: [nil, "oban_jobs"], min_duration: 500_000] + slow_queries_logging: [ + enabled: false, + min_duration: 500_000, + exclude_sources: [nil, "oban_jobs"] + ] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/lib/pleroma/telemetry/logger.ex b/lib/pleroma/telemetry/logger.ex index 0f73ecc02..d7fea9c0f 100644 --- a/lib/pleroma/telemetry/logger.ex +++ b/lib/pleroma/telemetry/logger.ex @@ -106,7 +106,9 @@ defmodule Pleroma.Telemetry.Logger do ) do logging_config = Pleroma.Config.get([:telemetry, :slow_queries_logging], []) - if logging_config[:min_duration] && query_time > logging_config[:min_duration] and + if logging_config[:enabled] && + logging_config[:min_duration] && + query_time > logging_config[:min_duration] and (is_nil(logging_config[:exclude_sources]) or source not in logging_config[:exclude_sources]) do log_slow_query(measurements, metadata, config) From 479fc5fff8355e552c5d2297d83f4ca7456d4f03 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 10:39:59 -0600 Subject: [PATCH 22/36] EnsureStaffPrivilegedPlug: add tests --- .../ensure_staff_privileged_plug_test.exs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs diff --git a/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs b/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs new file mode 100644 index 000000000..74f4ae504 --- /dev/null +++ b/test/pleroma/web/plugs/ensure_staff_privileged_plug_test.exs @@ -0,0 +1,60 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlugTest do + use Pleroma.Web.ConnCase, async: true + + alias Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug + import Pleroma.Factory + + test "accepts a user that is an admin" do + user = insert(:user, is_admin: true) + + conn = assign(build_conn(), :user, user) + + ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{}) + + assert conn == ret_conn + end + + test "accepts a user that is a moderator when :privileged_staff is enabled" do + clear_config([:instance, :privileged_staff], true) + user = insert(:user, is_moderator: true) + + conn = assign(build_conn(), :user, user) + + ret_conn = EnsureStaffPrivilegedPlug.call(conn, %{}) + + assert conn == ret_conn + end + + test "denies a user that is a moderator when :privileged_staff is disabled" do + clear_config([:instance, :privileged_staff], false) + user = insert(:user, is_moderator: true) + + conn = + build_conn() + |> assign(:user, user) + |> EnsureStaffPrivilegedPlug.call(%{}) + + assert conn.status == 403 + end + + test "denies a user that isn't a staff member" do + user = insert(:user) + + conn = + build_conn() + |> assign(:user, user) + |> EnsureStaffPrivilegedPlug.call(%{}) + + assert conn.status == 403 + end + + test "denies when a user isn't set" do + conn = EnsureStaffPrivilegedPlug.call(build_conn(), %{}) + + assert conn.status == 403 + end +end From d61a5515e6a7b22c226ee465578cbc5cccce18e4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 11:27:25 -0600 Subject: [PATCH 23/36] ConnectionPoolTest: tag erratic test --- test/pleroma/gun/connection_pool_test.exs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/pleroma/gun/connection_pool_test.exs b/test/pleroma/gun/connection_pool_test.exs index 4b3158625..51637f541 100644 --- a/test/pleroma/gun/connection_pool_test.exs +++ b/test/pleroma/gun/connection_pool_test.exs @@ -46,6 +46,7 @@ defmodule Pleroma.Gun.ConnectionPoolTest do end end + @tag :erratic test "connection limit is respected with concurrent requests" do clear_config([:connections_pool, :max_connections]) do clear_config([:connections_pool, :max_connections], 1) From a3fa9876118942e134f7c50778b4c20f899e0df7 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 16:58:10 -0600 Subject: [PATCH 24/36] AdminAPI: fix duplicated routes --- lib/pleroma/web/router.ex | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 02ca8d70a..6defc8080 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -266,9 +266,6 @@ defmodule Pleroma.Web.Router do post("/users/revoke_invite", InviteController, :revoke) post("/users/email_invite", InviteController, :email) - patch("/users/force_password_reset", AdminAPIController, :force_password_reset) - get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials) - get("/users", UserController, :index) get("/users/:nickname", UserController, :show) From 138f5a4517b7035597a4622a0dc293b6dec7a372 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 17:18:26 -0600 Subject: [PATCH 25/36] EnsureStaffPrivilegedPlug: don't let non-moderators through --- lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex b/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex index fe0a11dec..c6ed45635 100644 --- a/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex +++ b/lib/pleroma/web/plugs/ensure_staff_privileged_plug.ex @@ -4,9 +4,8 @@ defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug do @moduledoc """ - Ensures if staff are privileged enough to do certain tasks + Ensures staff are privileged enough to do certain tasks. """ - import Pleroma.Web.TranslationHelpers import Plug.Conn @@ -19,7 +18,7 @@ defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug do def call(%{assigns: %{user: %User{is_admin: true}}} = conn, _), do: conn - def call(conn, _) do + def call(%{assigns: %{user: %User{is_moderator: true}}} = conn, _) do if Config.get!([:instance, :privileged_staff]) do conn else @@ -28,4 +27,10 @@ defmodule Pleroma.Web.Plugs.EnsureStaffPrivilegedPlug do |> halt() end end + + def call(conn, _) do + conn + |> render_error(:forbidden, "User is not a staff member.") + |> halt() + end end From fa35e24a5ec70ecd92e9e31d1e13da44b9e27b6d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 18:05:35 -0600 Subject: [PATCH 26/36] Apps: add user_id index --- priv/repo/migrations/20210818023112_add_user_id_to_apps.exs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs b/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs index 39e7fbef5..88a6bce00 100644 --- a/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs +++ b/priv/repo/migrations/20210818023112_add_user_id_to_apps.exs @@ -5,5 +5,7 @@ defmodule Pleroma.Repo.Migrations.AddUserIdToApps do alter table(:apps) do add(:user_id, references(:users, type: :uuid, on_delete: :delete_all)) end + + create_if_not_exists(index(:apps, [:user_id])) end end From 2e4a1c56c36fcd4b9ef34bd3a771abfe21cc71d5 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 18:14:15 -0600 Subject: [PATCH 27/36] AppController: test creating with and without a user --- .../controllers/app_controller.ex | 13 ++++----- .../controllers/app_controller_test.exs | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index 079382b17..ef7331bf3 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -28,15 +28,9 @@ defmodule Pleroma.Web.MastodonAPI.AppController do defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation @doc "POST /api/v1/apps" - def create(%{assigns: %{user: user}, body_params: params} = conn, _params) do + def create(%{body_params: params} = conn, _params) do scopes = Scopes.fetch_scopes(params, ["read"]) - - user_id = - with %User{id: id} <- user do - id - else - _ -> nil - end + user_id = get_user_id(conn) app_attrs = params @@ -50,6 +44,9 @@ defmodule Pleroma.Web.MastodonAPI.AppController do end end + defp get_user_id(%{assigns: %{user: %User{id: user_id}}}), do: user_id + defp get_user_id(_conn), do: nil + @doc """ GET /api/v1/apps/verify_credentials Gets compact non-secret representation of the app. Supports app tokens and user tokens. diff --git a/test/pleroma/web/mastodon_api/controllers/app_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/app_controller_test.exs index 76d81b942..bfbb7f32d 100644 --- a/test/pleroma/web/mastodon_api/controllers/app_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/app_controller_test.exs @@ -35,6 +35,33 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do end test "creates an oauth app", %{conn: conn} do + app_attrs = build(:oauth_app) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/apps", %{ + client_name: app_attrs.client_name, + redirect_uris: app_attrs.redirect_uris + }) + + [app] = Repo.all(App) + + expected = %{ + "name" => app.client_name, + "website" => app.website, + "client_id" => app.client_id, + "client_secret" => app.client_secret, + "id" => app.id |> to_string(), + "redirect_uri" => app.redirect_uris, + "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) + } + + assert expected == json_response_and_validate_schema(conn, 200) + assert app.user_id == nil + end + + test "creates an oauth app with a user", %{conn: conn} do user = insert(:user) app_attrs = build(:oauth_app) @@ -60,5 +87,6 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do } assert expected == json_response_and_validate_schema(conn, 200) + assert app.user_id == user.id end end From cb2a072e6252b7c3f6473f7cfd1af5c0ec732d7b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 18:29:03 -0600 Subject: [PATCH 28/36] Apps: add test for get_user_apps/1 --- test/pleroma/web/o_auth/app_test.exs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/pleroma/web/o_auth/app_test.exs b/test/pleroma/web/o_auth/app_test.exs index fc2f0d940..a5223b0a5 100644 --- a/test/pleroma/web/o_auth/app_test.exs +++ b/test/pleroma/web/o_auth/app_test.exs @@ -41,4 +41,16 @@ defmodule Pleroma.Web.OAuth.AppTest do assert error.type == :unique end end + + test "get_user_apps/1" do + user = insert(:user) + + apps = [ + insert(:oauth_app, user_id: user.id), + insert(:oauth_app, user_id: user.id), + insert(:oauth_app, user_id: user.id) + ] + + assert App.get_user_apps(user) == apps + end end From 7704a722c06c9658d4037167dc5b6f01a4582b14 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 18:30:16 -0600 Subject: [PATCH 29/36] AppController: remove unnecessary `require Logger` --- lib/pleroma/web/mastodon_api/controllers/app_controller.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index ef7331bf3..8d18140ad 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -17,8 +17,6 @@ defmodule Pleroma.Web.MastodonAPI.AppController do alias Pleroma.Web.OAuth.Scopes alias Pleroma.Web.OAuth.Token - require Logger - action_fallback(Pleroma.Web.MastodonAPI.FallbackController) plug(:skip_auth when action in [:create, :verify_credentials]) From 5c80d4087df2f6a8436af87ad109eb9e3bd4e3c1 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 27 Dec 2021 18:52:34 -0600 Subject: [PATCH 30/36] PleromaAPI.AppView: add test --- .../web/pleroma_api/views/app_view_test.exs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/pleroma/web/pleroma_api/views/app_view_test.exs diff --git a/test/pleroma/web/pleroma_api/views/app_view_test.exs b/test/pleroma/web/pleroma_api/views/app_view_test.exs new file mode 100644 index 000000000..f0aee6987 --- /dev/null +++ b/test/pleroma/web/pleroma_api/views/app_view_test.exs @@ -0,0 +1,21 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.AppViewTest do + use Pleroma.DataCase, async: true + alias Pleroma.Web.PleromaAPI.AppView + import Pleroma.Factory + + test "index.json" do + apps = [ + insert(:oauth_app), + insert(:oauth_app), + insert(:oauth_app) + ] + + results = AppView.render("index.json", %{apps: apps}) + + assert [%{client_id: _, client_secret: _}, _, _] = results + end +end From f734579965b6f1a635e0622356e9cf6d4fff00bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 28 Dec 2021 16:11:17 +0100 Subject: [PATCH 31/36] MastoAPI: Add `GET /api/v1/accounts/lookup` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../api_spec/operations/account_operation.ex | 20 ++++++++++++++++ .../controllers/account_controller.ex | 12 ++++++++++ lib/pleroma/web/router.ex | 2 ++ .../controllers/account_controller_test.exs | 24 +++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 54e5ebc76..5836cab50 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -371,6 +371,26 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do } end + def lookup_operation do + %Operation{ + tags: ["Account lookup"], + summary: "Find a user by nickname", + operationId: "AccountController.lookup", + parameters: [ + Operation.parameter( + :acct, + :query, + :string, + "User nickname" + ) + ], + responses: %{ + 200 => Operation.response("Account", "application/json", Account), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + def endorsements_operation do %Operation{ tags: ["Retrieve account information"], diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 5fcbffc34..3eae0a646 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -477,6 +477,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do |> render("index.json", users: users, for: user, as: :user) end + @doc "GET /api/v1/accounts/lookup" + def lookup(%{assigns: %{user: for_user}} = conn, %{acct: nickname} = _params) do + with %User{} = user <- User.get_by_nickname(nickname) do + render(conn, "show.json", + user: user, + for: for_user + ) + else + error -> user_visibility_error(conn, error) + end + end + @doc "GET /api/v1/endorsements" def endorsements(conn, params), do: MastodonAPIController.empty_array(conn, params) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 5fbc2509e..ae373e58c 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -573,6 +573,8 @@ defmodule Pleroma.Web.Router do get("/accounts/search", SearchController, :account_search) get("/search", SearchController, :search) + get("/accounts/lookup", AccountController, :lookup) + get("/accounts/:id/statuses", AccountController, :statuses) get("/accounts/:id/followers", AccountController, :followers) get("/accounts/:id/following", AccountController, :following) diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index a92a58224..86349619e 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -1776,4 +1776,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert [%{"id" => ^id2}] = result end + + test "account lookup", %{conn: conn} do + %{nickname: acct} = insert(:user, %{nickname: "nickname"}) + %{nickname: acct_two} = insert(:user, %{nickname: "nickname@notlocaldoma.in"}) + + result = + conn + |> get("/api/v1/accounts/lookup?acct=#{acct}") + |> json_response_and_validate_schema(200) + + assert %{"acct" => ^acct} = result + + result = + conn + |> get("/api/v1/accounts/lookup?acct=#{acct_two}") + |> json_response_and_validate_schema(200) + + assert %{"acct" => ^acct_two} = result + + _result = + conn + |> get("/api/v1/accounts/lookup?acct=unexisting_nickname") + |> json_response_and_validate_schema(404) + end end From 0dd1caa841386b99bcbe4adeef2c1cde5e6a377a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 28 Dec 2021 18:24:48 +0100 Subject: [PATCH 32/36] AccountController.lookup: skip visibility check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../web/mastodon_api/controllers/account_controller.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 399a34217..6d8fcd026 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -493,11 +493,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do end @doc "GET /api/v1/accounts/lookup" - def lookup(%{assigns: %{user: for_user}} = conn, %{acct: nickname} = _params) do + def lookup(conn, %{acct: nickname} = _params) do with %User{} = user <- User.get_by_nickname(nickname) do render(conn, "show.json", user: user, - for: for_user + skip_visibility_check: true ) else error -> user_visibility_error(conn, error) From 1657db656cef7a6947e76d5213a04a1764a19cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 28 Dec 2021 20:02:59 +0100 Subject: [PATCH 33/36] AccountController.lookup: skip auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- lib/pleroma/web/mastodon_api/controllers/account_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 6d8fcd026..a307807a9 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -32,7 +32,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do plug(Pleroma.Web.ApiSpec.CastAndValidate) - plug(:skip_auth when action == :create) + plug(:skip_auth when action in [:create, :lookup]) plug(:skip_public_check when action in [:show, :statuses]) From 5f87472cdf60b987376d8fa6d2123f8acbed0bd9 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 28 Dec 2021 15:11:38 -0600 Subject: [PATCH 34/36] Update CHANGELOG.md --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e527f32de..79b669782 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,11 +18,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Experimental support for Finch. Put `config :tesla, :adapter, {Tesla.Adapter.Finch, name: MyFinch}` in your secrets file to use it. Reverse Proxy will still use Hackney. - AdminAPI: allow moderators to manage reports, users, invites, and custom emojis - AdminAPI: restrict moderators to access sensitive data: change user credentials, get password reset token, read private statuses and chats, etc +- PleromaAPI: Add remote follow API endpoint at `POST /api/v1/pleroma/remote_interaction` +- MastoAPI: Add `GET /api/v1/accounts/lookup` +- MastoAPI: Profile Directory support +- MastoAPI: Support v2 Suggestions (handpicked accounts only) +- Ability to log slow Ecto queries by configuring `:pleroma, :telemetry, :slow_queries_logging` +- Added Phoenix LiveDashboard at `/phoenix/live_dashboard` +- Added `/manifest.json` for progressive web apps. ### Fixed - Subscription(Bell) Notifications: Don't create from Pipeline Ingested replies - Handle Reject for already-accepted Follows properly - Display OpenGraph data on alternative notice routes. +- Fix replies count for remote replies +- ChatAPI: Add link headers +- Limited number of search results to 40 to prevent DoS attacks +- ActivityPub: fixed federation of attachment dimensions +- Fixed benchmarks +- Elixir 1.13 support +- Fixed crash when pinned_objects is nil +- Fixed slow timelines when there are a lot of deactivated users +- Fixed account deletion API ### Removed From 0c7fb520bf7d6d164a2334a23066d1188b2ec0e1 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Wed, 29 Dec 2021 11:41:21 +0300 Subject: [PATCH 35/36] Added index on [:target_id, :relationship_type] to :user_relationships (speeds up `Notification.exclude_blockers/_`). --- ...r_relationships_target_id_relationship_type_index.exs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs diff --git a/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs b/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs new file mode 100644 index 000000000..fcefa6508 --- /dev/null +++ b/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs @@ -0,0 +1,9 @@ +defmodule Pleroma.Repo.Migrations.UserRelationshipsTargetIdRelationshipTypeIndex do + use Ecto.Migration + + def change do + create_if_not_exists( + index(:user_relationships, [:target_id, :relationship_type]) + ) + end +end From a7bdefc208044ef2ad6ba05f646f1cfa1df8e06b Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Wed, 29 Dec 2021 11:44:33 +0300 Subject: [PATCH 36/36] `mix format` --- ...1_user_relationships_target_id_relationship_type_index.exs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs b/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs index fcefa6508..f3eb8409f 100644 --- a/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs +++ b/priv/repo/migrations/20211229075801_user_relationships_target_id_relationship_type_index.exs @@ -2,8 +2,6 @@ defmodule Pleroma.Repo.Migrations.UserRelationshipsTargetIdRelationshipTypeIndex use Ecto.Migration def change do - create_if_not_exists( - index(:user_relationships, [:target_id, :relationship_type]) - ) + create_if_not_exists(index(:user_relationships, [:target_id, :relationship_type])) end end