Merge branch 'develop' into feld-2168-media-preview-proxy
This commit is contained in:
commit
479578b148
54 changed files with 1095 additions and 254 deletions
|
|
@ -85,7 +85,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp increase_replies_count_if_reply(_create_data), do: :noop
|
||||
|
||||
@object_types ["ChatMessage", "Question", "Answer"]
|
||||
@object_types ~w[ChatMessage Question Answer Audio Event]
|
||||
@spec persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
|
||||
def persist(%{"type" => type} = object, meta) when type in @object_types do
|
||||
with {:ok, object} <- Object.create(object) do
|
||||
|
|
@ -1344,9 +1344,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
|
||||
def maybe_handle_clashing_nickname(data) do
|
||||
nickname = data[:nickname]
|
||||
|
||||
with %User{} = old_user <- User.get_by_nickname(nickname),
|
||||
with nickname when is_binary(nickname) <- data[:nickname],
|
||||
%User{} = old_user <- User.get_by_nickname(nickname),
|
||||
{_, false} <- {:ap_id_comparison, data[:ap_id] == old_user.ap_id} do
|
||||
Logger.info(
|
||||
"Found an old user for #{nickname}, the old ap id is #{old_user.ap_id}, new one is #{
|
||||
|
|
@ -1360,7 +1359,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
else
|
||||
{:ap_id_comparison, true} ->
|
||||
Logger.info(
|
||||
"Found an old user for #{nickname}, but the ap id #{data[:ap_id]} is the same as the new user. Race condition? Not changing anything."
|
||||
"Found an old user for #{data[:nickname]}, but the ap id #{data[:ap_id]} is the same as the new user. Race condition? Not changing anything."
|
||||
)
|
||||
|
||||
_ ->
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
|
||||
to =
|
||||
cond do
|
||||
actor.ap_id == Relay.relay_ap_id() ->
|
||||
actor.ap_id == Relay.ap_id() ->
|
||||
[actor.follower_address]
|
||||
|
||||
public? ->
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.EventValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator
|
||||
|
|
@ -43,6 +44,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Event"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|> EventValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert) do
|
||||
object = stringify_keys(object)
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Follow"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|
|
@ -187,7 +198,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,
|
||||
meta
|
||||
)
|
||||
when objtype in ~w[Question Answer Audio] do
|
||||
when objtype in ~w[Question Answer Audio Event] do
|
||||
with {:ok, object_data} <- cast_and_apply(object),
|
||||
meta = Keyword.put(meta, :object_data, object_data |> stringify_keys),
|
||||
{:ok, create_activity} <-
|
||||
|
|
@ -225,6 +236,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
AudioValidator.cast_and_apply(object)
|
||||
end
|
||||
|
||||
def cast_and_apply(%{"type" => "Event"} = object) do
|
||||
EventValidator.cast_and_apply(object)
|
||||
end
|
||||
|
||||
def cast_and_apply(o), do: {:error, {:validator_not_set, o}}
|
||||
|
||||
# is_struct/1 isn't present in Elixir 1.8.x
|
||||
|
|
|
|||
|
|
@ -41,34 +41,34 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
|
|||
end
|
||||
|
||||
def fix_media_type(data) do
|
||||
data =
|
||||
data
|
||||
|> Map.put_new("mediaType", data["mimeType"])
|
||||
data = Map.put_new(data, "mediaType", data["mimeType"])
|
||||
|
||||
if MIME.valid?(data["mediaType"]) do
|
||||
data
|
||||
else
|
||||
data
|
||||
|> Map.put("mediaType", "application/octet-stream")
|
||||
Map.put(data, "mediaType", "application/octet-stream")
|
||||
end
|
||||
end
|
||||
|
||||
def fix_url(data) do
|
||||
case data["url"] do
|
||||
url when is_binary(url) ->
|
||||
data
|
||||
|> Map.put(
|
||||
"url",
|
||||
[
|
||||
%{
|
||||
"href" => url,
|
||||
"type" => "Link",
|
||||
"mediaType" => data["mediaType"]
|
||||
}
|
||||
]
|
||||
)
|
||||
defp handle_href(href, mediaType) do
|
||||
[
|
||||
%{
|
||||
"href" => href,
|
||||
"type" => "Link",
|
||||
"mediaType" => mediaType
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
_ ->
|
||||
defp fix_url(data) do
|
||||
cond do
|
||||
is_binary(data["url"]) ->
|
||||
Map.put(data, "url", handle_href(data["url"], data["mediaType"]))
|
||||
|
||||
is_binary(data["href"]) and data["url"] == nil ->
|
||||
Map.put(data, "url", handle_href(data["href"], data["mediaType"]))
|
||||
|
||||
true ->
|
||||
data
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
|||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, :string)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
|
|
@ -66,10 +66,24 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
|||
|> changeset(data)
|
||||
end
|
||||
|
||||
defp fix_url(%{"url" => url} = data) when is_list(url) do
|
||||
attachment =
|
||||
Enum.find(url, fn x -> is_map(x) and String.starts_with?(x["mimeType"], "audio/") end)
|
||||
|
||||
link_element = Enum.find(url, fn x -> is_map(x) and x["mimeType"] == "text/html" end)
|
||||
|
||||
data
|
||||
|> Map.put("attachment", [attachment])
|
||||
|> Map.put("url", link_element["href"])
|
||||
end
|
||||
|
||||
defp fix_url(data), do: data
|
||||
|
||||
defp fix(data) do
|
||||
data
|
||||
|> CommonFixes.fix_defaults()
|
||||
|> CommonFixes.fix_attribution()
|
||||
|> fix_url()
|
||||
end
|
||||
|
||||
def changeset(struct, data) do
|
||||
|
|
@ -83,7 +97,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
|||
def validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Audio"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|
|
|
|||
|
|
@ -61,9 +61,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do
|
|||
end
|
||||
end
|
||||
|
||||
defp fix_addressing(data, meta) do
|
||||
if object = meta[:object_data] do
|
||||
data
|
||||
|> Map.put_new("to", object["to"] || [])
|
||||
|> Map.put_new("cc", object["cc"] || [])
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
defp fix(data, meta) do
|
||||
data
|
||||
|> fix_context(meta)
|
||||
|> fix_addressing(meta)
|
||||
end
|
||||
|
||||
def validate_data(cng, meta \\ []) do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key false
|
||||
@derive Jason.Encoder
|
||||
|
||||
# Extends from NoteValidator
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
# TODO: Write type
|
||||
field(:tag, {:array, :map}, default: [])
|
||||
field(:type, :string)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
field(:content, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
# TODO: Write type
|
||||
field(:emoji, :map, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:announcements, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
end
|
||||
|
||||
def cast_and_apply(data) do
|
||||
data
|
||||
|> cast_data
|
||||
|> apply_action(:insert)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
data
|
||||
|> cast_data()
|
||||
|> validate_data()
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
%__MODULE__{}
|
||||
|> changeset(data)
|
||||
end
|
||||
|
||||
defp fix(data) do
|
||||
data
|
||||
|> CommonFixes.fix_defaults()
|
||||
|> CommonFixes.fix_attribution()
|
||||
end
|
||||
|
||||
def changeset(struct, data) do
|
||||
data = fix(data)
|
||||
|
||||
struct
|
||||
|> cast(data, __schema__(:fields) -- [:attachment])
|
||||
|> cast_embed(:attachment)
|
||||
end
|
||||
|
||||
def validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Event"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|> CommonValidations.validate_host_match()
|
||||
end
|
||||
end
|
||||
|
|
@ -20,11 +20,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
|||
# TODO: Write type
|
||||
field(:tag, {:array, :map}, default: [])
|
||||
field(:type, :string)
|
||||
|
||||
field(:name, :string)
|
||||
field(:summary, :string)
|
||||
field(:content, :string)
|
||||
|
||||
field(:context, :string)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:summary, :string)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
# TODO: Write type
|
||||
field(:emoji, :map, default: %{})
|
||||
|
|
@ -35,13 +41,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
|||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, :string}, default: [])
|
||||
field(:announcements, {:array, :string}, default: [])
|
||||
|
||||
# see if needed
|
||||
field(:context_id, :string)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
field(:url, ObjectValidators.Uri)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,19 +10,13 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
require Logger
|
||||
|
||||
@relay_nickname "relay"
|
||||
@nickname "relay"
|
||||
|
||||
def get_actor do
|
||||
actor =
|
||||
relay_ap_id()
|
||||
|> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
|
||||
@spec ap_id() :: String.t()
|
||||
def ap_id, do: "#{Pleroma.Web.Endpoint.url()}/#{@nickname}"
|
||||
|
||||
actor
|
||||
end
|
||||
|
||||
def relay_ap_id do
|
||||
"#{Pleroma.Web.Endpoint.url()}/relay"
|
||||
end
|
||||
@spec get_actor() :: User.t() | nil
|
||||
def get_actor, do: User.get_or_create_service_actor_by_ap_id(ap_id(), @nickname)
|
||||
|
||||
@spec follow(String.t()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def follow(target_instance) do
|
||||
|
|
@ -61,34 +55,38 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
|||
|
||||
def publish(_), do: {:error, "Not implemented"}
|
||||
|
||||
@spec list(boolean()) :: {:ok, [String.t()]} | {:error, any()}
|
||||
def list(with_not_accepted \\ false) do
|
||||
@spec list() :: {:ok, [%{actor: String.t(), followed_back: boolean()}]} | {:error, any()}
|
||||
def list do
|
||||
with %User{} = user <- get_actor() do
|
||||
accepted =
|
||||
user
|
||||
|> User.following()
|
||||
|> Enum.map(fn entry -> URI.parse(entry).host end)
|
||||
|> following()
|
||||
|> Enum.map(fn actor -> %{actor: actor, followed_back: true} end)
|
||||
|
||||
without_accept =
|
||||
user
|
||||
|> Pleroma.Activity.following_requests_for_actor()
|
||||
|> Enum.map(fn activity -> %{actor: activity.data["object"], followed_back: false} end)
|
||||
|> Enum.uniq()
|
||||
|
||||
list =
|
||||
if with_not_accepted do
|
||||
without_accept =
|
||||
user
|
||||
|> Pleroma.Activity.following_requests_for_actor()
|
||||
|> Enum.map(fn a -> URI.parse(a.data["object"]).host <> " (no Accept received)" end)
|
||||
|> Enum.uniq()
|
||||
|
||||
accepted ++ without_accept
|
||||
else
|
||||
accepted
|
||||
end
|
||||
|
||||
{:ok, list}
|
||||
{:ok, accepted ++ without_accept}
|
||||
else
|
||||
error -> format_error(error)
|
||||
end
|
||||
end
|
||||
|
||||
@spec following() :: [String.t()]
|
||||
def following do
|
||||
get_actor()
|
||||
|> following()
|
||||
end
|
||||
|
||||
defp following(user) do
|
||||
user
|
||||
|> User.following_ap_ids()
|
||||
|> Enum.uniq()
|
||||
end
|
||||
|
||||
defp format_error({:error, error}), do: format_error(error)
|
||||
|
||||
defp format_error(error) do
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
end
|
||||
|
||||
def handle_object_creation(%{"type" => objtype} = object, meta)
|
||||
when objtype in ~w[Audio Question] do
|
||||
when objtype in ~w[Audio Question Event] do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -276,13 +276,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
Map.put(object, "url", url["href"])
|
||||
end
|
||||
|
||||
def fix_url(%{"type" => object_type, "url" => url} = object)
|
||||
when object_type in ["Video", "Audio"] and is_list(url) do
|
||||
def fix_url(%{"type" => "Video", "url" => url} = object) when is_list(url) do
|
||||
attachment =
|
||||
Enum.find(url, fn x ->
|
||||
media_type = x["mediaType"] || x["mimeType"] || ""
|
||||
|
||||
is_map(x) and String.starts_with?(media_type, ["audio/", "video/"])
|
||||
is_map(x) and String.starts_with?(media_type, "video/")
|
||||
end)
|
||||
|
||||
link_element =
|
||||
|
|
@ -461,7 +460,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
|
||||
options
|
||||
)
|
||||
when objtype in ~w{Article Event Note Video Page} do
|
||||
when objtype in ~w{Article Note Video Page} do
|
||||
actor = Containment.get_actor(data)
|
||||
|
||||
with nil <- Activity.get_create_by_object_ap_id(object["id"]),
|
||||
|
|
@ -555,7 +554,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype}} = data,
|
||||
_options
|
||||
)
|
||||
when objtype in ~w{Question Answer ChatMessage Audio} do
|
||||
when objtype in ~w{Question Answer ChatMessage Audio Event} do
|
||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue