forked from AkkomaGang/akkoma
Transmogrifier: Move following to the pipeline.
This commit is contained in:
parent
29fa75d00d
commit
172f4aff8e
4 changed files with 64 additions and 62 deletions
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator do
|
||||||
field(:to, ObjectValidators.Recipients, default: [])
|
field(:to, ObjectValidators.Recipients, default: [])
|
||||||
field(:cc, ObjectValidators.Recipients, default: [])
|
field(:cc, ObjectValidators.Recipients, default: [])
|
||||||
field(:object, ObjectValidators.ObjectID)
|
field(:object, ObjectValidators.ObjectID)
|
||||||
|
field(:state, :string, default: "pending")
|
||||||
end
|
end
|
||||||
|
|
||||||
def cast_data(data) do
|
def cast_data(data) do
|
||||||
|
@ -30,6 +31,7 @@ def validate_data(cng) do
|
||||||
cng
|
cng
|
||||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||||
|> validate_inclusion(:type, ["Follow"])
|
|> validate_inclusion(:type, ["Follow"])
|
||||||
|
|> validate_inclusion(:state, ~w{pending reject accept})
|
||||||
|> validate_actor_presence()
|
|> validate_actor_presence()
|
||||||
|> validate_actor_presence(field_name: :object)
|
|> validate_actor_presence(field_name: :object)
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
||||||
alias Pleroma.Activity.Ir.Topics
|
alias Pleroma.Activity.Ir.Topics
|
||||||
alias Pleroma.Chat
|
alias Pleroma.Chat
|
||||||
alias Pleroma.Chat.MessageReference
|
alias Pleroma.Chat.MessageReference
|
||||||
|
alias Pleroma.FollowingRelationship
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
|
@ -21,6 +22,65 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
||||||
|
|
||||||
def handle(object, meta \\ [])
|
def handle(object, meta \\ [])
|
||||||
|
|
||||||
|
# Tasks this handle
|
||||||
|
# - Follows if possible
|
||||||
|
# - Sends a notification
|
||||||
|
# - Generates accept or reject if appropriate
|
||||||
|
def handle(
|
||||||
|
%{
|
||||||
|
data: %{
|
||||||
|
"id" => follow_id,
|
||||||
|
"type" => "Follow",
|
||||||
|
"object" => followed_user,
|
||||||
|
"actor" => following_user
|
||||||
|
}
|
||||||
|
} = object,
|
||||||
|
meta
|
||||||
|
) do
|
||||||
|
with %User{} = follower <- User.get_cached_by_ap_id(following_user),
|
||||||
|
%User{} = followed <- User.get_cached_by_ap_id(followed_user),
|
||||||
|
{_, {:ok, _}, _, _} <-
|
||||||
|
{:following, User.follow(follower, followed, :follow_pending), follower, followed} do
|
||||||
|
if followed.local && !followed.locked do
|
||||||
|
Utils.update_follow_state_for_all(object, "accept")
|
||||||
|
FollowingRelationship.update(follower, followed, :follow_accept)
|
||||||
|
|
||||||
|
%{
|
||||||
|
to: [following_user],
|
||||||
|
actor: followed,
|
||||||
|
object: follow_id,
|
||||||
|
local: true
|
||||||
|
}
|
||||||
|
|> ActivityPub.accept()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{:following, {:error, _}, follower, followed} ->
|
||||||
|
Utils.update_follow_state_for_all(object, "reject")
|
||||||
|
FollowingRelationship.update(follower, followed, :follow_reject)
|
||||||
|
|
||||||
|
if followed.local do
|
||||||
|
%{
|
||||||
|
to: [follower.ap_id],
|
||||||
|
actor: followed,
|
||||||
|
object: follow_id,
|
||||||
|
local: true
|
||||||
|
}
|
||||||
|
|> ActivityPub.reject()
|
||||||
|
end
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, notifications} = Notification.create_notifications(object, do_send: false)
|
||||||
|
|
||||||
|
meta =
|
||||||
|
meta
|
||||||
|
|> add_notifications(notifications)
|
||||||
|
|
||||||
|
{:ok, object, meta}
|
||||||
|
end
|
||||||
|
|
||||||
# Tasks this handles:
|
# Tasks this handles:
|
||||||
# - Unfollow and block
|
# - Unfollow and block
|
||||||
def handle(
|
def handle(
|
||||||
|
|
|
@ -529,66 +529,6 @@ def handle_incoming(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_incoming(
|
|
||||||
%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data,
|
|
||||||
_options
|
|
||||||
) do
|
|
||||||
with %User{local: true} = followed <-
|
|
||||||
User.get_cached_by_ap_id(Containment.get_actor(%{"actor" => followed})),
|
|
||||||
{:ok, %User{} = follower} <-
|
|
||||||
User.get_or_fetch_by_ap_id(Containment.get_actor(%{"actor" => follower})),
|
|
||||||
{:ok, activity} <-
|
|
||||||
ActivityPub.follow(follower, followed, id, false, skip_notify_and_stream: true) do
|
|
||||||
with deny_follow_blocked <- Pleroma.Config.get([:user, :deny_follow_blocked]),
|
|
||||||
{_, false} <- {:user_blocked, User.blocks?(followed, follower) && deny_follow_blocked},
|
|
||||||
{_, false} <- {:user_locked, User.locked?(followed)},
|
|
||||||
{_, {:ok, follower}} <- {:follow, User.follow(follower, followed)},
|
|
||||||
{_, {:ok, _}} <-
|
|
||||||
{:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")},
|
|
||||||
{:ok, _relationship} <-
|
|
||||||
FollowingRelationship.update(follower, followed, :follow_accept) do
|
|
||||||
ActivityPub.accept(%{
|
|
||||||
to: [follower.ap_id],
|
|
||||||
actor: followed,
|
|
||||||
object: data,
|
|
||||||
local: true
|
|
||||||
})
|
|
||||||
else
|
|
||||||
{:user_blocked, true} ->
|
|
||||||
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
|
|
||||||
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
|
|
||||||
|
|
||||||
ActivityPub.reject(%{
|
|
||||||
to: [follower.ap_id],
|
|
||||||
actor: followed,
|
|
||||||
object: data,
|
|
||||||
local: true
|
|
||||||
})
|
|
||||||
|
|
||||||
{:follow, {:error, _}} ->
|
|
||||||
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
|
|
||||||
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
|
|
||||||
|
|
||||||
ActivityPub.reject(%{
|
|
||||||
to: [follower.ap_id],
|
|
||||||
actor: followed,
|
|
||||||
object: data,
|
|
||||||
local: true
|
|
||||||
})
|
|
||||||
|
|
||||||
{:user_locked, true} ->
|
|
||||||
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_pending)
|
|
||||||
:noop
|
|
||||||
end
|
|
||||||
|
|
||||||
ActivityPub.notify_and_stream(activity)
|
|
||||||
{:ok, activity}
|
|
||||||
else
|
|
||||||
_e ->
|
|
||||||
:error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_incoming(
|
def handle_incoming(
|
||||||
%{"type" => "Accept", "object" => follow_object, "actor" => _actor, "id" => id} = data,
|
%{"type" => "Accept", "object" => follow_object, "actor" => _actor, "id" => id} = data,
|
||||||
_options
|
_options
|
||||||
|
@ -696,7 +636,7 @@ def handle_incoming(
|
||||||
%{"type" => type} = data,
|
%{"type" => type} = data,
|
||||||
_options
|
_options
|
||||||
)
|
)
|
||||||
when type in ~w{Update Block} do
|
when type in ~w{Update Block Follow} do
|
||||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
|
|
@ -160,7 +160,7 @@ test "it rejects incoming follow requests if the following errors for some reaso
|
||||||
|> Poison.decode!()
|
|> Poison.decode!()
|
||||||
|> Map.put("object", user.ap_id)
|
|> Map.put("object", user.ap_id)
|
||||||
|
|
||||||
with_mock Pleroma.User, [:passthrough], follow: fn _, _ -> {:error, :testing} end do
|
with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
|
||||||
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
|
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
|
||||||
|
|
||||||
%Activity{} = activity = Activity.get_by_ap_id(id)
|
%Activity{} = activity = Activity.get_by_ap_id(id)
|
||||||
|
|
Loading…
Reference in a new issue