From 05f2cd0d930e93d1eb80a8a4ba3952f8ba46f5ce Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Wed, 10 May 2017 18:46:23 +0200 Subject: [PATCH] Handle incoming follows. Also Mastodon CWs. --- .../web/ostatus/handlers/follow_handler.ex | 16 ++ lib/pleroma/web/ostatus/ostatus.ex | 15 +- test/fixtures/follow.xml | 68 ++++++ .../https___pawoo.net_users_pekorino.atom | 231 ++++++++++++++++++ .../https___pawoo.net_users_pekorino.xml | 11 + test/fixtures/mastodon-note-cw.xml | 39 +++ test/support/httpoison_mock.ex | 24 +- test/web/ostatus/ostatus_test.exs | 27 +- 8 files changed, 427 insertions(+), 4 deletions(-) create mode 100644 lib/pleroma/web/ostatus/handlers/follow_handler.ex create mode 100644 test/fixtures/follow.xml create mode 100644 test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom create mode 100644 test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml create mode 100644 test/fixtures/mastodon-note-cw.xml diff --git a/lib/pleroma/web/ostatus/handlers/follow_handler.ex b/lib/pleroma/web/ostatus/handlers/follow_handler.ex new file mode 100644 index 000000000..f5db5582b --- /dev/null +++ b/lib/pleroma/web/ostatus/handlers/follow_handler.ex @@ -0,0 +1,16 @@ +defmodule Pleroma.Web.OStatus.FollowHandler do + alias Pleroma.Web.{XML, OStatus} + alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.User + + def handle(entry, doc) do + with {:ok, actor} <- OStatus.find_make_or_update_user(doc), + id when not is_nil(id) <- XML.string_from_xpath("/entry/id", entry), + followed_uri when not is_nil(followed_uri) <- XML.string_from_xpath("/entry/activity:object/id", entry), + {:ok, followed} <- OStatus.find_or_make_user(followed_uri), + {:ok, activity} <- ActivityPub.follow(actor, followed, id, false) do + User.follow(actor, followed) + {:ok, activity} + end + end +end diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index da0407aeb..b19f0172a 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -8,6 +8,7 @@ defmodule Pleroma.Web.OStatus do alias Pleroma.{Repo, User, Web, Object, Activity} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.{WebFinger, Websub} + alias Pleroma.Web.OStatus.FollowHandler def feed_path(user) do "#{user.ap_id}/feed.atom" @@ -30,6 +31,8 @@ def handle_incoming(xml_string) do {:xmlObj, :string, verb} = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry) case verb do + 'http://activitystrea.ms/schema/1.0/follow' -> + with {:ok, activity} <- FollowHandler.handle(entry, doc), do: activity 'http://activitystrea.ms/schema/1.0/share' -> with {:ok, activity, retweeted_activity} <- handle_share(entry, doc), do: [activity, retweeted_activity] 'http://activitystrea.ms/schema/1.0/favorite' -> @@ -116,8 +119,18 @@ def get_attachments(entry) do |> Enum.filter(&(&1)) end + def get_content(entry) do + base_content = string_from_xpath("/entry/content", entry) + + with scope when not is_nil(scope) <- string_from_xpath("//mastodon:scope", entry), + cw when not is_nil(cw) <- string_from_xpath("/entry/summary", entry) do + "#{cw}
#{base_content}" + else _e -> base_content + end + end + def handle_note(entry, doc \\ nil) do - content_html = string_from_xpath("//content[1]", entry) + content_html = get_content(entry) [author] = :xmerl_xpath.string('//author[1]', doc) {:ok, actor} = find_make_or_update_user(author) diff --git a/test/fixtures/follow.xml b/test/fixtures/follow.xml new file mode 100644 index 000000000..d4e89954b --- /dev/null +++ b/test/fixtures/follow.xml @@ -0,0 +1,68 @@ + + + GNU social + https://social.heldscal.la/api/statuses/user_timeline/23211.atom + lambadalambda timeline + Updates from lambadalambda on social.heldscal.la! + https://social.heldscal.la/avatar/23211-96-20170416114255.jpeg + 2017-05-07T09:54:49+00:00 + + http://activitystrea.ms/schema/1.0/person + https://social.heldscal.la/user/23211 + lambadalambda + Call me Deacon Blues. + + + + + + lambadalambda + Constance Variable + Call me Deacon Blues. + + Berlin + + + homepage + https://heldscal.la + true + + + + + + + + + + + + + tag:social.heldscal.la,2017-05-07:subscription:23211:person:44803:2017-05-07T09:54:48+00:00 + Constance Variable (lambadalambda@social.heldscal.la)'s status on Sunday, 07-May-2017 09:54:49 UTC + <a href="https://social.heldscal.la/lambadalambda">Constance Variable</a> started following <a href="https://pawoo.net/@pekorino">mono</a>. + + http://activitystrea.ms/schema/1.0/follow + 2017-05-07T09:54:49+00:00 + 2017-05-07T09:54:49+00:00 + + http://activitystrea.ms/schema/1.0/person + https://pawoo.net/users/pekorino + mono + http://shitposter.club/mono 孤独のグルメ + + + + + pekorino + mono + http://shitposter.club/mono 孤独のグルメ + + + tag:social.heldscal.la,2017-05-07:objectType=thread:nonce=6e80caf94e03029f + + + + + + diff --git a/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom b/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom new file mode 100644 index 000000000..17d1956e8 --- /dev/null +++ b/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom @@ -0,0 +1,231 @@ + + + https://pawoo.net/users/pekorino.atom + モノエ + シアトル・米国 + +GNUsocial 英語版 +http://shitposter.club/mono + + + 2017-05-07T09:28:20Z + https://img.pawoo.net/accounts/avatars/000/128/378/original/e1fce04a36a1ad90.jpg + + https://pawoo.net/users/pekorino + http://activitystrea.ms/schema/1.0/person + https://pawoo.net/users/pekorino + pekorino + pekorino@pawoo.net + <p>シアトル・米国</p><p>GNUsocial 英語版<br /><a href="http://shitposter.club/mono" rel="nofollow noopener" target="_blank"><span class="invisible">http://</span><span class="">shitposter.club/mono</span><span class="invisible"></span></a> </p> + + + + pekorino + モノエ + シアトル・米国 + +GNUsocial 英語版 +http://shitposter.club/mono + + + public + + + + + + + tag:pawoo.net,2017-05-07:objectId=9319211:objectType=Status + 2017-05-07T09:56:35Z + 2017-05-07T09:56:35Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/moonman" class="u-url mention">@<span>moonman</span></a></span> <span class="h-card"><a href="https://shitposter.club/rw" class="u-url mention">@<span>rw</span></a></span> <span class="h-card"><a href="https://social.heldscal.la/lambadalambda" class="u-url mention">@<span>lambadalambda</span></a></span> <span class="h-card"><a href="https://shitposter.club/mono" class="u-url mention">@<span>mono</span></a></span> </p><p>i have to wait for someone to respond to this before i can follow because i dont think this software has a direct follow by url option</p> + + + + + + public + + + + + + tag:pawoo.net,2017-05-07:objectId=9318595:objectType=Status + 2017-05-07T09:54:39Z + 2017-05-07T09:54:39Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/mono" class="u-url mention">@<span>mono</span></a></span> <span class="h-card"><a href="https://social.heldscal.la/lambadalambda" class="u-url mention">@<span>lambadalambda</span></a></span> <span class="h-card"><a href="https://shitposter.club/rw" class="u-url mention">@<span>rw</span></a></span> <span class="h-card"><a href="https://shitposter.club/moonman" class="u-url mention">@<span>moonman</span></a></span> <br />please respond</p> + + + + + + public + + + + + + tag:pawoo.net,2017-05-07:objectId=9313978:objectType=Status + 2017-05-07T09:39:17Z + 2017-05-07T09:39:17Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/moonman" class="u-url mention">@<span>moonman</span></a></span> <br />mastodon is so slow. browser crashed twice trying to set avatar</p> + + + public + + + + + tag:pawoo.net,2017-05-07:objectId=9312691:objectType=Status + 2017-05-07T09:34:38Z + 2017-05-07T09:34:38Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/hardbass2k8" class="u-url mention">@<span>hardbass2k8</span></a></span> <a href="https://pawoo.net/media/mZJjLpbPU72GFEz2Svk" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">pawoo.net/media/mZJjLpbPU72GFE</span><span class="invisible">z2Svk</span></a></p> + + + + public + + + + + + tag:pawoo.net,2017-05-07:objectId=9312379:objectType=Status + 2017-05-07T09:33:29Z + 2017-05-07T09:33:29Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/hardbass2k8" class="u-url mention">@<span>hardbass2k8</span></a></span> <a href="https://pawoo.net/media/nt5JHBEHyTN2bqzdcGU" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">pawoo.net/media/nt5JHBEHyTN2bq</span><span class="invisible">zdcGU</span></a></p> + + + + public + + + + + + tag:pawoo.net,2017-05-07:objectId=9311765:objectType=Status + 2017-05-07T09:31:26Z + 2017-05-07T09:31:26Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p><a href="https://pawoo.net/media/C4RV6ubsEtvS04DX6qs" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">pawoo.net/media/C4RV6ubsEtvS04</span><span class="invisible">DX6qs</span></a></p> + + + public + + + + + tag:pawoo.net,2017-05-07:objectId=9311610:objectType=Status + 2017-05-07T09:30:59Z + 2017-05-07T09:30:59Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p><a href="https://pawoo.net/media/MBmkeEdrjs8pAtCHN6s" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">pawoo.net/media/MBmkeEdrjs8pAt</span><span class="invisible">CHN6s</span></a></p> + + + public + + + + + tag:pawoo.net,2017-05-07:objectId=9307782:objectType=Status + 2017-05-07T09:16:47Z + 2017-05-07T09:16:47Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/mono" class="u-url mention">@<span>mono</span></a></span></p><p>test</p> + + + public + + + + + tag:pawoo.net,2017-05-07:objectId=9307444:objectType=Status + 2017-05-07T09:15:42Z + 2017-05-07T09:15:42Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/hardbass2k8" class="u-url mention">@<span>hardbass2k8</span></a></span> テスト</p> + + + public + + + + + + tag:pawoo.net,2017-05-07:objectId=9307239:objectType=Status + 2017-05-07T09:14:58Z + 2017-05-07T09:14:58Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p>ててててててテスト</p> + + public + + + + + tag:pawoo.net,2017-04-20:objectId=2212164:objectType=Status + 2017-04-20T06:19:18Z + 2017-04-20T06:19:18Z + New status by pekorino + http://activitystrea.ms/schema/1.0/comment + http://activitystrea.ms/schema/1.0/post + <p><span class="h-card"><a href="https://shitposter.club/mono" class="u-url mention">@<span>mono</span></a></span> <a href="https://pawoo.net/media/iMbjMBVPfZJX3lUC2Sc" rel="nofollow noopener" target="_blank"><span class="invisible">https://</span><span class="ellipsis">pawoo.net/media/iMbjMBVPfZJX3l</span><span class="invisible">UC2Sc</span></a></p> + + + + public + + + + + + tag:pawoo.net,2017-04-20:objectId=2206216:objectType=Status + 2017-04-20T05:57:59Z + 2017-04-20T05:57:59Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p>テスト</p> + + public + + + + + tag:pawoo.net,2017-04-20:objectId=2204702:objectType=Status + 2017-04-20T05:52:09Z + 2017-04-20T05:52:09Z + New status by pekorino + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <p>HELLOWORLD</p> + + public + + + + diff --git a/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml b/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml new file mode 100644 index 000000000..1f1478a5e --- /dev/null +++ b/test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml @@ -0,0 +1,11 @@ + + + acct:pekorino@pawoo.net + https://pawoo.net/@pekorino + https://pawoo.net/users/pekorino + + + + + + diff --git a/test/fixtures/mastodon-note-cw.xml b/test/fixtures/mastodon-note-cw.xml new file mode 100644 index 000000000..02f49dd61 --- /dev/null +++ b/test/fixtures/mastodon-note-cw.xml @@ -0,0 +1,39 @@ + + + https://mastodon.social/users/lambadalambda.atom + Critical Value + + 2017-04-16T21:47:25Z + https://files.mastodon.social/accounts/avatars/000/000/264/original/1429214160519.gif + + https://mastodon.social/users/lambadalambda + http://activitystrea.ms/schema/1.0/person + https://mastodon.social/users/lambadalambda + lambadalambda + lambadalambda@mastodon.social + + + + lambadalambda + Critical Value + public + + + + + + + tag:mastodon.social,2017-05-10:objectId=5551985:objectType=Status + 2017-05-10T12:21:36Z + 2017-05-10T12:21:36Z + New status by lambadalambda + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + technologic + <p>test</p> + + public + + + + diff --git a/test/support/httpoison_mock.ex b/test/support/httpoison_mock.ex index 733abced2..0eff336ab 100644 --- a/test/support/httpoison_mock.ex +++ b/test/support/httpoison_mock.ex @@ -16,7 +16,7 @@ def get("https://social.heldscal.la/.well-known/webfinger", [Accept: "applicatio body: File.read!("test/fixtures/httpoison_mock/shp@social.heldscal.la.xml") }} end - + def get("https://social.heldscal.la/.well-known/webfinger", [Accept: "application/xrd+xml"], [params: [resource: "https://social.heldscal.la/user/23211"]]) do {:ok, %Response{ status_code: 200, @@ -115,8 +115,28 @@ def get("https://shitposter.club/api/statuses/user_timeline/1.atom", _body, _hea }} end + def post("https://social.heldscal.la/main/push/hub", {:form, data}, ["Content-type": "application/x-www-form-urlencoded"]) do + {:ok, %Response{ + status_code: 202 + }} + end + + def get("https://pawoo.net/.well-known/webfinger", [Accept: "application/xrd+xml"], [params: [resource: "https://pawoo.net/users/pekorino"]]) do + {:ok, %Response{ + status_code: 200, + body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml") + }} + end + + def get("https://pawoo.net/users/pekorino.atom", _, _) do + {:ok, %Response{ + status_code: 200, + body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom") + }} + end + def get(url, body, headers) do - {:error, "Not implemented the mock response for get #{inspect(url)}"} + {:error, "Not implemented the mock response for get #{inspect(url)}, #{inspect(body)}, #{inspect(headers)}"} end def post(url, body, headers) do diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 39f299ab4..b326dc0a0 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -62,6 +62,16 @@ test "handle incoming notes - Mastodon, salmon, reply" do assert activity.data["context"] == "2hu" end + test "handle incoming notes - Mastodon, with CW" do + incoming = File.read!("test/fixtures/mastodon-note-cw.xml") + {:ok, [activity]} = OStatus.handle_incoming(incoming) + + assert activity.data["type"] == "Create" + assert activity.data["object"]["type"] == "Note" + assert activity.data["object"]["actor"] == "https://mastodon.social/users/lambadalambda" + assert String.contains?(activity.data["object"]["content"], "technologic") + end + test "handle incoming notes - GS, subscription, reply" do incoming = File.read!("test/fixtures/ostatus_incoming_reply.xml") {:ok, [activity]} = OStatus.handle_incoming(incoming) @@ -172,6 +182,21 @@ test "handle incoming replies" do assert activity.data["object"]["id"] == "tag:gs.example.org:4040,2017-04-25:noticeId=55:objectType=note" end + test "handle incoming follows" do + incoming = File.read!("test/fixtures/follow.xml") + {:ok, [activity]} = OStatus.handle_incoming(incoming) + assert activity.data["type"] == "Follow" + assert activity.data["id"] == "tag:social.heldscal.la,2017-05-07:subscription:23211:person:44803:2017-05-07T09:54:48+00:00" + assert activity.data["actor"] == "https://social.heldscal.la/user/23211" + assert activity.data["object"] == "https://pawoo.net/users/pekorino" + refute activity.local + + follower = User.get_cached_by_ap_id(activity.data["actor"]) + followed = User.get_cached_by_ap_id(activity.data["object"]) + + assert User.following?(follower, followed) + end + describe "new remote user creation" do test "returns local users" do local_user = insert(:user) @@ -270,6 +295,6 @@ test "it builds a missing status from an html url" do assert activity.data["actor"] == "https://shitposter.club/user/1" assert activity.data["object"]["id"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" - end + end end end