total rebase
[anni] / lib / pleroma / web / mastodon_api / controllers / list_controller.ex
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.MastodonAPI.ListController do
6   use Pleroma.Web, :controller
7
8   alias Pleroma.User
9   alias Pleroma.Web.MastodonAPI.AccountView
10   alias Pleroma.Web.Plugs.OAuthScopesPlug
11
12   @oauth_read_actions [:index, :show, :list_accounts]
13
14   plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
15   plug(:list_by_id_and_user when action not in [:index, :create])
16   plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action in @oauth_read_actions)
17   plug(OAuthScopesPlug, %{scopes: ["write:lists"]} when action not in @oauth_read_actions)
18
19   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
20
21   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ListOperation
22
23   # GET /api/v1/lists
24   def index(%{assigns: %{user: user}, private: %{open_api_spex: %{params: params}}} = conn, _) do
25     lists = Pleroma.List.for_user(user, params)
26     render(conn, "index.json", lists: lists)
27   end
28
29   # POST /api/v1/lists
30   def create(
31         %{assigns: %{user: user}, private: %{open_api_spex: %{body_params: %{title: title}}}} =
32           conn,
33         _
34       ) do
35     with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do
36       render(conn, "show.json", list: list)
37     end
38   end
39
40   # GET /api/v1/lists/:idOB
41   def show(%{assigns: %{list: list}} = conn, _) do
42     render(conn, "show.json", list: list)
43   end
44
45   # PUT /api/v1/lists/:id
46   def update(
47         %{assigns: %{list: list}, private: %{open_api_spex: %{body_params: %{title: title}}}} =
48           conn,
49         _
50       ) do
51     with {:ok, list} <- Pleroma.List.rename(list, title) do
52       render(conn, "show.json", list: list)
53     end
54   end
55
56   # DELETE /api/v1/lists/:id
57   def delete(%{assigns: %{list: list}} = conn, _) do
58     with {:ok, _list} <- Pleroma.List.delete(list) do
59       json(conn, %{})
60     end
61   end
62
63   # GET /api/v1/lists/:id/accounts
64   def list_accounts(%{assigns: %{user: user, list: list}} = conn, _) do
65     with {:ok, users} <- Pleroma.List.get_following(list) do
66       conn
67       |> put_view(AccountView)
68       |> render("index.json", for: user, users: users, as: :user)
69     end
70   end
71
72   # POST /api/v1/lists/:id/accounts
73   def add_to_list(
74         %{
75           assigns: %{list: list},
76           private: %{open_api_spex: %{body_params: %{account_ids: account_ids}}}
77         } = conn,
78         _
79       ) do
80     Enum.each(account_ids, fn account_id ->
81       with %User{} = followed <- User.get_cached_by_id(account_id) do
82         Pleroma.List.follow(list, followed)
83       end
84     end)
85
86     json(conn, %{})
87   end
88
89   # DELETE /api/v1/lists/:id/accounts
90   def remove_from_list(
91         %{
92           private: %{open_api_spex: %{params: %{account_ids: account_ids}}}
93         } = conn,
94         _
95       ) do
96     do_remove_from_list(conn, account_ids)
97   end
98
99   def remove_from_list(
100         %{private: %{open_api_spex: %{body_params: %{account_ids: account_ids}}}} = conn,
101         _
102       ) do
103     do_remove_from_list(conn, account_ids)
104   end
105
106   defp do_remove_from_list(%{assigns: %{list: list}} = conn, account_ids) do
107     Enum.each(account_ids, fn account_id ->
108       with %User{} = followed <- User.get_cached_by_id(account_id) do
109         Pleroma.List.unfollow(list, followed)
110       end
111     end)
112
113     json(conn, %{})
114   end
115
116   defp list_by_id_and_user(
117          %{assigns: %{user: user}, private: %{open_api_spex: %{params: %{id: id}}}} = conn,
118          _
119        ) do
120     case Pleroma.List.get(id, user) do
121       %Pleroma.List{} = list -> assign(conn, :list, list)
122       nil -> conn |> render_error(:not_found, "List not found") |> halt()
123     end
124   end
125 end