a66335c0227f841499703d12c03dcc59986ccce2
[akkoma] / lib / pleroma / web / mastodon_api / controllers / mastodon_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.MastodonAPI.MastodonAPIController do
6 use Pleroma.Web, :controller
7
8 import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
9
10 alias Pleroma.Bookmark
11 alias Pleroma.Config
12 alias Pleroma.Pagination
13 alias Pleroma.User
14 alias Pleroma.Web.ActivityPub.ActivityPub
15 alias Pleroma.Web.CommonAPI
16 alias Pleroma.Web.MastodonAPI.AccountView
17 alias Pleroma.Web.MastodonAPI.MastodonView
18 alias Pleroma.Web.MastodonAPI.StatusView
19
20 require Logger
21
22 action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
23
24 def follows(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
25 with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)},
26 {_, true} <- {:followed, follower.id != followed.id},
27 {:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do
28 conn
29 |> put_view(AccountView)
30 |> render("show.json", %{user: followed, for: follower})
31 else
32 {:followed, _} ->
33 {:error, :not_found}
34
35 {:error, message} ->
36 conn
37 |> put_status(:forbidden)
38 |> json(%{error: message})
39 end
40 end
41
42 def mutes(%{assigns: %{user: user}} = conn, _) do
43 with muted_accounts <- User.muted_users(user) do
44 res = AccountView.render("index.json", users: muted_accounts, for: user, as: :user)
45 json(conn, res)
46 end
47 end
48
49 def blocks(%{assigns: %{user: user}} = conn, _) do
50 with blocked_accounts <- User.blocked_users(user) do
51 res = AccountView.render("index.json", users: blocked_accounts, for: user, as: :user)
52 json(conn, res)
53 end
54 end
55
56 def favourites(%{assigns: %{user: user}} = conn, params) do
57 params =
58 params
59 |> Map.put("type", "Create")
60 |> Map.put("favorited_by", user.ap_id)
61 |> Map.put("blocking_user", user)
62
63 activities =
64 ActivityPub.fetch_activities([], params)
65 |> Enum.reverse()
66
67 conn
68 |> add_link_headers(activities)
69 |> put_view(StatusView)
70 |> render("index.json", %{activities: activities, for: user, as: :activity})
71 end
72
73 def bookmarks(%{assigns: %{user: user}} = conn, params) do
74 user = User.get_cached_by_id(user.id)
75
76 bookmarks =
77 Bookmark.for_user_query(user.id)
78 |> Pagination.fetch_paginated(params)
79
80 activities =
81 bookmarks
82 |> Enum.map(fn b -> Map.put(b.activity, :bookmark, Map.delete(b, :activity)) end)
83
84 conn
85 |> add_link_headers(bookmarks)
86 |> put_view(StatusView)
87 |> render("index.json", %{activities: activities, for: user, as: :activity})
88 end
89
90 def index(%{assigns: %{user: user}} = conn, _params) do
91 token = get_session(conn, :oauth_token)
92
93 if user && token do
94 mastodon_emoji =
95 Pleroma.Web.MastodonAPI.CustomEmojiView.render("index.json", %{
96 custom_emojis: Pleroma.Emoji.get_all()
97 })
98
99 limit = Config.get([:instance, :limit])
100
101 accounts = Map.put(%{}, user.id, AccountView.render("show.json", %{user: user, for: user}))
102
103 initial_state =
104 %{
105 meta: %{
106 streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
107 access_token: token,
108 locale: "en",
109 domain: Pleroma.Web.Endpoint.host(),
110 admin: "1",
111 me: "#{user.id}",
112 unfollow_modal: false,
113 boost_modal: false,
114 delete_modal: true,
115 auto_play_gif: false,
116 display_sensitive_media: false,
117 reduce_motion: false,
118 max_toot_chars: limit,
119 mascot: User.get_mascot(user)["url"]
120 },
121 poll_limits: Config.get([:instance, :poll_limits]),
122 rights: %{
123 delete_others_notice: present?(user.info.is_moderator),
124 admin: present?(user.info.is_admin)
125 },
126 compose: %{
127 me: "#{user.id}",
128 default_privacy: user.info.default_scope,
129 default_sensitive: false,
130 allow_content_types: Config.get([:instance, :allowed_post_formats])
131 },
132 media_attachments: %{
133 accept_content_types: [
134 ".jpg",
135 ".jpeg",
136 ".png",
137 ".gif",
138 ".webm",
139 ".mp4",
140 ".m4v",
141 "image\/jpeg",
142 "image\/png",
143 "image\/gif",
144 "video\/webm",
145 "video\/mp4"
146 ]
147 },
148 settings:
149 user.info.settings ||
150 %{
151 onboarded: true,
152 home: %{
153 shows: %{
154 reblog: true,
155 reply: true
156 }
157 },
158 notifications: %{
159 alerts: %{
160 follow: true,
161 favourite: true,
162 reblog: true,
163 mention: true
164 },
165 shows: %{
166 follow: true,
167 favourite: true,
168 reblog: true,
169 mention: true
170 },
171 sounds: %{
172 follow: true,
173 favourite: true,
174 reblog: true,
175 mention: true
176 }
177 }
178 },
179 push_subscription: nil,
180 accounts: accounts,
181 custom_emojis: mastodon_emoji,
182 char_limit: limit
183 }
184 |> Jason.encode!()
185
186 conn
187 |> put_layout(false)
188 |> put_view(MastodonView)
189 |> render("index.html", %{initial_state: initial_state})
190 else
191 conn
192 |> put_session(:return_to, conn.request_path)
193 |> redirect(to: "/web/login")
194 end
195 end
196
197 def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
198 with {:ok, _} <- User.update_info(user, &User.Info.mastodon_settings_update(&1, settings)) do
199 json(conn, %{})
200 else
201 e ->
202 conn
203 |> put_status(:internal_server_error)
204 |> json(%{error: inspect(e)})
205 end
206 end
207
208 # Stubs for unimplemented mastodon api
209 #
210 def empty_array(conn, _) do
211 Logger.debug("Unimplemented, returning an empty array")
212 json(conn, [])
213 end
214
215 def empty_object(conn, _) do
216 Logger.debug("Unimplemented, returning an empty object")
217 json(conn, %{})
218 end
219
220 defp present?(nil), do: false
221 defp present?(false), do: false
222 defp present?(_), do: true
223 end