ChatMessages: Better validation.

This commit is contained in:
lain 2020-04-16 15:21:47 +02:00
commit e2ced04917
8 changed files with 128 additions and 6 deletions

View file

@ -31,7 +31,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
def validate(%{"type" => "ChatMessage"} = object, meta) do
with {:ok, object} <-
object
|> ChatMessageValidator.cast_and_apply() do
|> ChatMessageValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert) do
object = stringify_keys(object)
{:ok, object, meta}
end
@ -40,7 +41,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
def validate(%{"type" => "Create"} = object, meta) do
with {:ok, object} <-
object
|> CreateChatMessageValidator.cast_and_apply() do
|> CreateChatMessageValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert) do
object = stringify_keys(object)
{:ok, object, meta}
end

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator do
use Ecto.Schema
alias Pleroma.Web.ActivityPub.ObjectValidators.Types
alias Pleroma.User
import Ecto.Changeset
@ -54,5 +55,30 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator do
data_cng
|> validate_inclusion(:type, ["ChatMessage"])
|> validate_required([:id, :actor, :to, :type, :content])
|> validate_length(:to, is: 1)
|> validate_local_concern()
end
@doc "Validates if at least one of the users in this ChatMessage is a local user, otherwise we don't want the message in our system. It also validates the presence of both users in our system."
def validate_local_concern(cng) do
with actor_ap <- get_field(cng, :actor),
{_, %User{} = actor} <- {:find_actor, User.get_cached_by_ap_id(actor_ap)},
{_, %User{} = recipient} <-
{:find_recipient, User.get_cached_by_ap_id(get_field(cng, :to) |> hd())},
{_, true} <- {:local?, Enum.any?([actor, recipient], & &1.local)} do
cng
else
{:local?, false} ->
cng
|> add_error(:actor, "actor and recipient are both remote")
{:find_actor, _} ->
cng
|> add_error(:actor, "can't find user")
{:find_recipient, _} ->
cng
|> add_error(:to, "can't find user")
end
end
end

View file

@ -8,7 +8,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
alias Pleroma.Object
alias Pleroma.User
def validate_actor_presence(cng, field_name \\ :actor) do
def validate_actor_presence(cng) do
validate_user_presence(cng, :actor)
end
def validate_user_presence(cng, field_name) do
cng
|> validate_change(field_name, fn field_name, actor ->
if User.get_cached_by_ap_id(actor) do

View file

@ -32,4 +32,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator do
def cast_data(data) do
cast(%__MODULE__{}, data, __schema__(:fields))
end
# No validation yet
def cast_and_validate(data) do
cast_data(data)
end
end

View file

@ -25,6 +25,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ChatMessageHandling do
{_, {:ok, activity, _meta}} <-
{:common_pipeline, Pipeline.common_pipeline(cast_data, local: false)} do
{:ok, activity}
else
e ->
{:error, e}
end
end
end