move to 2.5.5
[anni] / test / pleroma / web / admin_api / controllers / invite_controller_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.AdminAPI.InviteControllerTest do
6   use Pleroma.Web.ConnCase, async: false
7
8   import Pleroma.Factory
9
10   alias Pleroma.Repo
11   alias Pleroma.UserInviteToken
12
13   setup do
14     admin = insert(:user, is_admin: true)
15     token = insert(:oauth_admin_token, user: admin)
16
17     conn =
18       build_conn()
19       |> assign(:user, admin)
20       |> assign(:token, token)
21
22     {:ok, %{admin: admin, token: token, conn: conn}}
23   end
24
25   describe "POST /api/pleroma/admin/users/email_invite, with valid config" do
26     setup do
27       clear_config([:instance, :registrations_open], false)
28       clear_config([:instance, :invites_enabled], true)
29       clear_config([:instance, :admin_privileges], [:users_manage_invites])
30     end
31
32     test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
33       clear_config([:instance, :admin_privileges], [])
34
35       conn =
36         conn
37         |> put_req_header("content-type", "application/json;charset=utf-8")
38         |> post("/api/pleroma/admin/users/email_invite", %{
39           email: "foo@bar.com",
40           name: "J. D."
41         })
42
43       assert json_response(conn, :forbidden)
44     end
45
46     test "sends invitation and returns 204", %{admin: admin, conn: conn} do
47       recipient_email = "foo@bar.com"
48       recipient_name = "J. D."
49
50       conn =
51         conn
52         |> put_req_header("content-type", "application/json;charset=utf-8")
53         |> post("/api/pleroma/admin/users/email_invite", %{
54           email: recipient_email,
55           name: recipient_name
56         })
57
58       assert json_response_and_validate_schema(conn, :no_content)
59
60       token_record = List.last(Repo.all(Pleroma.UserInviteToken))
61       assert token_record
62       refute token_record.used
63
64       notify_email = Config.get([:instance, :notify_email])
65       instance_name = Config.get([:instance, :name])
66
67       email =
68         Pleroma.Emails.UserEmail.user_invitation_email(
69           admin,
70           token_record,
71           recipient_email,
72           recipient_name
73         )
74
75       Swoosh.TestAssertions.assert_email_sent(
76         from: {instance_name, notify_email},
77         to: {recipient_name, recipient_email},
78         html_body: email.html_body
79       )
80     end
81
82     test "it returns 403 if requested by a non-admin" do
83       non_admin_user = insert(:user)
84       token = insert(:oauth_token, user: non_admin_user)
85
86       conn =
87         build_conn()
88         |> assign(:user, non_admin_user)
89         |> assign(:token, token)
90         |> put_req_header("content-type", "application/json;charset=utf-8")
91         |> post("/api/pleroma/admin/users/email_invite", %{
92           email: "foo@bar.com",
93           name: "JD"
94         })
95
96       assert json_response(conn, :forbidden)
97     end
98
99     test "email with +", %{conn: conn, admin: admin} do
100       recipient_email = "foo+bar@baz.com"
101
102       conn
103       |> put_req_header("content-type", "application/json;charset=utf-8")
104       |> post("/api/pleroma/admin/users/email_invite", %{email: recipient_email})
105       |> json_response_and_validate_schema(:no_content)
106
107       token_record =
108         Pleroma.UserInviteToken
109         |> Repo.all()
110         |> List.last()
111
112       assert token_record
113       refute token_record.used
114
115       notify_email = Config.get([:instance, :notify_email])
116       instance_name = Config.get([:instance, :name])
117
118       email =
119         Pleroma.Emails.UserEmail.user_invitation_email(
120           admin,
121           token_record,
122           recipient_email
123         )
124
125       Swoosh.TestAssertions.assert_email_sent(
126         from: {instance_name, notify_email},
127         to: recipient_email,
128         html_body: email.html_body
129       )
130     end
131   end
132
133   describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
134     setup do
135       clear_config([:instance, :registrations_open])
136       clear_config([:instance, :invites_enabled])
137       clear_config([:instance, :admin_privileges], [:users_manage_invites])
138     end
139
140     test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
141       clear_config([:instance, :registrations_open], false)
142       clear_config([:instance, :invites_enabled], false)
143
144       conn =
145         conn
146         |> put_req_header("content-type", "application/json")
147         |> post("/api/pleroma/admin/users/email_invite", %{
148           email: "foo@bar.com",
149           name: "JD"
150         })
151
152       assert json_response_and_validate_schema(conn, :bad_request) ==
153                %{
154                  "error" =>
155                    "To send invites you need to set the `invites_enabled` option to true."
156                }
157     end
158
159     test "it returns 500 if `registrations_open` is enabled", %{conn: conn} do
160       clear_config([:instance, :registrations_open], true)
161       clear_config([:instance, :invites_enabled], true)
162
163       conn =
164         conn
165         |> put_req_header("content-type", "application/json")
166         |> post("/api/pleroma/admin/users/email_invite", %{
167           email: "foo@bar.com",
168           name: "JD"
169         })
170
171       assert json_response_and_validate_schema(conn, :bad_request) ==
172                %{
173                  "error" =>
174                    "To send invites you need to set the `registrations_open` option to false."
175                }
176     end
177   end
178
179   describe "POST /api/pleroma/admin/users/invite_token" do
180     setup do
181       clear_config([:instance, :admin_privileges], [:users_manage_invites])
182     end
183
184     test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
185       clear_config([:instance, :admin_privileges], [])
186
187       conn =
188         conn
189         |> put_req_header("content-type", "application/json")
190         |> post("/api/pleroma/admin/users/invite_token")
191
192       assert json_response(conn, :forbidden)
193     end
194
195     test "without options", %{conn: conn} do
196       conn =
197         conn
198         |> put_req_header("content-type", "application/json")
199         |> post("/api/pleroma/admin/users/invite_token")
200
201       invite_json = json_response_and_validate_schema(conn, 200)
202       invite = UserInviteToken.find_by_token!(invite_json["token"])
203       refute invite.used
204       refute invite.expires_at
205       refute invite.max_use
206       assert invite.invite_type == "one_time"
207     end
208
209     test "with expires_at", %{conn: conn} do
210       conn =
211         conn
212         |> put_req_header("content-type", "application/json")
213         |> post("/api/pleroma/admin/users/invite_token", %{
214           "expires_at" => Date.to_string(Date.utc_today())
215         })
216
217       invite_json = json_response_and_validate_schema(conn, 200)
218       invite = UserInviteToken.find_by_token!(invite_json["token"])
219
220       refute invite.used
221       assert invite.expires_at == Date.utc_today()
222       refute invite.max_use
223       assert invite.invite_type == "date_limited"
224     end
225
226     test "with max_use", %{conn: conn} do
227       conn =
228         conn
229         |> put_req_header("content-type", "application/json")
230         |> post("/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
231
232       invite_json = json_response_and_validate_schema(conn, 200)
233       invite = UserInviteToken.find_by_token!(invite_json["token"])
234       refute invite.used
235       refute invite.expires_at
236       assert invite.max_use == 150
237       assert invite.invite_type == "reusable"
238     end
239
240     test "with max use and expires_at", %{conn: conn} do
241       conn =
242         conn
243         |> put_req_header("content-type", "application/json")
244         |> post("/api/pleroma/admin/users/invite_token", %{
245           "max_use" => 150,
246           "expires_at" => Date.to_string(Date.utc_today())
247         })
248
249       invite_json = json_response_and_validate_schema(conn, 200)
250       invite = UserInviteToken.find_by_token!(invite_json["token"])
251       refute invite.used
252       assert invite.expires_at == Date.utc_today()
253       assert invite.max_use == 150
254       assert invite.invite_type == "reusable_date_limited"
255     end
256   end
257
258   describe "GET /api/pleroma/admin/users/invites" do
259     setup do
260       clear_config([:instance, :admin_privileges], [:users_manage_invites])
261     end
262
263     test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
264       clear_config([:instance, :admin_privileges], [])
265
266       conn = get(conn, "/api/pleroma/admin/users/invites")
267
268       assert json_response(conn, :forbidden)
269     end
270
271     test "no invites", %{conn: conn} do
272       conn = get(conn, "/api/pleroma/admin/users/invites")
273
274       assert json_response_and_validate_schema(conn, 200) == %{"invites" => []}
275     end
276
277     test "with invite", %{conn: conn} do
278       {:ok, invite} = UserInviteToken.create_invite()
279
280       conn = get(conn, "/api/pleroma/admin/users/invites")
281
282       assert json_response_and_validate_schema(conn, 200) == %{
283                "invites" => [
284                  %{
285                    "expires_at" => nil,
286                    "id" => invite.id,
287                    "invite_type" => "one_time",
288                    "max_use" => nil,
289                    "token" => invite.token,
290                    "used" => false,
291                    "uses" => 0
292                  }
293                ]
294              }
295     end
296   end
297
298   describe "POST /api/pleroma/admin/users/revoke_invite" do
299     setup do
300       clear_config([:instance, :admin_privileges], [:users_manage_invites])
301     end
302
303     test "returns 403 if not privileged with :users_manage_invites", %{conn: conn} do
304       clear_config([:instance, :admin_privileges], [])
305
306       conn =
307         conn
308         |> put_req_header("content-type", "application/json")
309         |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
310
311       assert json_response(conn, :forbidden)
312     end
313
314     test "with token", %{conn: conn} do
315       {:ok, invite} = UserInviteToken.create_invite()
316
317       conn =
318         conn
319         |> put_req_header("content-type", "application/json")
320         |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
321
322       assert json_response_and_validate_schema(conn, 200) == %{
323                "expires_at" => nil,
324                "id" => invite.id,
325                "invite_type" => "one_time",
326                "max_use" => nil,
327                "token" => invite.token,
328                "used" => true,
329                "uses" => 0
330              }
331     end
332
333     test "with invalid token", %{conn: conn} do
334       conn =
335         conn
336         |> put_req_header("content-type", "application/json")
337         |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
338
339       assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
340     end
341   end
342 end