Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
[akkoma] / lib / pleroma / web / pleroma_api / controllers / account_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.PleromaAPI.AccountController do
6 use Pleroma.Web, :controller
7
8 import Pleroma.Web.ControllerHelper,
9 only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
10
11 alias Ecto.Changeset
12 alias Pleroma.Plugs.RateLimiter
13 alias Pleroma.User
14 alias Pleroma.Web.ActivityPub.ActivityPub
15 alias Pleroma.Web.CommonAPI
16 alias Pleroma.Web.MastodonAPI.StatusView
17
18 require Pleroma.Constants
19
20 plug(RateLimiter, :account_confirmation_resend when action == :confirmation_resend)
21 plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
22 plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
23
24 @doc "POST /api/v1/pleroma/accounts/confirmation_resend"
25 def confirmation_resend(conn, params) do
26 nickname_or_email = params["email"] || params["nickname"]
27
28 with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
29 {:ok, _} <- User.try_send_confirmation_email(user) do
30 json_response(conn, :no_content, "")
31 end
32 end
33
34 @doc "PATCH /api/v1/pleroma/accounts/update_avatar"
35 def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
36 {:ok, user} =
37 user
38 |> Changeset.change(%{avatar: nil})
39 |> User.update_and_set_cache()
40
41 CommonAPI.update(user)
42
43 json(conn, %{url: nil})
44 end
45
46 def update_avatar(%{assigns: %{user: user}} = conn, params) do
47 {:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
48 {:ok, user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
49 %{"url" => [%{"href" => href} | _]} = data
50
51 CommonAPI.update(user)
52
53 json(conn, %{url: href})
54 end
55
56 @doc "PATCH /api/v1/pleroma/accounts/update_banner"
57 def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
58 new_info = %{"banner" => %{}}
59
60 with {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
61 CommonAPI.update(user)
62 json(conn, %{url: nil})
63 end
64 end
65
66 def update_banner(%{assigns: %{user: user}} = conn, params) do
67 with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
68 new_info <- %{"banner" => object.data},
69 {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
70 CommonAPI.update(user)
71 %{"url" => [%{"href" => href} | _]} = object.data
72
73 json(conn, %{url: href})
74 end
75 end
76
77 @doc "PATCH /api/v1/pleroma/accounts/update_background"
78 def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
79 new_info = %{"background" => %{}}
80
81 with {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
82 json(conn, %{url: nil})
83 end
84 end
85
86 def update_background(%{assigns: %{user: user}} = conn, params) do
87 with {:ok, object} <- ActivityPub.upload(params, type: :background),
88 new_info <- %{"background" => object.data},
89 {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
90 %{"url" => [%{"href" => href} | _]} = object.data
91
92 json(conn, %{url: href})
93 end
94 end
95
96 @doc "GET /api/v1/pleroma/accounts/:id/favourites"
97 def favourites(%{assigns: %{account: %{info: %{hide_favorites: true}}}} = conn, _params) do
98 render_error(conn, :forbidden, "Can't get favorites")
99 end
100
101 def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
102 params =
103 params
104 |> Map.put("type", "Create")
105 |> Map.put("favorited_by", user.ap_id)
106 |> Map.put("blocking_user", for_user)
107
108 recipients =
109 if for_user do
110 [Pleroma.Constants.as_public()] ++ [for_user.ap_id | for_user.following]
111 else
112 [Pleroma.Constants.as_public()]
113 end
114
115 activities =
116 recipients
117 |> ActivityPub.fetch_activities(params)
118 |> Enum.reverse()
119
120 conn
121 |> add_link_headers(activities)
122 |> put_view(StatusView)
123 |> render("index.json", activities: activities, for: for_user, as: :activity)
124 end
125
126 @doc "POST /api/v1/pleroma/accounts/:id/subscribe"
127 def subscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
128 with {:ok, subscription_target} <- User.subscribe(user, subscription_target) do
129 render(conn, "relationship.json", user: user, target: subscription_target)
130 else
131 {:error, message} -> json_response(conn, :forbidden, %{error: message})
132 end
133 end
134
135 @doc "POST /api/v1/pleroma/accounts/:id/unsubscribe"
136 def unsubscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
137 with {:ok, subscription_target} <- User.unsubscribe(user, subscription_target) do
138 render(conn, "relationship.json", user: user, target: subscription_target)
139 else
140 {:error, message} -> json_response(conn, :forbidden, %{error: message})
141 end
142 end
143 end