First
[anni] / test / mix / tasks / pleroma / config_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 Mix.Tasks.Pleroma.ConfigTest do
6   use Pleroma.DataCase
7
8   import Pleroma.Factory
9
10   alias Mix.Tasks.Pleroma.Config, as: MixTask
11   alias Pleroma.ConfigDB
12   alias Pleroma.Repo
13
14   setup_all do
15     Mix.shell(Mix.Shell.Process)
16
17     on_exit(fn ->
18       Mix.shell(Mix.Shell.IO)
19       Application.delete_env(:pleroma, :first_setting)
20       Application.delete_env(:pleroma, :second_setting)
21     end)
22
23     :ok
24   end
25
26   defp config_records do
27     ConfigDB
28     |> Repo.all()
29     |> Enum.sort()
30   end
31
32   defp insert_config_record(group, key, value) do
33     insert(:config,
34       group: group,
35       key: key,
36       value: value
37     )
38   end
39
40   test "error if file with custom settings doesn't exist" do
41     MixTask.migrate_to_db("config/non_existent_config_file.exs")
42
43     msg =
44       "To migrate settings, you must define custom settings in config/non_existent_config_file.exs."
45
46     assert_receive {:mix_shell, :info, [^msg]}, 15
47   end
48
49   describe "migrate_to_db/1" do
50     setup do
51       clear_config(:configurable_from_database, true)
52     end
53
54     @tag capture_log: true
55     test "config migration refused when deprecated settings are found" do
56       clear_config([:media_proxy, :whitelist], ["domain_without_scheme.com"])
57       assert config_records() == []
58
59       MixTask.migrate_to_db("test/fixtures/config/temp.secret.exs")
60
61       assert_received {:mix_shell, :error, [message]}
62
63       assert message =~
64                "Migration is not allowed until all deprecation warnings have been resolved."
65     end
66
67     test "filtered settings are migrated to db" do
68       assert config_records() == []
69
70       MixTask.migrate_to_db("test/fixtures/config/temp.secret.exs")
71
72       config1 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":first_setting"})
73       config2 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":second_setting"})
74       refute ConfigDB.get_by_params(%{group: ":pleroma", key: "Pleroma.Repo"})
75       refute ConfigDB.get_by_params(%{group: ":postgrex", key: ":json_library"})
76       refute ConfigDB.get_by_params(%{group: ":pleroma", key: ":database"})
77
78       assert config1.value == [key: "value", key2: [Repo]]
79       assert config2.value == [key: "value2", key2: ["Activity"]]
80     end
81
82     test "config table is truncated before migration" do
83       insert_config_record(:pleroma, :first_setting, key: "value", key2: ["Activity"])
84       assert length(config_records()) == 1
85
86       MixTask.migrate_to_db("test/fixtures/config/temp.secret.exs")
87
88       config = ConfigDB.get_by_params(%{group: ":pleroma", key: ":first_setting"})
89       assert config.value == [key: "value", key2: [Repo]]
90     end
91   end
92
93   describe "with deletion of temp file" do
94     setup do
95       clear_config(:configurable_from_database, true)
96       temp_file = "config/temp.exported_from_db.secret.exs"
97
98       on_exit(fn ->
99         :ok = File.rm(temp_file)
100       end)
101
102       {:ok, temp_file: temp_file}
103     end
104
105     test "settings are migrated to file and deleted from db", %{temp_file: temp_file} do
106       insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"])
107       insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo])
108
109       MixTask.run(["migrate_from_db", "--env", "temp", "-d"])
110
111       assert config_records() == []
112
113       file = File.read!(temp_file)
114       assert file =~ "config :pleroma, :setting_first,"
115       assert file =~ "config :pleroma, :setting_second,"
116     end
117
118     test "load a settings with large values and pass to file", %{temp_file: temp_file} do
119       insert(:config,
120         key: :instance,
121         value: [
122           name: "Pleroma",
123           email: "example@example.com",
124           notify_email: "noreply@example.com",
125           description: "A Pleroma instance, an alternative fediverse server",
126           limit: 5_000,
127           chat_limit: 5_000,
128           remote_limit: 100_000,
129           upload_limit: 16_000_000,
130           avatar_upload_limit: 2_000_000,
131           background_upload_limit: 4_000_000,
132           banner_upload_limit: 4_000_000,
133           poll_limits: %{
134             max_options: 20,
135             max_option_chars: 200,
136             min_expiration: 0,
137             max_expiration: 365 * 24 * 60 * 60
138           },
139           registrations_open: true,
140           federating: true,
141           federation_incoming_replies_max_depth: 100,
142           federation_reachability_timeout_days: 7,
143           federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
144           allow_relay: true,
145           public: true,
146           quarantined_instances: [],
147           managed_config: true,
148           static_dir: "instance/static/",
149           allowed_post_formats: ["text/plain", "text/html", "text/markdown", "text/bbcode"],
150           autofollowed_nicknames: [],
151           max_pinned_statuses: 1,
152           attachment_links: false,
153           max_report_comment_size: 1000,
154           safe_dm_mentions: false,
155           healthcheck: false,
156           remote_post_retention_days: 90,
157           skip_thread_containment: true,
158           limit_to_local_content: :unauthenticated,
159           user_bio_length: 5000,
160           user_name_length: 100,
161           max_account_fields: 10,
162           max_remote_account_fields: 20,
163           account_field_name_length: 512,
164           account_field_value_length: 2048,
165           external_user_synchronization: true,
166           extended_nickname_format: true,
167           multi_factor_authentication: [
168             totp: [
169               digits: 6,
170               period: 30
171             ],
172             backup_codes: [
173               number: 2,
174               length: 6
175             ]
176           ]
177         ]
178       )
179
180       MixTask.run(["migrate_from_db", "--env", "temp", "-d"])
181
182       assert config_records() == []
183       assert File.exists?(temp_file)
184       {:ok, file} = File.read(temp_file)
185
186       assert file ==
187                "import Config\n\nconfig :pleroma, :instance,\n  name: \"Pleroma\",\n  email: \"example@example.com\",\n  notify_email: \"noreply@example.com\",\n  description: \"A Pleroma instance, an alternative fediverse server\",\n  limit: 5000,\n  chat_limit: 5000,\n  remote_limit: 100_000,\n  upload_limit: 16_000_000,\n  avatar_upload_limit: 2_000_000,\n  background_upload_limit: 4_000_000,\n  banner_upload_limit: 4_000_000,\n  poll_limits: %{\n    max_expiration: 31_536_000,\n    max_option_chars: 200,\n    max_options: 20,\n    min_expiration: 0\n  },\n  registrations_open: true,\n  federating: true,\n  federation_incoming_replies_max_depth: 100,\n  federation_reachability_timeout_days: 7,\n  federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n  allow_relay: true,\n  public: true,\n  quarantined_instances: [],\n  managed_config: true,\n  static_dir: \"instance/static/\",\n  allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n  autofollowed_nicknames: [],\n  max_pinned_statuses: 1,\n  attachment_links: false,\n  max_report_comment_size: 1000,\n  safe_dm_mentions: false,\n  healthcheck: false,\n  remote_post_retention_days: 90,\n  skip_thread_containment: true,\n  limit_to_local_content: :unauthenticated,\n  user_bio_length: 5000,\n  user_name_length: 100,\n  max_account_fields: 10,\n  max_remote_account_fields: 20,\n  account_field_name_length: 512,\n  account_field_value_length: 2048,\n  external_user_synchronization: true,\n  extended_nickname_format: true,\n  multi_factor_authentication: [\n    totp: [digits: 6, period: 30],\n    backup_codes: [number: 2, length: 6]\n  ]\n"
188     end
189   end
190
191   describe "migrate_from_db/1" do
192     setup do: clear_config(:configurable_from_database, true)
193
194     setup do
195       insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"])
196       insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo])
197
198       path = "test/instance_static"
199       file_path = Path.join(path, "temp.exported_from_db.secret.exs")
200
201       on_exit(fn -> File.rm!(file_path) end)
202
203       [file_path: file_path]
204     end
205
206     test "with path parameter", %{file_path: file_path} do
207       MixTask.run(["migrate_from_db", "--env", "temp", "--path", Path.dirname(file_path)])
208
209       file = File.read!(file_path)
210       assert file =~ "config :pleroma, :setting_first,"
211       assert file =~ "config :pleroma, :setting_second,"
212     end
213
214     test "release", %{file_path: file_path} do
215       clear_config(:release, true)
216       clear_config(:config_path, file_path)
217
218       MixTask.run(["migrate_from_db", "--env", "temp"])
219
220       file = File.read!(file_path)
221       assert file =~ "config :pleroma, :setting_first,"
222       assert file =~ "config :pleroma, :setting_second,"
223     end
224   end
225
226   describe "operations on database config" do
227     setup do: clear_config(:configurable_from_database, true)
228
229     test "dumping a specific group" do
230       insert_config_record(:pleroma, :instance, name: "Pleroma Test")
231
232       insert_config_record(:web_push_encryption, :vapid_details,
233         subject: "mailto:administrator@example.com",
234         public_key:
235           "BOsPL-_KjNnjj_RMvLeR3dTOrcndi4TbMR0cu56gLGfGaT5m1gXxSfRHOcC4Dd78ycQL1gdhtx13qgKHmTM5xAI",
236         private_key: "Ism6FNdS31nLCA94EfVbJbDdJXCxAZ8cZiB1JQPN_t4"
237       )
238
239       MixTask.run(["dump", "pleroma"])
240
241       assert_receive {:mix_shell, :info,
242                       ["config :pleroma, :instance, [name: \"Pleroma Test\"]\r\n\r\n"]}
243
244       refute_receive {
245         :mix_shell,
246         :info,
247         [
248           "config :web_push_encryption, :vapid_details, [subject: \"mailto:administrator@example.com\", public_key: \"BOsPL-_KjNnjj_RMvLeR3dTOrcndi4TbMR0cu56gLGfGaT5m1gXxSfRHOcC4Dd78ycQL1gdhtx13qgKHmTM5xAI\", private_key: \"Ism6FNdS31nLCA94EfVbJbDdJXCxAZ8cZiB1JQPN_t4\"]\r\n\r\n"
249         ]
250       }
251
252       # Ensure operations work when using atom syntax
253       MixTask.run(["dump", ":pleroma"])
254
255       assert_receive {:mix_shell, :info,
256                       ["config :pleroma, :instance, [name: \"Pleroma Test\"]\r\n\r\n"]}
257     end
258
259     test "dumping a specific key in a group" do
260       insert_config_record(:pleroma, :instance, name: "Pleroma Test")
261       insert_config_record(:pleroma, Pleroma.Captcha, enabled: false)
262
263       MixTask.run(["dump", "pleroma", "Pleroma.Captcha"])
264
265       refute_receive {:mix_shell, :info,
266                       ["config :pleroma, :instance, [name: \"Pleroma Test\"]\r\n\r\n"]}
267
268       assert_receive {:mix_shell, :info,
269                       ["config :pleroma, Pleroma.Captcha, [enabled: false]\r\n\r\n"]}
270     end
271
272     test "dumps all configuration successfully" do
273       insert_config_record(:pleroma, :instance, name: "Pleroma Test")
274       insert_config_record(:pleroma, Pleroma.Captcha, enabled: false)
275
276       MixTask.run(["dump"])
277
278       assert_receive {:mix_shell, :info,
279                       ["config :pleroma, :instance, [name: \"Pleroma Test\"]\r\n\r\n"]}
280
281       assert_receive {:mix_shell, :info,
282                       ["config :pleroma, Pleroma.Captcha, [enabled: false]\r\n\r\n"]}
283     end
284   end
285
286   describe "when configdb disabled" do
287     test "refuses to dump" do
288       clear_config(:configurable_from_database, false)
289
290       insert_config_record(:pleroma, :instance, name: "Pleroma Test")
291
292       MixTask.run(["dump"])
293
294       msg =
295         "ConfigDB not enabled. Please check the value of :configurable_from_database in your configuration."
296
297       assert_receive {:mix_shell, :error, [^msg]}
298     end
299   end
300
301   describe "destructive operations" do
302     setup do: clear_config(:configurable_from_database, true)
303
304     setup do
305       insert_config_record(:pleroma, :instance, name: "Pleroma Test")
306       insert_config_record(:pleroma, Pleroma.Captcha, enabled: false)
307       insert_config_record(:pleroma2, :key2, z: 1)
308
309       assert length(config_records()) == 3
310
311       :ok
312     end
313
314     test "deletes group of settings" do
315       MixTask.run(["delete", "--force", "pleroma"])
316
317       assert [%ConfigDB{group: :pleroma2, key: :key2}] = config_records()
318     end
319
320     test "deletes specified key" do
321       MixTask.run(["delete", "--force", "pleroma", "Pleroma.Captcha"])
322
323       assert [
324                %ConfigDB{group: :pleroma, key: :instance},
325                %ConfigDB{group: :pleroma2, key: :key2}
326              ] = config_records()
327     end
328
329     test "resets entire config" do
330       MixTask.run(["reset", "--force"])
331
332       assert config_records() == []
333     end
334   end
335 end