Check if domains resolve correctly

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2023-11-14 13:51:55 +01:00
parent 34c142e672
commit c3b989951a
8 changed files with 115 additions and 8 deletions

View file

@ -591,10 +591,12 @@
remote_fetcher: 2,
attachments_cleanup: 1,
new_users_digest: 1,
mute_expire: 5
mute_expire: 5,
check_domain_resolve: 1
],
plugins: [Oban.Plugins.Pruner],
crontab: [
{"0 0 * * 0", Pleroma.Workers.Cron.CheckDomainsResolveWorker},
{"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker},
{"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker}
]

View file

@ -12,6 +12,8 @@ defmodule Pleroma.Domain do
schema "domains" do
field(:domain, :string, default: "")
field(:public, :boolean, default: false)
field(:resolves, :boolean, default: false)
field(:last_checked_at, :naive_datetime)
timestamps()
end
@ -29,6 +31,17 @@ def update_changeset(%__MODULE__{} = domain, params \\ %{}) do
|> cast(params, [:public])
end
def update_state_changeset(%__MODULE__{} = domain, resolves) do
domain
|> cast(
%{
resolves: resolves,
last_checked_at: NaiveDateTime.utc_now()
},
[:resolves, :last_checked_at]
)
end
def list do
__MODULE__
|> order_by(asc: :id)

View file

@ -38,6 +38,10 @@ 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
Pleroma.Workers.CheckDomainResolveWorker.enqueue("check_domain_resolve", %{
"id" => domain.id
})
render(conn, "show.json", domain: domain)
else
{:domain_not_used, false} ->

View file

@ -6,16 +6,30 @@ defmodule Pleroma.Web.AdminAPI.DomainView do
use Pleroma.Web, :view
alias Pleroma.Domain
alias Pleroma.Web.CommonAPI.Utils
def render("index.json", %{domains: domains}) do
render_many(domains, __MODULE__, "show.json")
def render("index.json", %{domains: domains} = assigns) do
render_many(domains, __MODULE__, "show.json", assigns |> Map.delete("domains"))
end
def render("show.json", %{domain: %Domain{id: id, domain: domain, public: public}}) do
def render("show.json", %{domain: %Domain{} = domain} = assigns) do
%{
id: id |> to_string(),
domain: domain,
public: public
id: domain.id |> to_string(),
domain: domain.domain,
public: domain.public
}
|> maybe_put_resolve_information(domain, assigns)
end
defp maybe_put_resolve_information(map, _domain, %{admin: false}) do
map
end
defp maybe_put_resolve_information(map, domain, _assigns) do
map
|> Map.merge(%{
resolves: domain.resolves,
last_checked_at: Utils.to_masto_date(domain.last_checked_at)
})
end
end

View file

@ -156,7 +156,7 @@ defp multitenancy do
%{
enabled: true,
domains: DomainView.render("index.json", domains: domains)
domains: DomainView.render("index.json", domains: domains, admin: false)
}
else
nil

View file

@ -0,0 +1,38 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.CheckDomainResolveWorker do
use Pleroma.Workers.WorkerHelper, queue: "check_domain_resolve"
alias Pleroma.Domain
alias Pleroma.HTTP
alias Pleroma.Repo
alias Pleroma.Web.Endpoint
alias Pleroma.Web.WebFinger
@impl Oban.Worker
def perform(%Job{args: %{"op" => "check_domain_resolve", "id" => domain_id}}) do
domain = Domain.get(domain_id)
resolves =
with {:ok, %Tesla.Env{status: status, body: hostmeta_body}} when status in 200..299 <-
HTTP.get("https://" <> domain.domain <> "/.well-known/host-meta"),
{:ok, template} <- WebFinger.get_template_from_xml(hostmeta_body),
base_url <- Endpoint.url(),
true <- template == "#{base_url}/.well-known/webfinger?resource={uri}" do
true
else
_ -> false
end
domain
|> Domain.update_state_changeset(resolves)
|> Repo.update!()
:ok
end
@impl Oban.Worker
def timeout(_job), do: :timer.seconds(5)
end

View file

@ -0,0 +1,34 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.Cron.CheckDomainsResolveWorker do
@moduledoc """
The worker to check if alternative domains resolve correctly.
"""
use Oban.Worker, queue: "check_domain_resolve"
alias Pleroma.Domain
alias Pleroma.Repo
import Ecto.Query
require Logger
@impl Oban.Worker
def perform(_job) do
domains =
Domain
|> select([d], d.id)
|> Repo.all()
Enum.each(domains, fn domain_id ->
Pleroma.Workers.CheckDomainResolveWorker.enqueue("check_domain_resolve", %{
"id" => domain_id
})
end)
:ok
end
end

View file

@ -5,6 +5,8 @@ def change do
create_if_not_exists table(:domains) do
add(:domain, :citext)
add(:public, :boolean)
add(:resolves, :boolean)
add(:last_checked_at, :naive_datetime)
timestamps()
end