Merge branch 'stable' into mergeback/2.2.1
[akkoma] / test / pleroma / web / admin_api / controllers / invite_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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: true
7
8 import Pleroma.Factory
9
10 alias Pleroma.Config
11 alias Pleroma.Repo
12 alias Pleroma.UserInviteToken
13
14 setup do
15 admin = insert(:user, is_admin: true)
16 token = insert(:oauth_admin_token, user: admin)
17
18 conn =
19 build_conn()
20 |> assign(:user, admin)
21 |> assign(:token, token)
22
23 {:ok, %{admin: admin, token: token, conn: conn}}
24 end
25
26 describe "POST /api/pleroma/admin/users/email_invite, with valid config" do
27 setup do: clear_config([:instance, :registrations_open], false)
28 setup do: clear_config([:instance, :invites_enabled], true)
29
30 test "sends invitation and returns 204", %{admin: admin, conn: conn} do
31 recipient_email = "foo@bar.com"
32 recipient_name = "J. D."
33
34 conn =
35 conn
36 |> put_req_header("content-type", "application/json;charset=utf-8")
37 |> post("/api/pleroma/admin/users/email_invite", %{
38 email: recipient_email,
39 name: recipient_name
40 })
41
42 assert json_response_and_validate_schema(conn, :no_content)
43
44 token_record = List.last(Repo.all(Pleroma.UserInviteToken))
45 assert token_record
46 refute token_record.used
47
48 notify_email = Config.get([:instance, :notify_email])
49 instance_name = Config.get([:instance, :name])
50
51 email =
52 Pleroma.Emails.UserEmail.user_invitation_email(
53 admin,
54 token_record,
55 recipient_email,
56 recipient_name
57 )
58
59 Swoosh.TestAssertions.assert_email_sent(
60 from: {instance_name, notify_email},
61 to: {recipient_name, recipient_email},
62 html_body: email.html_body
63 )
64 end
65
66 test "it returns 403 if requested by a non-admin" do
67 non_admin_user = insert(:user)
68 token = insert(:oauth_token, user: non_admin_user)
69
70 conn =
71 build_conn()
72 |> assign(:user, non_admin_user)
73 |> assign(:token, token)
74 |> put_req_header("content-type", "application/json;charset=utf-8")
75 |> post("/api/pleroma/admin/users/email_invite", %{
76 email: "foo@bar.com",
77 name: "JD"
78 })
79
80 assert json_response(conn, :forbidden)
81 end
82
83 test "email with +", %{conn: conn, admin: admin} do
84 recipient_email = "foo+bar@baz.com"
85
86 conn
87 |> put_req_header("content-type", "application/json;charset=utf-8")
88 |> post("/api/pleroma/admin/users/email_invite", %{email: recipient_email})
89 |> json_response_and_validate_schema(:no_content)
90
91 token_record =
92 Pleroma.UserInviteToken
93 |> Repo.all()
94 |> List.last()
95
96 assert token_record
97 refute token_record.used
98
99 notify_email = Config.get([:instance, :notify_email])
100 instance_name = Config.get([:instance, :name])
101
102 email =
103 Pleroma.Emails.UserEmail.user_invitation_email(
104 admin,
105 token_record,
106 recipient_email
107 )
108
109 Swoosh.TestAssertions.assert_email_sent(
110 from: {instance_name, notify_email},
111 to: recipient_email,
112 html_body: email.html_body
113 )
114 end
115 end
116
117 describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
118 setup do: clear_config([:instance, :registrations_open])
119 setup do: clear_config([:instance, :invites_enabled])
120
121 test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
122 Config.put([:instance, :registrations_open], false)
123 Config.put([:instance, :invites_enabled], false)
124
125 conn =
126 conn
127 |> put_req_header("content-type", "application/json")
128 |> post("/api/pleroma/admin/users/email_invite", %{
129 email: "foo@bar.com",
130 name: "JD"
131 })
132
133 assert json_response_and_validate_schema(conn, :bad_request) ==
134 %{
135 "error" =>
136 "To send invites you need to set the `invites_enabled` option to true."
137 }
138 end
139
140 test "it returns 500 if `registrations_open` is enabled", %{conn: conn} do
141 Config.put([:instance, :registrations_open], true)
142 Config.put([:instance, :invites_enabled], true)
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 `registrations_open` option to false."
156 }
157 end
158 end
159
160 describe "POST /api/pleroma/admin/users/invite_token" do
161 test "without options", %{conn: conn} do
162 conn =
163 conn
164 |> put_req_header("content-type", "application/json")
165 |> post("/api/pleroma/admin/users/invite_token")
166
167 invite_json = json_response_and_validate_schema(conn, 200)
168 invite = UserInviteToken.find_by_token!(invite_json["token"])
169 refute invite.used
170 refute invite.expires_at
171 refute invite.max_use
172 assert invite.invite_type == "one_time"
173 end
174
175 test "with expires_at", %{conn: conn} do
176 conn =
177 conn
178 |> put_req_header("content-type", "application/json")
179 |> post("/api/pleroma/admin/users/invite_token", %{
180 "expires_at" => Date.to_string(Date.utc_today())
181 })
182
183 invite_json = json_response_and_validate_schema(conn, 200)
184 invite = UserInviteToken.find_by_token!(invite_json["token"])
185
186 refute invite.used
187 assert invite.expires_at == Date.utc_today()
188 refute invite.max_use
189 assert invite.invite_type == "date_limited"
190 end
191
192 test "with max_use", %{conn: conn} do
193 conn =
194 conn
195 |> put_req_header("content-type", "application/json")
196 |> post("/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
197
198 invite_json = json_response_and_validate_schema(conn, 200)
199 invite = UserInviteToken.find_by_token!(invite_json["token"])
200 refute invite.used
201 refute invite.expires_at
202 assert invite.max_use == 150
203 assert invite.invite_type == "reusable"
204 end
205
206 test "with max use and expires_at", %{conn: conn} do
207 conn =
208 conn
209 |> put_req_header("content-type", "application/json")
210 |> post("/api/pleroma/admin/users/invite_token", %{
211 "max_use" => 150,
212 "expires_at" => Date.to_string(Date.utc_today())
213 })
214
215 invite_json = json_response_and_validate_schema(conn, 200)
216 invite = UserInviteToken.find_by_token!(invite_json["token"])
217 refute invite.used
218 assert invite.expires_at == Date.utc_today()
219 assert invite.max_use == 150
220 assert invite.invite_type == "reusable_date_limited"
221 end
222 end
223
224 describe "GET /api/pleroma/admin/users/invites" do
225 test "no invites", %{conn: conn} do
226 conn = get(conn, "/api/pleroma/admin/users/invites")
227
228 assert json_response_and_validate_schema(conn, 200) == %{"invites" => []}
229 end
230
231 test "with invite", %{conn: conn} do
232 {:ok, invite} = UserInviteToken.create_invite()
233
234 conn = get(conn, "/api/pleroma/admin/users/invites")
235
236 assert json_response_and_validate_schema(conn, 200) == %{
237 "invites" => [
238 %{
239 "expires_at" => nil,
240 "id" => invite.id,
241 "invite_type" => "one_time",
242 "max_use" => nil,
243 "token" => invite.token,
244 "used" => false,
245 "uses" => 0
246 }
247 ]
248 }
249 end
250 end
251
252 describe "POST /api/pleroma/admin/users/revoke_invite" do
253 test "with token", %{conn: conn} do
254 {:ok, invite} = UserInviteToken.create_invite()
255
256 conn =
257 conn
258 |> put_req_header("content-type", "application/json")
259 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
260
261 assert json_response_and_validate_schema(conn, 200) == %{
262 "expires_at" => nil,
263 "id" => invite.id,
264 "invite_type" => "one_time",
265 "max_use" => nil,
266 "token" => invite.token,
267 "used" => true,
268 "uses" => 0
269 }
270 end
271
272 test "with invalid token", %{conn: conn} do
273 conn =
274 conn
275 |> put_req_header("content-type", "application/json")
276 |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
277
278 assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
279 end
280 end
281 end