Przeglądaj źródła

ObjectValidators.{Announce,EmojiReact,Like}: Fix context, actor & addressing

elixir-1.11-ci
Haelwenn (lanodan) Monnier 2 lat temu
rodzic
commit
c839078a75
Nie znaleziono w bazie danych klucza dla tego podpisu ID klucza GPG: D5B7A8E43C997DEE
8 zmienionych plików z 105 dodań i 105 usunięć
  1. +21
    -6
      lib/pleroma/web/activity_pub/object_validators/announce_validator.ex
  2. +19
    -1
      lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
  3. +16
    -15
      lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex
  4. +17
    -33
      lib/pleroma/web/activity_pub/object_validators/like_validator.ex
  5. +12
    -10
      test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
  6. +19
    -16
      test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
  7. +1
    -1
      test/pleroma/web/activity_pub/relay_test.exs
  8. +0
    -23
      test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs

+ 21
- 6
lib/pleroma/web/activity_pub/object_validators/announce_validator.ex Wyświetl plik

@@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility

@@ -23,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
field(:type, :string)
field(:object, ObjectValidators.ObjectID)
field(:actor, ObjectValidators.ObjectID)
field(:context, :string, autogenerate: {Utils, :generate_context_id, []})
field(:context, :string)
field(:to, ObjectValidators.Recipients, default: [])
field(:cc, ObjectValidators.Recipients, default: [])
field(:published, ObjectValidators.DateTime)
@@ -36,6 +37,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
end

def cast_data(data) do
data =
data
|> fix()

%__MODULE__{}
|> changeset(data)
end
@@ -43,11 +48,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
def changeset(struct, data) do
struct
|> cast(data, __schema__(:fields))
|> fix_after_cast()
end

def fix_after_cast(cng) do
cng
defp fix(data) do
data =
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_activity_addressing()

with %Object{} = object <- Object.normalize(data["object"]) do
data
|> CommonFixes.fix_activity_context(object)
|> CommonFixes.fix_object_action_recipients(object)
else
_ -> data
end
end

defp validate_data(data_cng) do
@@ -60,7 +75,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
|> validate_announcable()
end

def validate_announcable(cng) do
defp validate_announcable(cng) do
with actor when is_binary(actor) <- get_field(cng, :actor),
object when is_binary(object) <- get_field(cng, :object),
%User{} = actor <- User.get_cached_by_ap_id(actor),
@@ -91,7 +106,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
end
end

def validate_existing_announce(cng) do
defp validate_existing_announce(cng) do
actor = get_field(cng, :actor)
object = get_field(cng, :object)



+ 19
- 1
lib/pleroma/web/activity_pub/object_validators/common_fixes.ex Wyświetl plik

@@ -4,6 +4,7 @@

defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object
alias Pleroma.Object.Containment
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
@@ -36,7 +37,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
|> Transmogrifier.fix_implicit_addressing(follower_collection)
end

def fix_activity_addressing(activity, _meta) do
def fix_activity_addressing(activity) do
%User{follower_address: follower_collection} = User.get_cached_by_ap_id(activity["actor"])

activity
@@ -57,4 +58,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
|> Map.put("actor", actor)
|> Map.put("attributedTo", actor)
end

def fix_activity_context(data, %Object{data: %{"context" => object_context}}) do
data
|> Map.put("context", object_context)
end

def fix_object_action_recipients(%{"actor" => actor} = data, %Object{data: %{"actor" => actor}}) do
to = ((data["to"] || []) -- [actor]) |> Enum.uniq()

Map.put(data, "to", to)
end

def fix_object_action_recipients(data, %Object{data: %{"actor" => actor}}) do
to = ((data["to"] || []) ++ [actor]) |> Enum.uniq()

Map.put(data, "to", to)
end
end

+ 16
- 15
lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex Wyświetl plik

@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do

alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes

import Ecto.Changeset
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
@@ -31,6 +32,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
end

def cast_data(data) do
data =
data
|> fix()

%__MODULE__{}
|> changeset(data)
end
@@ -38,28 +43,24 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
def changeset(struct, data) do
struct
|> cast(data, __schema__(:fields))
|> fix_after_cast()
end

def fix_after_cast(cng) do
cng
|> fix_context()
end

def fix_context(cng) do
object = get_field(cng, :object)
defp fix(data) do
data =
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_activity_addressing()

with nil <- get_field(cng, :context),
%Object{data: %{"context" => context}} <- Object.get_cached_by_ap_id(object) do
cng
|> put_change(:context, context)
with %Object{} = object <- Object.normalize(data["object"]) do
data
|> CommonFixes.fix_activity_context(object)
|> CommonFixes.fix_object_action_recipients(object)
else
_ ->
cng
_ -> data
end
end

def validate_emoji(cng) do
defp validate_emoji(cng) do
content = get_field(cng, :content)

if Pleroma.Emoji.is_unicode_emoji?(content) do


+ 17
- 33
lib/pleroma/web/activity_pub/object_validators/like_validator.ex Wyświetl plik

@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do

alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.Utils

import Ecto.Changeset
@@ -31,6 +32,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
end

def cast_data(data) do
data =
data
|> fix()

%__MODULE__{}
|> changeset(data)
end
@@ -38,41 +43,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
def changeset(struct, data) do
struct
|> cast(data, __schema__(:fields))
|> fix_after_cast()
end

def fix_after_cast(cng) do
cng
|> fix_recipients()
|> fix_context()
end

def fix_context(cng) do
object = get_field(cng, :object)

with nil <- get_field(cng, :context),
%Object{data: %{"context" => context}} <- Object.get_cached_by_ap_id(object) do
cng
|> put_change(:context, context)
else
_ ->
cng
end
end

def fix_recipients(cng) do
to = get_field(cng, :to)
cc = get_field(cng, :cc)
object = get_field(cng, :object)
defp fix(data) do
data =
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_activity_addressing()

with {[], []} <- {to, cc},
%Object{data: %{"actor" => actor}} <- Object.get_cached_by_ap_id(object),
{:ok, actor} <- ObjectValidators.ObjectID.cast(actor) do
cng
|> put_change(:to, [actor])
with %Object{} = object <- Object.normalize(data["object"]) do
data
|> CommonFixes.fix_activity_context(object)
|> CommonFixes.fix_object_action_recipients(object)
else
_ ->
cng
_ -> data
end
end

@@ -85,7 +69,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
|> validate_existing_like()
end

def validate_existing_like(%{changes: %{actor: actor, object: object}} = cng) do
defp validate_existing_like(%{changes: %{actor: actor, object: object}} = cng) do
if Utils.get_existing_like(actor, %{data: %{"id" => object}}) do
cng
|> add_error(:actor, "already liked this object")
@@ -95,5 +79,5 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
end
end

def validate_existing_like(cng), do: cng
defp validate_existing_like(cng), do: cng
end

+ 12
- 10
test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs Wyświetl plik

@@ -33,6 +33,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do
assert {:ok, _object, _meta} = ObjectValidator.validate(valid_announce, [])
end

test "keeps announced object context", %{valid_announce: valid_announce} do
assert %Object{data: %{"context" => object_context}} =
Object.get_cached_by_ap_id(valid_announce["object"])

{:ok, %{"context" => context}, _} =
valid_announce
|> Map.put("context", "https://example.org/invalid_context_id")
|> ObjectValidator.validate([])

assert context == object_context
end

test "returns an error if the object can't be found", %{valid_announce: valid_announce} do
without_object =
valid_announce
@@ -51,16 +63,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do
assert {:object, {"can't find object", []}} in cng.errors
end

test "returns an error if we don't have the actor", %{valid_announce: valid_announce} do
nonexisting_actor =
valid_announce
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")

{:error, cng} = ObjectValidator.validate(nonexisting_actor, [])

assert {:actor, {"can't find user", []}} in cng.errors
end

test "returns an error if the actor already announced the object", %{
valid_announce: valid_announce,
announcer: announcer,


+ 19
- 16
test/pleroma/web/activity_pub/object_validators/like_validation_test.exs Wyświetl plik

@@ -40,17 +40,30 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
assert LikeValidator.cast_and_validate(valid_like).valid?
end

test "sets the 'to' field to the object actor if no recipients are given", %{
test "Add object actor from 'to' field if it doesn't owns the like", %{valid_like: valid_like} do
user = insert(:user)

object_actor = valid_like["actor"]

valid_like =
valid_like
|> Map.put("actor", user.ap_id)
|> Map.put("to", [])

{:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
assert object_actor in object["to"]
end

test "Removes object actor from 'to' field if it owns the like", %{
valid_like: valid_like,
user: user
} do
without_recipients =
valid_like =
valid_like
|> Map.delete("to")
|> Map.put("to", [user.ap_id])

{:ok, object, _meta} = ObjectValidator.validate(without_recipients, [])

assert object["to"] == [user.ap_id]
{:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
refute user.ap_id in object["to"]
end

test "sets the context field to the context of the object if no context is given", %{
@@ -66,16 +79,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
assert object["context"] == post_activity.data["context"]
end

test "it errors when the actor is missing or not known", %{valid_like: valid_like} do
without_actor = Map.delete(valid_like, "actor")

refute LikeValidator.cast_and_validate(without_actor).valid?

with_invalid_actor = Map.put(valid_like, "actor", "invalidactor")

refute LikeValidator.cast_and_validate(with_invalid_actor).valid?
end

test "it errors when the object is missing or not known", %{valid_like: valid_like} do
without_object = Map.delete(valid_like, "object")



+ 1
- 1
test/pleroma/web/activity_pub/relay_test.exs Wyświetl plik

@@ -148,7 +148,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
assert {:ok, %Activity{} = activity} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["to"] == [service_actor.follower_address]
assert service_actor.follower_address in activity.data["to"]
assert called(Pleroma.Web.Federator.publish(activity))
end



+ 0
- 23
test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs Wyświetl plik

@@ -150,27 +150,4 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do

assert {:error, _e} = Transmogrifier.handle_incoming(data)
end

test "it does not clobber the addressing on announce activities" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})

data =
File.read!("test/fixtures/mastodon-announce.json")
|> Jason.decode!()
|> Map.put("object", Object.normalize(activity, fetch: false).data["id"])
|> Map.put("to", ["http://mastodon.example.org/users/admin/followers"])
|> Map.put("cc", [])

_user =
insert(:user,
local: false,
ap_id: data["actor"],
follower_address: "http://mastodon.example.org/users/admin/followers"
)

{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)

assert data["to"] == ["http://mastodon.example.org/users/admin/followers"]
end
end

Ładowanie…
Anuluj
Zapisz