Refresh profiles in a background task

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-05-12 18:18:20 +02:00
parent 8c53ea442f
commit 4100b2f962
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
6 changed files with 40 additions and 15 deletions

View File

@ -32,9 +32,10 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
end end
def refresh_profile(%Actor{type: type, url: url}) when type in [:Person, :Application] do def refresh_profile(%Actor{type: type, url: url}) when type in [:Person, :Application] do
with {:ok, %Actor{outbox_url: outbox_url}} <- ActivityPubActor.make_actor_from_url(url), with {:ok, %Actor{outbox_url: outbox_url} = actor} <-
ActivityPubActor.make_actor_from_url(url),
:ok <- fetch_collection(outbox_url, Relay.get_actor()) do :ok <- fetch_collection(outbox_url, Relay.get_actor()) do
:ok {:ok, actor}
end end
end end

View File

@ -12,9 +12,10 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Transmogrifier} alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier}
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
alias Mobilizon.Federation.WebFinger alias Mobilizon.Federation.WebFinger
alias Mobilizon.Service.Workers.Background
alias Mobilizon.GraphQL.API.Follows alias Mobilizon.GraphQL.API.Follows
@ -95,13 +96,16 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
end end
end end
@spec refresh(String.t()) :: {:ok, any()}
def refresh(address) do def refresh(address) do
Logger.debug("We're trying to refresh a remote instance") Logger.debug("We're trying to refresh a remote instance")
with {:ok, target_instance} <- fetch_actor(address), with {:ok, target_instance} <- fetch_actor(address),
{:ok, %Actor{} = target_actor} <- {:ok, %Actor{id: target_actor_id}} <-
ActivityPubActor.get_or_fetch_actor_by_url(target_instance) do ActivityPubActor.get_or_fetch_actor_by_url(target_instance) do
Refresher.refresh_profile(target_actor) Background.enqueue("refresh_profile", %{
"actor_id" => target_actor_id
})
end end
end end

View File

@ -17,10 +17,11 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Todos.{Todo, TodoList}
alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Activity, Refresher, Relay, Utils} alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Utils}
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
alias Mobilizon.Federation.ActivityPub.Types.Ownable alias Mobilizon.Federation.ActivityPub.Types.Ownable
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
alias Mobilizon.Service.Workers.Background
alias Mobilizon.Tombstone alias Mobilizon.Tombstone
alias Mobilizon.Web.Email.Participation alias Mobilizon.Web.Email.Participation
alias Mobilizon.Web.Endpoint alias Mobilizon.Web.Endpoint
@ -792,7 +793,9 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
# If this is an instance follow, refresh the followed profile (especially their outbox) # If this is an instance follow, refresh the followed profile (especially their outbox)
if follower.id == relay_actor.id do if follower.id == relay_actor.id do
Refresher.refresh_profile(followed) Background.enqueue("refresh_profile", %{
"actor_id" => followed.id
})
end end
{:ok, activity, follow} {:ok, activity, follow}

View File

@ -7,7 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
alias Mobilizon.{Actors, Admin, Users} alias Mobilizon.{Actors, Admin, Users}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Refresher alias Mobilizon.Service.Workers.Background
alias Mobilizon.Users.User alias Mobilizon.Users.User
import Mobilizon.Web.Gettext import Mobilizon.Web.Gettext
@ -16,8 +16,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
def refresh_profile(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) def refresh_profile(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
when is_admin(role) do when is_admin(role) do
case Actors.get_actor(id) do case Actors.get_actor(id) do
%Actor{domain: domain} = actor when not is_nil(domain) -> %Actor{domain: domain, id: actor_id} = actor when not is_nil(domain) ->
Refresher.refresh_profile(actor) Background.enqueue("refresh_profile", %{
"actor_id" => actor_id
})
{:ok, actor} {:ok, actor}
%Actor{} -> %Actor{} ->
@ -80,7 +83,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
{:delete_tombstones, {_, nil}} <- {:delete_tombstones, {_, nil}} <-
{:delete_tombstones, Mobilizon.Tombstone.delete_actor_tombstones(id)}, {:delete_tombstones, Mobilizon.Tombstone.delete_actor_tombstones(id)},
{:ok, %Actor{} = actor} <- Actors.update_actor(actor, %{suspended: false}), {:ok, %Actor{} = actor} <- Actors.update_actor(actor, %{suspended: false}),
{:ok, %Actor{} = actor} <- refresh_if_remote(actor), :ok <- refresh_if_remote(actor),
{:ok, _} <- Admin.log_action(moderator_actor, "unsuspend", actor) do {:ok, _} <- Admin.log_action(moderator_actor, "unsuspend", actor) do
{:ok, actor} {:ok, actor}
else else
@ -99,7 +102,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
{:error, dgettext("errors", "Only moderators and administrators can unsuspend a profile")} {:error, dgettext("errors", "Only moderators and administrators can unsuspend a profile")}
end end
@spec refresh_if_remote(Actor.t()) :: {:ok, Actor.t()} @spec refresh_if_remote(Actor.t()) :: :ok
defp refresh_if_remote(%Actor{domain: nil} = actor), do: {:ok, actor} defp refresh_if_remote(%Actor{domain: nil}), do: :ok
defp refresh_if_remote(%Actor{} = actor), do: Refresher.refresh_profile(actor)
defp refresh_if_remote(%Actor{id: actor_id}) do
Background.enqueue("refresh_profile", %{
"actor_id" => actor_id
})
:ok
end
end end

View File

@ -14,7 +14,7 @@ defmodule Mix.Tasks.Mobilizon.Relay.Refresh do
IO.puts("Refreshing #{target}, this can take a while.") IO.puts("Refreshing #{target}, this can take a while.")
case Relay.refresh(target) do case Relay.refresh(target) do
:ok -> {:ok, _} ->
IO.puts("Refreshed #{target}") IO.puts("Refreshed #{target}")
err -> err ->

View File

@ -5,6 +5,7 @@ defmodule Mobilizon.Service.Workers.Background do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub.Refresher
use Mobilizon.Service.Workers.Helper, queue: "background" use Mobilizon.Service.Workers.Helper, queue: "background"
@ -22,4 +23,10 @@ defmodule Mobilizon.Service.Workers.Background do
Actors.actor_key_rotation(actor) Actors.actor_key_rotation(actor)
end end
end end
def perform(%Job{args: %{"op" => "refresh_profile", "actor_id" => actor_id}}) do
with %Actor{} = actor <- Actors.get_actor(actor_id) do
Refresher.refresh_profile(actor)
end
end
end end