implement invisible support for remote users

This commit is contained in:
Ariadne Conill 2019-10-05 20:41:33 +00:00
parent 95871cb462
commit ef659331b0
7 changed files with 95 additions and 7 deletions

View file

@ -267,7 +267,8 @@ def remote_user_creation(info, params) do
:follower_count, :follower_count,
:fields, :fields,
:following_count, :following_count,
:discoverable :discoverable,
:invisible
]) ])
|> validate_fields(true) |> validate_fields(true)
end end

View file

@ -1107,6 +1107,13 @@ defp object_to_user_data(data) do
data = Transmogrifier.maybe_fix_user_object(data) data = Transmogrifier.maybe_fix_user_object(data)
discoverable = data["discoverable"] || false discoverable = data["discoverable"] || false
invisible =
if is_list(data["type"]) do
Enum.member?(data["type"], "Invisible")
else
false
end
user_data = %{ user_data = %{
ap_id: data["id"], ap_id: data["id"],
info: %{ info: %{
@ -1115,7 +1122,8 @@ defp object_to_user_data(data) do
banner: banner, banner: banner,
fields: fields, fields: fields,
locked: locked, locked: locked,
discoverable: discoverable discoverable: discoverable,
invisible: invisible
}, },
avatar: avatar, avatar: avatar,
name: data["name"], name: data["name"],

View file

@ -596,13 +596,20 @@ def handle_incoming(
data, data,
_options _options
) )
when object_type in ["Person", "Application", "Service", "Organization"] do when object_type in [
"Person",
"Application",
"Service",
"Organization",
["Application", "Invisible"]
] do
with %User{ap_id: ^actor_id} = actor <- User.get_cached_by_ap_id(object["id"]) do with %User{ap_id: ^actor_id} = actor <- User.get_cached_by_ap_id(object["id"]) do
{:ok, new_user_data} = ActivityPub.user_data_from_user_object(object) {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object)
banner = new_user_data[:info][:banner] banner = new_user_data[:info][:banner]
locked = new_user_data[:info][:locked] || false locked = new_user_data[:info][:locked] || false
attachment = get_in(new_user_data, [:info, :source_data, "attachment"]) || [] attachment = get_in(new_user_data, [:info, :source_data, "attachment"]) || []
invisible = new_user_data[:info][:invisible] || false
fields = fields =
attachment attachment
@ -612,7 +619,7 @@ def handle_incoming(
update_data = update_data =
new_user_data new_user_data
|> Map.take([:name, :bio, :avatar]) |> Map.take([:name, :bio, :avatar])
|> Map.put(:info, %{banner: banner, locked: locked, fields: fields}) |> Map.put(:info, %{banner: banner, locked: locked, fields: fields, invisible: invisible})
actor actor
|> User.upgrade_changeset(update_data, true) |> User.upgrade_changeset(update_data, true)

View file

@ -491,11 +491,15 @@ def add_announce_to_object(
%Activity{data: %{"actor" => actor}}, %Activity{data: %{"actor" => actor}},
object object
) do ) do
unless actor |> User.get_cached_by_ap_id() |> User.invisible?() do
announcements = take_announcements(object) announcements = take_announcements(object)
with announcements <- Enum.uniq([actor | announcements]) do with announcements <- Enum.uniq([actor | announcements]) do
update_element_in_object("announcement", announcements, object) update_element_in_object("announcement", announcements, object)
end end
else
{:ok, object}
end
end end
def add_announce_to_object(_, object), do: {:ok, object} def add_announce_to_object(_, object), do: {:ok, object}

View file

@ -0,0 +1,54 @@
{
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1", {
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"movedTo": "as:movedTo",
"Hashtag": "as:Hashtag",
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji"
}],
"id": "http://mastodon.example.org/users/admin",
"type": ["Application", "Invisible"],
"following": "http://mastodon.example.org/users/admin/following",
"followers": "http://mastodon.example.org/users/admin/followers",
"inbox": "http://mastodon.example.org/users/admin/inbox",
"outbox": "http://mastodon.example.org/users/admin/outbox",
"preferredUsername": "admin",
"name": null,
"summary": "\u003cp\u003e\u003c/p\u003e",
"url": "http://mastodon.example.org/@admin",
"manuallyApprovesFollowers": false,
"publicKey": {
"id": "http://mastodon.example.org/users/admin#main-key",
"owner": "http://mastodon.example.org/users/admin",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtc4Tir+3ADhSNF6VKrtW\nOU32T01w7V0yshmQei38YyiVwVvFu8XOP6ACchkdxbJ+C9mZud8qWaRJKVbFTMUG\nNX4+6Q+FobyuKrwN7CEwhDALZtaN2IPbaPd6uG1B7QhWorrY+yFa8f2TBM3BxnUy\nI4T+bMIZIEYG7KtljCBoQXuTQmGtuffO0UwJksidg2ffCF5Q+K//JfQagJ3UzrR+\nZXbKMJdAw4bCVJYs4Z5EhHYBwQWiXCyMGTd7BGlmMkY6Av7ZqHKC/owp3/0EWDNz\nNqF09Wcpr3y3e8nA10X40MJqp/wR+1xtxp+YGbq/Cj5hZGBG7etFOmIpVBrDOhry\nBwIDAQAB\n-----END PUBLIC KEY-----\n"
},
"attachment": [{
"type": "PropertyValue",
"name": "foo",
"value": "bar"
},
{
"type": "PropertyValue",
"name": "foo1",
"value": "bar1"
}
],
"endpoints": {
"sharedInbox": "http://mastodon.example.org/inbox"
},
"icon": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
},
"image": {
"type": "Image",
"mediaType": "image/png",
"url": "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
}
}

View file

@ -348,6 +348,14 @@ def get("http://mastodon.example.org/users/admin", _, _, Accept: "application/ac
}} }}
end end
def get("http://mastodon.example.org/users/relay", _, _, Accept: "application/activity+json") do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/relay@mastdon.example.org.json")
}}
end
def get("http://mastodon.example.org/users/gargron", _, _, Accept: "application/activity+json") do def get("http://mastodon.example.org/users/gargron", _, _, Accept: "application/activity+json") do
{:error, :nxdomain} {:error, :nxdomain}
end end

View file

@ -179,6 +179,12 @@ test "it returns a user" do
assert user.follower_address == "http://mastodon.example.org/users/admin/followers" assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
end end
test "it returns a user that is invisible" do
user_id = "http://mastodon.example.org/users/relay"
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.info.invisible
end
test "it fetches the appropriate tag-restricted posts" do test "it fetches the appropriate tag-restricted posts" do
user = insert(:user) user = insert(:user)