move to 2.5.5
[anni] / test / pleroma / web / federator_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.FederatorTest do
6   alias Pleroma.Instances
7   alias Pleroma.Tests.ObanHelpers
8   alias Pleroma.Web.CommonAPI
9   alias Pleroma.Web.Federator
10   alias Pleroma.Workers.PublisherWorker
11
12   use Pleroma.DataCase
13   use Oban.Testing, repo: Pleroma.Repo
14
15   import Pleroma.Factory
16   import Mock
17
18   setup_all do
19     Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
20
21     :ok
22   end
23
24   setup_all do: clear_config([:instance, :federating], true)
25   setup do: clear_config([:instance, :allow_relay])
26   setup do: clear_config([:mrf, :policies])
27   setup do: clear_config([:mrf_keyword])
28
29   describe "Publish an activity" do
30     setup do
31       user = insert(:user)
32       {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
33
34       relay_mock = {
35         Pleroma.Web.ActivityPub.Relay,
36         [],
37         [publish: fn _activity -> send(self(), :relay_publish) end]
38       }
39
40       %{activity: activity, relay_mock: relay_mock}
41     end
42
43     test "with relays active, it publishes to the relay", %{
44       activity: activity,
45       relay_mock: relay_mock
46     } do
47       with_mocks([relay_mock]) do
48         Federator.publish(activity)
49         ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
50       end
51
52       assert_received :relay_publish
53     end
54
55     test "with relays deactivated, it does not publish to the relay", %{
56       activity: activity,
57       relay_mock: relay_mock
58     } do
59       clear_config([:instance, :allow_relay], false)
60
61       with_mocks([relay_mock]) do
62         Federator.publish(activity)
63         ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
64       end
65
66       refute_received :relay_publish
67     end
68   end
69
70   describe "Targets reachability filtering in `publish`" do
71     test "it federates only to reachable instances via AP" do
72       user = insert(:user)
73
74       {inbox1, inbox2} =
75         {"https://domain.com/users/nick1/inbox", "https://domain2.com/users/nick2/inbox"}
76
77       insert(:user, %{
78         local: false,
79         nickname: "nick1@domain.com",
80         ap_id: "https://domain.com/users/nick1",
81         inbox: inbox1,
82         ap_enabled: true
83       })
84
85       insert(:user, %{
86         local: false,
87         nickname: "nick2@domain2.com",
88         ap_id: "https://domain2.com/users/nick2",
89         inbox: inbox2,
90         ap_enabled: true
91       })
92
93       dt = NaiveDateTime.utc_now()
94       Instances.set_unreachable(inbox1, dt)
95
96       Instances.set_consistently_unreachable(URI.parse(inbox2).host)
97
98       {:ok, _activity} =
99         CommonAPI.post(user, %{status: "HI @nick1@domain.com, @nick2@domain2.com!"})
100
101       expected_dt = NaiveDateTime.to_iso8601(dt)
102
103       ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
104
105       assert ObanHelpers.member?(
106                %{
107                  "op" => "publish_one",
108                  "params" => %{"inbox" => inbox1, "unreachable_since" => expected_dt}
109                },
110                all_enqueued(worker: PublisherWorker)
111              )
112     end
113   end
114
115   describe "Receive an activity" do
116     test "successfully processes incoming AP docs with correct origin" do
117       params = %{
118         "@context" => "https://www.w3.org/ns/activitystreams",
119         "actor" => "http://mastodon.example.org/users/admin",
120         "type" => "Create",
121         "id" => "http://mastodon.example.org/users/admin/activities/1",
122         "object" => %{
123           "type" => "Note",
124           "content" => "hi world!",
125           "id" => "http://mastodon.example.org/users/admin/objects/1",
126           "attributedTo" => "http://mastodon.example.org/users/admin",
127           "to" => ["https://www.w3.org/ns/activitystreams#Public"]
128         },
129         "to" => ["https://www.w3.org/ns/activitystreams#Public"]
130       }
131
132       assert {:ok, job} = Federator.incoming_ap_doc(params)
133       assert {:ok, _activity} = ObanHelpers.perform(job)
134
135       assert {:ok, job} = Federator.incoming_ap_doc(params)
136       assert {:cancel, :already_present} = ObanHelpers.perform(job)
137     end
138
139     test "rejects incoming AP docs with incorrect origin" do
140       params = %{
141         "@context" => "https://www.w3.org/ns/activitystreams",
142         "actor" => "https://niu.moe/users/rye",
143         "type" => "Create",
144         "id" => "http://mastodon.example.org/users/admin/activities/1",
145         "object" => %{
146           "type" => "Note",
147           "content" => "hi world!",
148           "id" => "http://mastodon.example.org/users/admin/objects/1",
149           "attributedTo" => "http://mastodon.example.org/users/admin",
150           "to" => ["https://www.w3.org/ns/activitystreams#Public"]
151         },
152         "to" => ["https://www.w3.org/ns/activitystreams#Public"]
153       }
154
155       assert {:ok, job} = Federator.incoming_ap_doc(params)
156       assert {:cancel, :origin_containment_failed} = ObanHelpers.perform(job)
157     end
158
159     test "it does not crash if MRF rejects the post" do
160       clear_config([:mrf_keyword, :reject], ["lain"])
161
162       clear_config(
163         [:mrf, :policies],
164         Pleroma.Web.ActivityPub.MRF.KeywordPolicy
165       )
166
167       params =
168         File.read!("test/fixtures/mastodon-post-activity.json")
169         |> Jason.decode!()
170
171       assert {:ok, job} = Federator.incoming_ap_doc(params)
172       assert {:cancel, _} = ObanHelpers.perform(job)
173     end
174   end
175 end