Merge branch 'develop' into feature/configurable-blocks
This commit is contained in:
commit
2e294ee44a
51 changed files with 1066 additions and 167 deletions
|
|
@ -57,6 +57,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
if activity.data["type"] in ["Create", "Announce"] do
|
||||
Pleroma.Web.Streamer.stream("user", activity)
|
||||
Pleroma.Web.Streamer.stream("list", activity)
|
||||
|
||||
if Enum.member?(activity.data["to"], public) do
|
||||
Pleroma.Web.Streamer.stream("public", activity)
|
||||
|
|
@ -198,7 +199,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
:ok <- maybe_federate(unannounce_activity),
|
||||
{:ok, _activity} <- Repo.delete(announce_activity),
|
||||
{:ok, object} <- remove_announce_from_object(announce_activity, object) do
|
||||
{:ok, unannounce_activity, announce_activity, object}
|
||||
{:ok, unannounce_activity, object}
|
||||
else
|
||||
_e -> {:ok, object}
|
||||
end
|
||||
|
|
@ -214,6 +215,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
|
||||
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
|
||||
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
|
||||
{:ok, activity} <- insert(unfollow_data, local),
|
||||
:ok <- maybe_federate(activity) do
|
||||
|
|
@ -449,11 +451,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
|
||||
blocks = info["blocks"] || []
|
||||
domain_blocks = info["domain_blocks"] || []
|
||||
|
||||
from(
|
||||
activity in query,
|
||||
where: fragment("not (? = ANY(?))", activity.actor, ^blocks),
|
||||
where: fragment("not (?->'to' \\?| ?)", activity.data, ^blocks)
|
||||
where: fragment("not (?->'to' \\?| ?)", activity.data, ^blocks),
|
||||
where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks)
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -502,7 +506,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
|
||||
def upload(file) do
|
||||
data = Upload.store(file)
|
||||
data = Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media])
|
||||
Repo.insert(%Object{data: data})
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
|
|||
alias Pleroma.User
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
@mrf_rejectnonpublic Application.get_env(:pleroma, :mrf_rejectnonpublic)
|
||||
@allow_followersonly Keyword.get(@mrf_rejectnonpublic, :allow_followersonly)
|
||||
@allow_direct Keyword.get(@mrf_rejectnonpublic, :allow_direct)
|
||||
|
||||
@impl true
|
||||
def filter(object) do
|
||||
if object["type"] == "Create" do
|
||||
|
|
@ -18,9 +22,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do
|
|||
end
|
||||
|
||||
case visibility do
|
||||
"public" -> {:ok, object}
|
||||
"unlisted" -> {:ok, object}
|
||||
_ -> {:reject, nil}
|
||||
"public" ->
|
||||
{:ok, object}
|
||||
|
||||
"unlisted" ->
|
||||
{:ok, object}
|
||||
|
||||
"followers" ->
|
||||
with true <- @allow_followersonly do
|
||||
{:ok, object}
|
||||
else
|
||||
_e -> {:reject, nil}
|
||||
end
|
||||
|
||||
"direct" ->
|
||||
with true <- @allow_direct do
|
||||
{:ok, object}
|
||||
else
|
||||
_e -> {:reject, nil}
|
||||
end
|
||||
end
|
||||
else
|
||||
{:ok, object}
|
||||
|
|
|
|||
|
|
@ -30,14 +30,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
when not is_nil(in_reply_to_id) do
|
||||
case ActivityPub.fetch_object_from_id(in_reply_to_id) do
|
||||
{:ok, replied_object} ->
|
||||
activity = Activity.get_create_activity_by_object_ap_id(replied_object.data["id"])
|
||||
|
||||
object
|
||||
|> Map.put("inReplyTo", replied_object.data["id"])
|
||||
|> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id)
|
||||
|> Map.put("inReplyToStatusId", activity.id)
|
||||
|> Map.put("conversation", replied_object.data["context"] || object["conversation"])
|
||||
|> Map.put("context", replied_object.data["context"] || object["conversation"])
|
||||
with %Activity{} = activity <-
|
||||
Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) do
|
||||
object
|
||||
|> Map.put("inReplyTo", replied_object.data["id"])
|
||||
|> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id)
|
||||
|> Map.put("inReplyToStatusId", activity.id)
|
||||
|> Map.put("conversation", replied_object.data["context"] || object["conversation"])
|
||||
|> Map.put("context", replied_object.data["context"] || object["conversation"])
|
||||
else
|
||||
e ->
|
||||
Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}")
|
||||
object
|
||||
end
|
||||
|
||||
e ->
|
||||
Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}")
|
||||
|
|
@ -137,9 +142,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
with %User{local: true} = followed <- User.get_cached_by_ap_id(followed),
|
||||
%User{} = follower <- User.get_or_fetch_by_ap_id(follower),
|
||||
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
|
||||
ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true})
|
||||
if not User.locked?(followed) do
|
||||
ActivityPub.accept(%{
|
||||
to: [follower.ap_id],
|
||||
actor: followed.ap_id,
|
||||
object: data,
|
||||
local: true
|
||||
})
|
||||
|
||||
User.follow(follower, followed)
|
||||
end
|
||||
|
||||
User.follow(follower, followed)
|
||||
{:ok, activity}
|
||||
else
|
||||
_e -> :error
|
||||
|
|
@ -252,7 +265,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
{:ok, new_user_data} = ActivityPub.user_data_from_user_object(object)
|
||||
|
||||
banner = new_user_data[:info]["banner"]
|
||||
locked = new_user_data[:info]["locked"]
|
||||
locked = new_user_data[:info]["locked"] || false
|
||||
|
||||
update_data =
|
||||
new_user_data
|
||||
|
|
@ -304,7 +317,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
with %User{} = actor <- User.get_or_fetch_by_ap_id(actor),
|
||||
{:ok, object} <-
|
||||
get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id),
|
||||
{:ok, activity, _, _} <- ActivityPub.unannounce(actor, object, id, false) do
|
||||
{:ok, activity, _} <- ActivityPub.unannounce(actor, object, id, false) do
|
||||
{:ok, activity}
|
||||
else
|
||||
_e -> :error
|
||||
|
|
@ -432,6 +445,58 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
{:ok, data}
|
||||
end
|
||||
|
||||
# Mastodon Accept/Reject requires a non-normalized object containing the actor URIs,
|
||||
# because of course it does.
|
||||
def prepare_outgoing(%{"type" => "Accept"} = data) do
|
||||
follow_activity_id =
|
||||
if is_binary(data["object"]) do
|
||||
data["object"]
|
||||
else
|
||||
data["object"]["id"]
|
||||
end
|
||||
|
||||
with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
|
||||
object = %{
|
||||
"actor" => follow_activity.actor,
|
||||
"object" => follow_activity.data["object"],
|
||||
"id" => follow_activity.data["id"],
|
||||
"type" => "Follow"
|
||||
}
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|> Map.put("@context", "https://www.w3.org/ns/activitystreams")
|
||||
|
||||
{:ok, data}
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_outgoing(%{"type" => "Reject"} = data) do
|
||||
follow_activity_id =
|
||||
if is_binary(data["object"]) do
|
||||
data["object"]
|
||||
else
|
||||
data["object"]["id"]
|
||||
end
|
||||
|
||||
with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do
|
||||
object = %{
|
||||
"actor" => follow_activity.actor,
|
||||
"object" => follow_activity.data["object"],
|
||||
"id" => follow_activity.data["id"],
|
||||
"type" => "Follow"
|
||||
}
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|> Map.put("@context", "https://www.w3.org/ns/activitystreams")
|
||||
|
||||
{:ok, data}
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_outgoing(%{"type" => _type} = data) do
|
||||
data =
|
||||
data
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
alias Pleroma.Web.Endpoint
|
||||
alias Ecto.{Changeset, UUID}
|
||||
import Ecto.Query
|
||||
require Logger
|
||||
|
||||
# Some implementations send the actor URI as the actor field, others send the entire actor object,
|
||||
# so figure out what the actor's URI is based on what we have.
|
||||
|
|
@ -216,10 +217,27 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
|
||||
#### Follow-related helpers
|
||||
|
||||
@doc """
|
||||
Updates a follow activity's state (for locked accounts).
|
||||
"""
|
||||
def update_follow_state(%Activity{} = activity, state) do
|
||||
with new_data <-
|
||||
activity.data
|
||||
|> Map.put("state", state),
|
||||
changeset <- Changeset.change(activity, data: new_data),
|
||||
{:ok, activity} <- Repo.update(changeset) do
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Makes a follow activity data for the given follower and followed
|
||||
"""
|
||||
def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id}, activity_id) do
|
||||
def make_follow_data(
|
||||
%User{ap_id: follower_id},
|
||||
%User{ap_id: followed_id} = followed,
|
||||
activity_id
|
||||
) do
|
||||
data = %{
|
||||
"type" => "Follow",
|
||||
"actor" => follower_id,
|
||||
|
|
@ -228,7 +246,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
"object" => followed_id
|
||||
}
|
||||
|
||||
if activity_id, do: Map.put(data, "id", activity_id), else: data
|
||||
data = if activity_id, do: Map.put(data, "id", activity_id), else: data
|
||||
data = if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue