fix create service actor

This commit is contained in:
Maksim Pechnikov 2020-01-08 16:40:38 +03:00
parent fcd5dd259a
commit 70410dfafd
3 changed files with 80 additions and 14 deletions

View file

@ -1430,9 +1430,36 @@ defmodule Pleroma.User do
Creates an internal service actor by URI if missing. Creates an internal service actor by URI if missing.
Optionally takes nickname for addressing. Optionally takes nickname for addressing.
""" """
def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do @spec get_or_create_service_actor_by_ap_id(String.t(), String.t()) :: User.t() | nil
with user when is_nil(user) <- get_cached_by_ap_id(uri) do def get_or_create_service_actor_by_ap_id(uri, nickname) do
{:ok, user} = {_, user} =
case get_cached_by_ap_id(uri) do
nil ->
with {:error, %{errors: errors}} <- create_service_actor(uri, nickname) do
Logger.error("Cannot create service actor: #{uri}/.\n#{inspect(errors)}")
{:error, nil}
end
%User{invisible: false} = user ->
set_invisible(user)
user ->
{:ok, user}
end
user
end
@spec set_invisible(User.t()) :: {:ok, User.t()}
defp set_invisible(user) do
user
|> change(%{invisible: true})
|> update_and_set_cache()
end
@spec create_service_actor(String.t(), String.t()) ::
{:ok, User.t()} | {:error, Ecto.Changeset.t()}
defp create_service_actor(uri, nickname) do
%User{ %User{
invisible: true, invisible: true,
local: true, local: true,
@ -1440,10 +1467,10 @@ defmodule Pleroma.User do
nickname: nickname, nickname: nickname,
follower_address: uri <> "/followers" follower_address: uri <> "/followers"
} }
|> change
|> unique_constraint(:nickname)
|> Repo.insert() |> Repo.insert()
|> set_cache()
user
end
end end
# AP style # AP style

View file

@ -9,10 +9,12 @@ defmodule Pleroma.Web.ActivityPub.Relay do
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
require Logger require Logger
@relay_nickname "relay"
def get_actor do def get_actor do
actor = actor =
relay_ap_id() relay_ap_id()
|> User.get_or_create_service_actor_by_ap_id() |> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
actor actor
end end

View file

@ -17,6 +17,7 @@ defmodule Pleroma.UserTest do
import Mock import Mock
import Pleroma.Factory import Pleroma.Factory
import ExUnit.CaptureLog
setup_all do setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -26,6 +27,42 @@ defmodule Pleroma.UserTest do
clear_config([:instance, :account_activation_required]) clear_config([:instance, :account_activation_required])
describe "service actors" do describe "service actors" do
test "returns updated invisible actor" do
uri = "#{Pleroma.Web.Endpoint.url()}/relay"
followers_uri = "#{uri}/followers"
insert(
:user,
%{
nickname: "relay",
invisible: false,
local: true,
ap_id: uri,
follower_address: followers_uri
}
)
actor = User.get_or_create_service_actor_by_ap_id(uri, "relay")
assert actor.invisible
end
test "returns relay user" do
uri = "#{Pleroma.Web.Endpoint.url()}/relay"
followers_uri = "#{uri}/followers"
assert %User{
nickname: "relay",
invisible: true,
local: true,
ap_id: ^uri,
follower_address: ^followers_uri
} = User.get_or_create_service_actor_by_ap_id(uri, "relay")
assert capture_log(fn ->
refute User.get_or_create_service_actor_by_ap_id("/relay", "relay")
end) =~ "Cannot create service actor:"
end
test "returns invisible actor" do test "returns invisible actor" do
uri = "#{Pleroma.Web.Endpoint.url()}/internal/fetch-test" uri = "#{Pleroma.Web.Endpoint.url()}/internal/fetch-test"
followers_uri = "#{uri}/followers" followers_uri = "#{uri}/followers"