Merge branch 'feature/dm-sanity' into 'develop'
DM sanitization See merge request pleroma/pleroma!458
This commit is contained in:
commit
69454c8345
8 changed files with 186 additions and 4 deletions
|
@ -802,11 +802,23 @@ def fetch_and_contain_remote_object_from_id(id) do
|
||||||
def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false
|
def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false
|
||||||
def is_public?(%Object{data: data}), do: is_public?(data)
|
def is_public?(%Object{data: data}), do: is_public?(data)
|
||||||
def is_public?(%Activity{data: data}), do: is_public?(data)
|
def is_public?(%Activity{data: data}), do: is_public?(data)
|
||||||
|
def is_public?(%{"directMessage" => true}), do: false
|
||||||
|
|
||||||
def is_public?(data) do
|
def is_public?(data) do
|
||||||
"https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || []))
|
"https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || []))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_private?(activity) do
|
||||||
|
!is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true
|
||||||
|
def is_direct?(%Object{data: %{"directMessage" => true}}), do: true
|
||||||
|
|
||||||
|
def is_direct?(activity) do
|
||||||
|
!is_public?(activity) && !is_private?(activity)
|
||||||
|
end
|
||||||
|
|
||||||
def visible_for_user?(activity, nil) do
|
def visible_for_user?(activity, nil) do
|
||||||
is_public?(activity)
|
is_public?(activity)
|
||||||
end
|
end
|
||||||
|
|
|
@ -93,12 +93,47 @@ def fix_addressing_list(map, field) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_addressing(map) do
|
def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, explicit_mentions) do
|
||||||
map
|
explicit_to =
|
||||||
|
to
|
||||||
|
|> Enum.filter(fn x -> x in explicit_mentions end)
|
||||||
|
|
||||||
|
explicit_cc =
|
||||||
|
to
|
||||||
|
|> Enum.filter(fn x -> x not in explicit_mentions end)
|
||||||
|
|
||||||
|
final_cc =
|
||||||
|
(cc ++ explicit_cc)
|
||||||
|
|> Enum.uniq()
|
||||||
|
|
||||||
|
object
|
||||||
|
|> Map.put("to", explicit_to)
|
||||||
|
|> Map.put("cc", final_cc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_explicit_addressing(object, _explicit_mentions), do: object
|
||||||
|
|
||||||
|
# if directMessage flag is set to true, leave the addressing alone
|
||||||
|
def fix_explicit_addressing(%{"directMessage" => true} = object), do: object
|
||||||
|
|
||||||
|
def fix_explicit_addressing(object) do
|
||||||
|
explicit_mentions =
|
||||||
|
object
|
||||||
|
|> Utils.determine_explicit_mentions()
|
||||||
|
|
||||||
|
explicit_mentions = explicit_mentions ++ ["https://www.w3.org/ns/activitystreams#Public"]
|
||||||
|
|
||||||
|
object
|
||||||
|
|> fix_explicit_addressing(explicit_mentions)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_addressing(object) do
|
||||||
|
object
|
||||||
|> fix_addressing_list("to")
|
|> fix_addressing_list("to")
|
||||||
|> fix_addressing_list("cc")
|
|> fix_addressing_list("cc")
|
||||||
|> fix_addressing_list("bto")
|
|> fix_addressing_list("bto")
|
||||||
|> fix_addressing_list("bcc")
|
|> fix_addressing_list("bcc")
|
||||||
|
|> fix_explicit_addressing
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_actor(%{"attributedTo" => actor} = object) do
|
def fix_actor(%{"attributedTo" => actor} = object) do
|
||||||
|
@ -348,6 +383,7 @@ def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = obj
|
||||||
additional:
|
additional:
|
||||||
Map.take(data, [
|
Map.take(data, [
|
||||||
"cc",
|
"cc",
|
||||||
|
"directMessage",
|
||||||
"id"
|
"id"
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,20 @@ def normalize_params(params) do
|
||||||
Map.put(params, "actor", get_ap_id(params["actor"]))
|
Map.put(params, "actor", get_ap_id(params["actor"]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do
|
||||||
|
tag
|
||||||
|
|> Enum.filter(fn x -> is_map(x) end)
|
||||||
|
|> Enum.filter(fn x -> x["type"] == "Mention" end)
|
||||||
|
|> Enum.map(fn x -> x["href"] end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do
|
||||||
|
Map.put(object, "tag", [tag])
|
||||||
|
|> determine_explicit_mentions()
|
||||||
|
end
|
||||||
|
|
||||||
|
def determine_explicit_mentions(_), do: []
|
||||||
|
|
||||||
defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
|
defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
|
||||||
defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
|
defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
|
||||||
defp recipient_in_collection(_, _), do: false
|
defp recipient_in_collection(_, _), do: false
|
||||||
|
|
|
@ -143,7 +143,7 @@ def post(user, %{"status" => status} = data) do
|
||||||
actor: user,
|
actor: user,
|
||||||
context: context,
|
context: context,
|
||||||
object: object,
|
object: object,
|
||||||
additional: %{"cc" => cc}
|
additional: %{"cc" => cc, "directMessage" => visibility == "direct"}
|
||||||
})
|
})
|
||||||
|
|
||||||
res
|
res
|
||||||
|
|
|
@ -231,6 +231,9 @@ def get_visibility(object) do
|
||||||
Enum.any?(to, &String.contains?(&1, "/followers")) ->
|
Enum.any?(to, &String.contains?(&1, "/followers")) ->
|
||||||
"private"
|
"private"
|
||||||
|
|
||||||
|
length(cc) > 0 ->
|
||||||
|
"private"
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
"direct"
|
"direct"
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
"toot": "http://joinmastodon.org/ns#",
|
"toot": "http://joinmastodon.org/ns#",
|
||||||
"totalItems": "as:totalItems",
|
"totalItems": "as:totalItems",
|
||||||
"value": "schema:value",
|
"value": "schema:value",
|
||||||
"sensitive": "as:sensitive"
|
"sensitive": "as:sensitive",
|
||||||
|
"litepub": "http://litepub.social/ns#",
|
||||||
|
"directMessage": "litepub:directMessage"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,36 @@ test "it works for incoming notices with url not being a string (prismo)" do
|
||||||
assert data["object"]["url"] == "https://prismo.news/posts/83"
|
assert data["object"]["url"] == "https://prismo.news/posts/83"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it cleans up incoming notices which are not really DMs" do
|
||||||
|
user = insert(:user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
to = [user.ap_id, other_user.ap_id]
|
||||||
|
|
||||||
|
data =
|
||||||
|
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||||
|
|> Poison.decode!()
|
||||||
|
|> Map.put("to", to)
|
||||||
|
|> Map.put("cc", [])
|
||||||
|
|
||||||
|
object =
|
||||||
|
data["object"]
|
||||||
|
|> Map.put("to", to)
|
||||||
|
|> Map.put("cc", [])
|
||||||
|
|
||||||
|
data = Map.put(data, "object", object)
|
||||||
|
|
||||||
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||||
|
|
||||||
|
assert data["to"] == []
|
||||||
|
assert data["cc"] == to
|
||||||
|
|
||||||
|
object = data["object"]
|
||||||
|
|
||||||
|
assert object["to"] == []
|
||||||
|
assert object["cc"] == to
|
||||||
|
end
|
||||||
|
|
||||||
test "it works for incoming follow requests" do
|
test "it works for incoming follow requests" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
|
@ -872,6 +902,34 @@ test "it adds like collection to object" do
|
||||||
assert modified["object"]["likes"]["type"] == "OrderedCollection"
|
assert modified["object"]["likes"]["type"] == "OrderedCollection"
|
||||||
assert modified["object"]["likes"]["totalItems"] == 0
|
assert modified["object"]["likes"]["totalItems"] == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "the directMessage flag is present" do
|
||||||
|
user = insert(:user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "2hu :moominmamma:"})
|
||||||
|
|
||||||
|
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||||
|
|
||||||
|
assert modified["directMessage"] == false
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(user, %{"status" => "@{other_user.nickname} :moominmamma:"})
|
||||||
|
|
||||||
|
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||||
|
|
||||||
|
assert modified["directMessage"] == false
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(user, %{
|
||||||
|
"status" => "@{other_user.nickname} :moominmamma:",
|
||||||
|
"visibility" => "direct"
|
||||||
|
})
|
||||||
|
|
||||||
|
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||||
|
|
||||||
|
assert modified["directMessage"] == true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "user upgrade" do
|
describe "user upgrade" do
|
||||||
|
|
57
test/web/activity_pub/utils_test.exs
Normal file
57
test/web/activity_pub/utils_test.exs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
||||||
|
describe "determine_explicit_mentions()" do
|
||||||
|
test "works with an object that has mentions" do
|
||||||
|
object = %{
|
||||||
|
"tag" => [
|
||||||
|
%{
|
||||||
|
"type" => "Mention",
|
||||||
|
"href" => "https://example.com/~alyssa",
|
||||||
|
"name" => "Alyssa P. Hacker"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "works with an object that does not have mentions" do
|
||||||
|
object = %{
|
||||||
|
"tag" => [
|
||||||
|
%{"type" => "Hashtag", "href" => "https://example.com/tag/2hu", "name" => "2hu"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "works with an object that has mentions and other tags" do
|
||||||
|
object = %{
|
||||||
|
"tag" => [
|
||||||
|
%{
|
||||||
|
"type" => "Mention",
|
||||||
|
"href" => "https://example.com/~alyssa",
|
||||||
|
"name" => "Alyssa P. Hacker"
|
||||||
|
},
|
||||||
|
%{"type" => "Hashtag", "href" => "https://example.com/tag/2hu", "name" => "2hu"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "works with an object that has no tags" do
|
||||||
|
object = %{}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "works with an object that has only IR tags" do
|
||||||
|
object = %{"tag" => ["2hu"]}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue