Merge develop into feature/770-add-emoji-tags
[akkoma] / lib / pleroma / web / admin_api / admin_api_controller.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.AdminAPI.AdminAPIController do
6 use Pleroma.Web, :controller
7 alias Pleroma.User
8 alias Pleroma.Web.ActivityPub.Relay
9 alias Pleroma.Web.AdminAPI.AccountView
10 alias Pleroma.Web.AdminAPI.Search
11
12 import Pleroma.Web.ControllerHelper, only: [json_response: 3]
13
14 require Logger
15
16 @users_page_size 50
17
18 action_fallback(:errors)
19
20 def user_delete(conn, %{"nickname" => nickname}) do
21 User.get_by_nickname(nickname)
22 |> User.delete()
23
24 conn
25 |> json(nickname)
26 end
27
28 def user_create(
29 conn,
30 %{"nickname" => nickname, "email" => email, "password" => password}
31 ) do
32 user_data = %{
33 nickname: nickname,
34 name: nickname,
35 email: email,
36 password: password,
37 password_confirmation: password,
38 bio: "."
39 }
40
41 changeset = User.register_changeset(%User{}, user_data, confirmed: true)
42 {:ok, user} = User.register(changeset)
43
44 conn
45 |> json(user.nickname)
46 end
47
48 def user_show(conn, %{"nickname" => nickname}) do
49 with %User{} = user <- User.get_by_nickname(nickname) do
50 conn
51 |> json(AccountView.render("show.json", %{user: user}))
52 else
53 _ -> {:error, :not_found}
54 end
55 end
56
57 def user_toggle_activation(conn, %{"nickname" => nickname}) do
58 user = User.get_by_nickname(nickname)
59
60 {:ok, updated_user} = User.deactivate(user, !user.info.deactivated)
61
62 conn
63 |> json(AccountView.render("show.json", %{user: updated_user}))
64 end
65
66 def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
67 with {:ok, _} <- User.tag(nicknames, tags),
68 do: json_response(conn, :no_content, "")
69 end
70
71 def untag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do
72 with {:ok, _} <- User.untag(nicknames, tags),
73 do: json_response(conn, :no_content, "")
74 end
75
76 def list_users(conn, params) do
77 {page, page_size} = page_params(params)
78 filters = maybe_parse_filters(params["filters"])
79
80 search_params = %{
81 query: params["query"],
82 page: page,
83 page_size: page_size
84 }
85
86 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
87 do:
88 conn
89 |> json(
90 AccountView.render("index.json",
91 users: users,
92 count: count,
93 page_size: page_size
94 )
95 )
96 end
97
98 @filters ~w(local external active deactivated)
99
100 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
101
102 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
103 defp maybe_parse_filters(filters) do
104 filters
105 |> String.split(",")
106 |> Enum.filter(&Enum.member?(@filters, &1))
107 |> Enum.map(&String.to_atom(&1))
108 |> Enum.into(%{}, &{&1, true})
109 end
110
111 def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})
112 when permission_group in ["moderator", "admin"] do
113 user = User.get_by_nickname(nickname)
114
115 info =
116 %{}
117 |> Map.put("is_" <> permission_group, true)
118
119 info_cng = User.Info.admin_api_update(user.info, info)
120
121 cng =
122 user
123 |> Ecto.Changeset.change()
124 |> Ecto.Changeset.put_embed(:info, info_cng)
125
126 {:ok, _user} = User.update_and_set_cache(cng)
127
128 json(conn, info)
129 end
130
131 def right_add(conn, _) do
132 conn
133 |> put_status(404)
134 |> json(%{error: "No such permission_group"})
135 end
136
137 def right_get(conn, %{"nickname" => nickname}) do
138 user = User.get_by_nickname(nickname)
139
140 conn
141 |> json(%{
142 is_moderator: user.info.is_moderator,
143 is_admin: user.info.is_admin
144 })
145 end
146
147 def right_delete(
148 %{assigns: %{user: %User{:nickname => admin_nickname}}} = conn,
149 %{
150 "permission_group" => permission_group,
151 "nickname" => nickname
152 }
153 )
154 when permission_group in ["moderator", "admin"] do
155 if admin_nickname == nickname do
156 conn
157 |> put_status(403)
158 |> json(%{error: "You can't revoke your own admin status."})
159 else
160 user = User.get_by_nickname(nickname)
161
162 info =
163 %{}
164 |> Map.put("is_" <> permission_group, false)
165
166 info_cng = User.Info.admin_api_update(user.info, info)
167
168 cng =
169 Ecto.Changeset.change(user)
170 |> Ecto.Changeset.put_embed(:info, info_cng)
171
172 {:ok, _user} = User.update_and_set_cache(cng)
173
174 json(conn, info)
175 end
176 end
177
178 def right_delete(conn, _) do
179 conn
180 |> put_status(404)
181 |> json(%{error: "No such permission_group"})
182 end
183
184 def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do
185 with {:ok, status} <- Ecto.Type.cast(:boolean, status),
186 %User{} = user <- User.get_by_nickname(nickname),
187 {:ok, _} <- User.deactivate(user, !status),
188 do: json_response(conn, :no_content, "")
189 end
190
191 def relay_follow(conn, %{"relay_url" => target}) do
192 with {:ok, _message} <- Relay.follow(target) do
193 json(conn, target)
194 else
195 _ ->
196 conn
197 |> put_status(500)
198 |> json(target)
199 end
200 end
201
202 def relay_unfollow(conn, %{"relay_url" => target}) do
203 with {:ok, _message} <- Relay.unfollow(target) do
204 json(conn, target)
205 else
206 _ ->
207 conn
208 |> put_status(500)
209 |> json(target)
210 end
211 end
212
213 @doc "Sends registration invite via email"
214 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
215 with true <-
216 Pleroma.Config.get([:instance, :invites_enabled]) &&
217 !Pleroma.Config.get([:instance, :registrations_open]),
218 {:ok, invite_token} <- Pleroma.UserInviteToken.create_token(),
219 email <-
220 Pleroma.UserEmail.user_invitation_email(user, invite_token, email, params["name"]),
221 {:ok, _} <- Pleroma.Mailer.deliver(email) do
222 json_response(conn, :no_content, "")
223 end
224 end
225
226 @doc "Get a account registeration invite token (base64 string)"
227 def get_invite_token(conn, _params) do
228 {:ok, token} = Pleroma.UserInviteToken.create_token()
229
230 conn
231 |> json(token.token)
232 end
233
234 @doc "Get a password reset token (base64 string) for given nickname"
235 def get_password_reset(conn, %{"nickname" => nickname}) do
236 (%User{local: true} = user) = User.get_by_nickname(nickname)
237 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
238
239 conn
240 |> json(token.token)
241 end
242
243 def errors(conn, {:error, :not_found}) do
244 conn
245 |> put_status(404)
246 |> json("Not found")
247 end
248
249 def errors(conn, {:param_cast, _}) do
250 conn
251 |> put_status(400)
252 |> json("Invalid parameters")
253 end
254
255 def errors(conn, _) do
256 conn
257 |> put_status(500)
258 |> json("Something went wrong")
259 end
260
261 defp page_params(params) do
262 {get_page(params["page"]), get_page_size(params["page_size"])}
263 end
264
265 defp get_page(page_string) when is_nil(page_string), do: 1
266
267 defp get_page(page_string) do
268 case Integer.parse(page_string) do
269 {page, _} -> page
270 :error -> 1
271 end
272 end
273
274 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
275
276 defp get_page_size(page_size_string) do
277 case Integer.parse(page_size_string) do
278 {page_size, _} -> page_size
279 :error -> @users_page_size
280 end
281 end
282 end