Merge branch 'feature/confirm-user-acc-resend-confirmation' into 'develop'
[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.Activity
8 alias Pleroma.ModerationLog
9 alias Pleroma.Plugs.OAuthScopesPlug
10 alias Pleroma.User
11 alias Pleroma.UserInviteToken
12 alias Pleroma.Web.ActivityPub.ActivityPub
13 alias Pleroma.Web.ActivityPub.Relay
14 alias Pleroma.Web.ActivityPub.Utils
15 alias Pleroma.Web.AdminAPI.AccountView
16 alias Pleroma.Web.AdminAPI.Config
17 alias Pleroma.Web.AdminAPI.ConfigView
18 alias Pleroma.Web.AdminAPI.ModerationLogView
19 alias Pleroma.Web.AdminAPI.Report
20 alias Pleroma.Web.AdminAPI.ReportView
21 alias Pleroma.Web.AdminAPI.Search
22 alias Pleroma.Web.CommonAPI
23 alias Pleroma.Web.Endpoint
24 alias Pleroma.Web.MastodonAPI.StatusView
25 alias Pleroma.Web.Router
26
27 import Pleroma.Web.ControllerHelper, only: [json_response: 3]
28
29 require Logger
30
31 plug(
32 OAuthScopesPlug,
33 %{scopes: ["read:accounts"]}
34 when action in [:list_users, :user_show, :right_get, :invites]
35 )
36
37 plug(
38 OAuthScopesPlug,
39 %{scopes: ["write:accounts"]}
40 when action in [
41 :get_invite_token,
42 :revoke_invite,
43 :email_invite,
44 :get_password_reset,
45 :user_follow,
46 :user_unfollow,
47 :user_delete,
48 :users_create,
49 :user_toggle_activation,
50 :user_activate,
51 :user_deactivate,
52 :tag_users,
53 :untag_users,
54 :right_add,
55 :right_delete
56 ]
57 )
58
59 plug(
60 OAuthScopesPlug,
61 %{scopes: ["read:reports"]} when action in [:list_reports, :report_show]
62 )
63
64 plug(
65 OAuthScopesPlug,
66 %{scopes: ["write:reports"]}
67 when action in [:report_update_state, :report_respond]
68 )
69
70 plug(
71 OAuthScopesPlug,
72 %{scopes: ["read:statuses"]} when action == :list_user_statuses
73 )
74
75 plug(
76 OAuthScopesPlug,
77 %{scopes: ["write:statuses"]}
78 when action in [:status_update, :status_delete]
79 )
80
81 plug(
82 OAuthScopesPlug,
83 %{scopes: ["read"]}
84 when action in [:config_show, :migrate_to_db, :migrate_from_db, :list_log]
85 )
86
87 plug(
88 OAuthScopesPlug,
89 %{scopes: ["write"]}
90 when action in [:relay_follow, :relay_unfollow, :config_update]
91 )
92
93 @users_page_size 50
94
95 action_fallback(:errors)
96
97 def user_delete(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
98 user = User.get_cached_by_nickname(nickname)
99 User.delete(user)
100
101 ModerationLog.insert_log(%{
102 actor: admin,
103 subject: [user],
104 action: "delete"
105 })
106
107 conn
108 |> json(nickname)
109 end
110
111 def user_delete(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
112 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
113 User.delete(users)
114
115 ModerationLog.insert_log(%{
116 actor: admin,
117 subject: users,
118 action: "delete"
119 })
120
121 conn
122 |> json(nicknames)
123 end
124
125 def user_follow(%{assigns: %{user: admin}} = conn, %{
126 "follower" => follower_nick,
127 "followed" => followed_nick
128 }) do
129 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
130 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
131 User.follow(follower, followed)
132
133 ModerationLog.insert_log(%{
134 actor: admin,
135 followed: followed,
136 follower: follower,
137 action: "follow"
138 })
139 end
140
141 conn
142 |> json("ok")
143 end
144
145 def user_unfollow(%{assigns: %{user: admin}} = conn, %{
146 "follower" => follower_nick,
147 "followed" => followed_nick
148 }) do
149 with %User{} = follower <- User.get_cached_by_nickname(follower_nick),
150 %User{} = followed <- User.get_cached_by_nickname(followed_nick) do
151 User.unfollow(follower, followed)
152
153 ModerationLog.insert_log(%{
154 actor: admin,
155 followed: followed,
156 follower: follower,
157 action: "unfollow"
158 })
159 end
160
161 conn
162 |> json("ok")
163 end
164
165 def users_create(%{assigns: %{user: admin}} = conn, %{"users" => users}) do
166 changesets =
167 Enum.map(users, fn %{"nickname" => nickname, "email" => email, "password" => password} ->
168 user_data = %{
169 nickname: nickname,
170 name: nickname,
171 email: email,
172 password: password,
173 password_confirmation: password,
174 bio: "."
175 }
176
177 User.register_changeset(%User{}, user_data, need_confirmation: false)
178 end)
179 |> Enum.reduce(Ecto.Multi.new(), fn changeset, multi ->
180 Ecto.Multi.insert(multi, Ecto.UUID.generate(), changeset)
181 end)
182
183 case Pleroma.Repo.transaction(changesets) do
184 {:ok, users} ->
185 res =
186 users
187 |> Map.values()
188 |> Enum.map(fn user ->
189 {:ok, user} = User.post_register_action(user)
190
191 user
192 end)
193 |> Enum.map(&AccountView.render("created.json", %{user: &1}))
194
195 ModerationLog.insert_log(%{
196 actor: admin,
197 subjects: Map.values(users),
198 action: "create"
199 })
200
201 conn
202 |> json(res)
203
204 {:error, id, changeset, _} ->
205 res =
206 Enum.map(changesets.operations, fn
207 {current_id, {:changeset, _current_changeset, _}} when current_id == id ->
208 AccountView.render("create-error.json", %{changeset: changeset})
209
210 {_, {:changeset, current_changeset, _}} ->
211 AccountView.render("create-error.json", %{changeset: current_changeset})
212 end)
213
214 conn
215 |> put_status(:conflict)
216 |> json(res)
217 end
218 end
219
220 def user_show(conn, %{"nickname" => nickname}) do
221 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
222 conn
223 |> put_view(AccountView)
224 |> render("show.json", %{user: user})
225 else
226 _ -> {:error, :not_found}
227 end
228 end
229
230 def list_user_statuses(conn, %{"nickname" => nickname} = params) do
231 godmode = params["godmode"] == "true" || params["godmode"] == true
232
233 with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do
234 {_, page_size} = page_params(params)
235
236 activities =
237 ActivityPub.fetch_user_activities(user, nil, %{
238 "limit" => page_size,
239 "godmode" => godmode
240 })
241
242 conn
243 |> put_view(StatusView)
244 |> render("index.json", %{activities: activities, as: :activity})
245 else
246 _ -> {:error, :not_found}
247 end
248 end
249
250 def user_toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
251 user = User.get_cached_by_nickname(nickname)
252
253 {:ok, updated_user} = User.deactivate(user, !user.deactivated)
254
255 action = if user.deactivated, do: "activate", else: "deactivate"
256
257 ModerationLog.insert_log(%{
258 actor: admin,
259 subject: [user],
260 action: action
261 })
262
263 conn
264 |> put_view(AccountView)
265 |> render("show.json", %{user: updated_user})
266 end
267
268 def user_activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
269 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
270 {:ok, updated_users} = User.deactivate(users, false)
271
272 ModerationLog.insert_log(%{
273 actor: admin,
274 subject: users,
275 action: "activate"
276 })
277
278 conn
279 |> put_view(AccountView)
280 |> render("index.json", %{users: Keyword.values(updated_users)})
281 end
282
283 def user_deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
284 users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
285 {:ok, updated_users} = User.deactivate(users, true)
286
287 ModerationLog.insert_log(%{
288 actor: admin,
289 subject: users,
290 action: "deactivate"
291 })
292
293 conn
294 |> put_view(AccountView)
295 |> render("index.json", %{users: Keyword.values(updated_users)})
296 end
297
298 def tag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
299 with {:ok, _} <- User.tag(nicknames, tags) do
300 ModerationLog.insert_log(%{
301 actor: admin,
302 nicknames: nicknames,
303 tags: tags,
304 action: "tag"
305 })
306
307 json_response(conn, :no_content, "")
308 end
309 end
310
311 def untag_users(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames, "tags" => tags}) do
312 with {:ok, _} <- User.untag(nicknames, tags) do
313 ModerationLog.insert_log(%{
314 actor: admin,
315 nicknames: nicknames,
316 tags: tags,
317 action: "untag"
318 })
319
320 json_response(conn, :no_content, "")
321 end
322 end
323
324 def list_users(conn, params) do
325 {page, page_size} = page_params(params)
326 filters = maybe_parse_filters(params["filters"])
327
328 search_params = %{
329 query: params["query"],
330 page: page,
331 page_size: page_size,
332 tags: params["tags"],
333 name: params["name"],
334 email: params["email"]
335 }
336
337 with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
338 {:ok, users, count} <- filter_service_users(users, count),
339 do:
340 conn
341 |> json(
342 AccountView.render("index.json",
343 users: users,
344 count: count,
345 page_size: page_size
346 )
347 )
348 end
349
350 defp filter_service_users(users, count) do
351 filtered_users = Enum.reject(users, &service_user?/1)
352 count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count
353
354 {:ok, filtered_users, count}
355 end
356
357 defp service_user?(user) do
358 String.match?(user.ap_id, ~r/.*\/relay$/) or
359 String.match?(user.ap_id, ~r/.*\/internal\/fetch$/)
360 end
361
362 @filters ~w(local external active deactivated is_admin is_moderator)
363
364 @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
365 defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
366
367 defp maybe_parse_filters(filters) do
368 filters
369 |> String.split(",")
370 |> Enum.filter(&Enum.member?(@filters, &1))
371 |> Enum.map(&String.to_atom(&1))
372 |> Enum.into(%{}, &{&1, true})
373 end
374
375 def right_add_multiple(%{assigns: %{user: admin}} = conn, %{
376 "permission_group" => permission_group,
377 "nicknames" => nicknames
378 })
379 when permission_group in ["moderator", "admin"] do
380 update = %{:"is_#{permission_group}" => true}
381
382 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
383
384 for u <- users, do: User.admin_api_update(u, update)
385
386 ModerationLog.insert_log(%{
387 action: "grant",
388 actor: admin,
389 subject: users,
390 permission: permission_group
391 })
392
393 json(conn, update)
394 end
395
396 def right_add_multiple(conn, _) do
397 render_error(conn, :not_found, "No such permission_group")
398 end
399
400 def right_add(%{assigns: %{user: admin}} = conn, %{
401 "permission_group" => permission_group,
402 "nickname" => nickname
403 })
404 when permission_group in ["moderator", "admin"] do
405 fields = %{:"is_#{permission_group}" => true}
406
407 {:ok, user} =
408 nickname
409 |> User.get_cached_by_nickname()
410 |> User.admin_api_update(fields)
411
412 ModerationLog.insert_log(%{
413 action: "grant",
414 actor: admin,
415 subject: [user],
416 permission: permission_group
417 })
418
419 json(conn, fields)
420 end
421
422 def right_add(conn, _) do
423 render_error(conn, :not_found, "No such permission_group")
424 end
425
426 def right_get(conn, %{"nickname" => nickname}) do
427 user = User.get_cached_by_nickname(nickname)
428
429 conn
430 |> json(%{
431 is_moderator: user.is_moderator,
432 is_admin: user.is_admin
433 })
434 end
435
436 def right_delete_multiple(
437 %{assigns: %{user: %{nickname: admin_nickname} = admin}} = conn,
438 %{
439 "permission_group" => permission_group,
440 "nicknames" => nicknames
441 }
442 )
443 when permission_group in ["moderator", "admin"] do
444 with false <- Enum.member?(nicknames, admin_nickname) do
445 update = %{:"is_#{permission_group}" => false}
446
447 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
448
449 for u <- users, do: User.admin_api_update(u, update)
450
451 ModerationLog.insert_log(%{
452 action: "revoke",
453 actor: admin,
454 subject: users,
455 permission: permission_group
456 })
457
458 json(conn, update)
459 else
460 _ -> render_error(conn, :forbidden, "You can't revoke your own admin/moderator status.")
461 end
462 end
463
464 def right_delete_multiple(conn, _) do
465 render_error(conn, :not_found, "No such permission_group")
466 end
467
468 def right_delete(
469 %{assigns: %{user: admin}} = conn,
470 %{
471 "permission_group" => permission_group,
472 "nickname" => nickname
473 }
474 )
475 when permission_group in ["moderator", "admin"] do
476 fields = %{:"is_#{permission_group}" => false}
477
478 {:ok, user} =
479 nickname
480 |> User.get_cached_by_nickname()
481 |> User.admin_api_update(fields)
482
483 ModerationLog.insert_log(%{
484 action: "revoke",
485 actor: admin,
486 subject: [user],
487 permission: permission_group
488 })
489
490 json(conn, fields)
491 end
492
493 def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
494 render_error(conn, :forbidden, "You can't revoke your own admin status.")
495 end
496
497 def relay_list(conn, _params) do
498 with {:ok, list} <- Relay.list() do
499 json(conn, %{relays: list})
500 else
501 _ ->
502 conn
503 |> put_status(500)
504 end
505 end
506
507 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
508 with {:ok, _message} <- Relay.follow(target) do
509 ModerationLog.insert_log(%{
510 action: "relay_follow",
511 actor: admin,
512 target: target
513 })
514
515 json(conn, target)
516 else
517 _ ->
518 conn
519 |> put_status(500)
520 |> json(target)
521 end
522 end
523
524 def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
525 with {:ok, _message} <- Relay.unfollow(target) do
526 ModerationLog.insert_log(%{
527 action: "relay_unfollow",
528 actor: admin,
529 target: target
530 })
531
532 json(conn, target)
533 else
534 _ ->
535 conn
536 |> put_status(500)
537 |> json(target)
538 end
539 end
540
541 @doc "Sends registration invite via email"
542 def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
543 with true <-
544 Pleroma.Config.get([:instance, :invites_enabled]) &&
545 !Pleroma.Config.get([:instance, :registrations_open]),
546 {:ok, invite_token} <- UserInviteToken.create_invite(),
547 email <-
548 Pleroma.Emails.UserEmail.user_invitation_email(
549 user,
550 invite_token,
551 email,
552 params["name"]
553 ),
554 {:ok, _} <- Pleroma.Emails.Mailer.deliver(email) do
555 json_response(conn, :no_content, "")
556 end
557 end
558
559 @doc "Create an account registration invite token"
560 def create_invite_token(conn, params) do
561 opts = %{}
562
563 opts =
564 if params["max_use"],
565 do: Map.put(opts, :max_use, params["max_use"]),
566 else: opts
567
568 opts =
569 if params["expires_at"],
570 do: Map.put(opts, :expires_at, params["expires_at"]),
571 else: opts
572
573 {:ok, invite} = UserInviteToken.create_invite(opts)
574
575 json(conn, AccountView.render("invite.json", %{invite: invite}))
576 end
577
578 @doc "Get list of created invites"
579 def invites(conn, _params) do
580 invites = UserInviteToken.list_invites()
581
582 conn
583 |> put_view(AccountView)
584 |> render("invites.json", %{invites: invites})
585 end
586
587 @doc "Revokes invite by token"
588 def revoke_invite(conn, %{"token" => token}) do
589 with {:ok, invite} <- UserInviteToken.find_by_token(token),
590 {:ok, updated_invite} = UserInviteToken.update_invite(invite, %{used: true}) do
591 conn
592 |> put_view(AccountView)
593 |> render("invite.json", %{invite: updated_invite})
594 else
595 nil -> {:error, :not_found}
596 end
597 end
598
599 @doc "Get a password reset token (base64 string) for given nickname"
600 def get_password_reset(conn, %{"nickname" => nickname}) do
601 (%User{local: true} = user) = User.get_cached_by_nickname(nickname)
602 {:ok, token} = Pleroma.PasswordResetToken.create_token(user)
603
604 conn
605 |> json(%{
606 token: token.token,
607 link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
608 })
609 end
610
611 @doc "Force password reset for a given user"
612 def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
613 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
614
615 Enum.map(users, &User.force_password_reset_async/1)
616
617 ModerationLog.insert_log(%{
618 actor: admin,
619 subject: users,
620 action: "force_password_reset"
621 })
622
623 json_response(conn, :no_content, "")
624 end
625
626 def list_reports(conn, params) do
627 {page, page_size} = page_params(params)
628
629 conn
630 |> put_view(ReportView)
631 |> render("index.json", %{reports: Utils.get_reports(params, page, page_size)})
632 end
633
634 def list_grouped_reports(conn, _params) do
635 reports = Utils.get_reported_activities()
636
637 conn
638 |> put_view(ReportView)
639 |> render("index_grouped.json", Utils.get_reports_grouped_by_status(reports))
640 end
641
642 def report_show(conn, %{"id" => id}) do
643 with %Activity{} = report <- Activity.get_by_id(id) do
644 conn
645 |> put_view(ReportView)
646 |> render("show.json", Report.extract_report_info(report))
647 else
648 _ -> {:error, :not_found}
649 end
650 end
651
652 def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
653 result =
654 reports
655 |> Enum.map(fn report ->
656 with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
657 ModerationLog.insert_log(%{
658 action: "report_update",
659 actor: admin,
660 subject: activity
661 })
662
663 activity
664 else
665 {:error, message} -> %{id: report["id"], error: message}
666 end
667 end)
668
669 case Enum.any?(result, &Map.has_key?(&1, :error)) do
670 true -> json_response(conn, :bad_request, result)
671 false -> json_response(conn, :no_content, "")
672 end
673 end
674
675 def report_respond(%{assigns: %{user: user}} = conn, %{"id" => id} = params) do
676 with false <- is_nil(params["status"]),
677 %Activity{} <- Activity.get_by_id(id) do
678 params =
679 params
680 |> Map.put("in_reply_to_status_id", id)
681 |> Map.put("visibility", "direct")
682
683 {:ok, activity} = CommonAPI.post(user, params)
684
685 ModerationLog.insert_log(%{
686 action: "report_response",
687 actor: user,
688 subject: activity,
689 text: params["status"]
690 })
691
692 conn
693 |> put_view(StatusView)
694 |> render("show.json", %{activity: activity})
695 else
696 true ->
697 {:param_cast, nil}
698
699 nil ->
700 {:error, :not_found}
701 end
702 end
703
704 def status_update(%{assigns: %{user: admin}} = conn, %{"id" => id} = params) do
705 with {:ok, activity} <- CommonAPI.update_activity_scope(id, params) do
706 {:ok, sensitive} = Ecto.Type.cast(:boolean, params["sensitive"])
707
708 ModerationLog.insert_log(%{
709 action: "status_update",
710 actor: admin,
711 subject: activity,
712 sensitive: sensitive,
713 visibility: params["visibility"]
714 })
715
716 conn
717 |> put_view(StatusView)
718 |> render("show.json", %{activity: activity})
719 end
720 end
721
722 def status_delete(%{assigns: %{user: user}} = conn, %{"id" => id}) do
723 with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do
724 ModerationLog.insert_log(%{
725 action: "status_delete",
726 actor: user,
727 subject_id: id
728 })
729
730 json(conn, %{})
731 end
732 end
733
734 def list_log(conn, params) do
735 {page, page_size} = page_params(params)
736
737 log =
738 ModerationLog.get_all(%{
739 page: page,
740 page_size: page_size,
741 start_date: params["start_date"],
742 end_date: params["end_date"],
743 user_id: params["user_id"],
744 search: params["search"]
745 })
746
747 conn
748 |> put_view(ModerationLogView)
749 |> render("index.json", %{log: log})
750 end
751
752 def migrate_to_db(conn, _params) do
753 Mix.Tasks.Pleroma.Config.run(["migrate_to_db"])
754 json(conn, %{})
755 end
756
757 def migrate_from_db(conn, _params) do
758 Mix.Tasks.Pleroma.Config.run(["migrate_from_db", Pleroma.Config.get(:env), "true"])
759 json(conn, %{})
760 end
761
762 def config_show(conn, _params) do
763 configs = Pleroma.Repo.all(Config)
764
765 conn
766 |> put_view(ConfigView)
767 |> render("index.json", %{configs: configs})
768 end
769
770 def config_update(conn, %{"configs" => configs}) do
771 updated =
772 if Pleroma.Config.get([:instance, :dynamic_configuration]) do
773 updated =
774 Enum.map(configs, fn
775 %{"group" => group, "key" => key, "delete" => "true"} = params ->
776 {:ok, config} = Config.delete(%{group: group, key: key, subkeys: params["subkeys"]})
777 config
778
779 %{"group" => group, "key" => key, "value" => value} ->
780 {:ok, config} = Config.update_or_create(%{group: group, key: key, value: value})
781 config
782 end)
783 |> Enum.reject(&is_nil(&1))
784
785 Pleroma.Config.TransferTask.load_and_update_env()
786 Mix.Tasks.Pleroma.Config.run(["migrate_from_db", Pleroma.Config.get(:env), "false"])
787 updated
788 else
789 []
790 end
791
792 conn
793 |> put_view(ConfigView)
794 |> render("index.json", %{configs: updated})
795 end
796
797 def reload_emoji(conn, _params) do
798 Pleroma.Emoji.reload()
799
800 conn |> json("ok")
801 end
802
803 def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
804 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
805
806 User.toggle_confirmation(users)
807
808 ModerationLog.insert_log(%{
809 actor: admin,
810 subject: users,
811 action: "confirm_email"
812 })
813
814 conn |> json("")
815 end
816
817 def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
818 users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
819
820 User.try_send_confirmation_email(users)
821
822 ModerationLog.insert_log(%{
823 actor: admin,
824 subject: users,
825 action: "resend_confirmation_email"
826 })
827
828 conn |> json("")
829 end
830
831 def errors(conn, {:error, :not_found}) do
832 conn
833 |> put_status(:not_found)
834 |> json(dgettext("errors", "Not found"))
835 end
836
837 def errors(conn, {:error, reason}) do
838 conn
839 |> put_status(:bad_request)
840 |> json(reason)
841 end
842
843 def errors(conn, {:param_cast, _}) do
844 conn
845 |> put_status(:bad_request)
846 |> json(dgettext("errors", "Invalid parameters"))
847 end
848
849 def errors(conn, _) do
850 conn
851 |> put_status(:internal_server_error)
852 |> json(dgettext("errors", "Something went wrong"))
853 end
854
855 defp page_params(params) do
856 {get_page(params["page"]), get_page_size(params["page_size"])}
857 end
858
859 defp get_page(page_string) when is_nil(page_string), do: 1
860
861 defp get_page(page_string) do
862 case Integer.parse(page_string) do
863 {page, _} -> page
864 :error -> 1
865 end
866 end
867
868 defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
869
870 defp get_page_size(page_size_string) do
871 case Integer.parse(page_size_string) do
872 {page_size, _} -> page_size
873 :error -> @users_page_size
874 end
875 end
876 end