diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 7bbc132f12..00103abf25 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -210,7 +210,8 @@ defp cachex_children do expiration: chat_message_id_idempotency_key_expiration(), limit: 500_000 ), - build_cachex("rel_me", limit: 2500) + build_cachex("rel_me", limit: 2500), + build_cachex("domain", limit: 2500) ] end diff --git a/lib/pleroma/domain.ex b/lib/pleroma/domain.ex index d1c633a930..6d518fe00a 100644 --- a/lib/pleroma/domain.ex +++ b/lib/pleroma/domain.ex @@ -2,6 +2,8 @@ # Copyright © 2017-2023 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Domain do + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + use Ecto.Schema import Ecto.Changeset @@ -11,6 +13,7 @@ defmodule Pleroma.Domain do schema "domains" do field(:domain, :string, default: "") + field(:service_domain, :string, default: "") field(:public, :boolean, default: false) field(:resolves, :boolean, default: false) field(:last_checked_at, :naive_datetime) @@ -22,8 +25,10 @@ def changeset(%__MODULE__{} = domain, params \\ %{}) do domain |> cast(params, [:domain, :public]) |> validate_required([:domain]) + |> maybe_add_service_domain() |> update_change(:domain, &String.downcase/1) |> unique_constraint(:domain) + |> unique_constraint(:service_domain) end def update_changeset(%__MODULE__{} = domain, params \\ %{}) do @@ -42,6 +47,12 @@ def update_state_changeset(%__MODULE__{} = domain, resolves) do ) end + defp maybe_add_service_domain(%{changes: %{service_domain: _}} = changeset), do: changeset + + defp maybe_add_service_domain(%{changes: %{domain: domain}} = changeset) do + change(changeset, service_domain: domain) + end + def list do __MODULE__ |> order_by(asc: :id) @@ -66,4 +77,8 @@ def delete(id) do get(id) |> Repo.delete() end + + def cached_list do + @cachex.fetch!(:domain_cache, "domains_list", fn _ -> list() end) + end end diff --git a/lib/pleroma/web/admin_api/controllers/domain_controller.ex b/lib/pleroma/web/admin_api/controllers/domain_controller.ex index 832f6288c0..3dd42c59a0 100644 --- a/lib/pleroma/web/admin_api/controllers/domain_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/domain_controller.ex @@ -3,6 +3,8 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.AdminAPI.DomainController do + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + use Pleroma.Web, :controller alias Pleroma.Domain @@ -37,7 +39,8 @@ def index(conn, _) do def create(%{body_params: params} = conn, _) do with {:domain_not_used, true} <- {:domain_not_used, params[:domain] !== Pleroma.Web.WebFinger.domain()}, - {:ok, domain} <- Domain.create(params) do + {:ok, domain} <- Domain.create(params), + _ <- @cachex.del(:domain, :domains_list) do Pleroma.Workers.CheckDomainResolveWorker.enqueue("check_domain_resolve", %{ "id" => domain.id }) @@ -59,11 +62,14 @@ def update(%{body_params: params} = conn, %{id: id}) do params |> Domain.update(id) + @cachex.del(:domain, :domains_list) + render(conn, "show.json", domain: domain) end def delete(conn, %{id: id}) do - with {:ok, _} <- Domain.delete(id) do + with {:ok, _} <- Domain.delete(id), + _ <- @cachex.del(:domain, :domains_list) do json(conn, %{}) else _ -> json_response(conn, :bad_request, "") diff --git a/lib/pleroma/web/api_spec/operations/admin/domain_operation.ex b/lib/pleroma/web/api_spec/operations/admin/domain_operation.ex index d73c67b3d5..a91872f976 100644 --- a/lib/pleroma/web/api_spec/operations/admin/domain_operation.ex +++ b/lib/pleroma/web/api_spec/operations/admin/domain_operation.ex @@ -84,6 +84,7 @@ defp create_request do required: [:domain], properties: %{ domain: %Schema{type: :string}, + service_domain: %Schema{type: :string, nullable: true}, public: %Schema{type: :boolean, nullable: true} } } @@ -104,7 +105,10 @@ defp domain do properties: %{ id: %Schema{type: :integer}, domain: %Schema{type: :string}, - public: %Schema{type: :boolean} + service_domain: %Schema{type: :string}, + public: %Schema{type: :boolean}, + resolves: %Schema{type: :boolean}, + last_checked_at: %Schema{type: :string, format: "date-time", nullable: true} } } end diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index 9f78c279c0..ecc546ce73 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -152,7 +152,7 @@ defp multitenancy do if enabled do domains = [%Domain{id: "", domain: Pleroma.Web.WebFinger.domain(), public: true}] ++ - Repo.all(Domain) + Domain.cached_list() %{ enabled: true, diff --git a/priv/repo/migrations/20230618190919_create_domains.exs b/priv/repo/migrations/20230618190919_create_domains.exs index 9994a46829..cfb1498949 100644 --- a/priv/repo/migrations/20230618190919_create_domains.exs +++ b/priv/repo/migrations/20230618190919_create_domains.exs @@ -4,6 +4,7 @@ defmodule Pleroma.Repo.Migrations.CreateDomains do def change do create_if_not_exists table(:domains) do add(:domain, :citext) + add(:service_domain, :citext) add(:public, :boolean) add(:resolves, :boolean) add(:last_checked_at, :naive_datetime) @@ -12,6 +13,7 @@ def change do end create_if_not_exists(unique_index(:domains, [:domain])) + create_if_not_exists(unique_index(:domains, [:service_domain])) alter table(:users) do add(:domain_id, references(:domains))