First
[anni] / lib / pleroma / web / pleroma_api / controllers / account_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.PleromaAPI.AccountController do
6   use Pleroma.Web, :controller
7
8   import Pleroma.Web.ControllerHelper,
9     only: [
10       json_response: 3,
11       add_link_headers: 2,
12       embed_relationships?: 1,
13       assign_account_by_id: 2
14     ]
15
16   alias Pleroma.User
17   alias Pleroma.Web.ActivityPub.ActivityPub
18   alias Pleroma.Web.MastodonAPI.StatusView
19   alias Pleroma.Web.Plugs.OAuthScopesPlug
20   alias Pleroma.Web.Plugs.RateLimiter
21
22   require Pleroma.Constants
23
24   plug(
25     Majic.Plug,
26     [pool: Pleroma.MajicPool] when action in [:update_avatar, :update_background, :update_banner]
27   )
28
29   plug(
30     OpenApiSpex.Plug.PutApiSpec,
31     [module: Pleroma.Web.ApiSpec] when action == :confirmation_resend
32   )
33
34   plug(Pleroma.Web.ApiSpec.CastAndValidate)
35
36   plug(:skip_auth when action == :confirmation_resend)
37
38   plug(
39     OAuthScopesPlug,
40     %{scopes: ["follow", "write:follows"]} when action in [:subscribe, :unsubscribe]
41   )
42
43   plug(
44     OAuthScopesPlug,
45     %{scopes: ["read:favourites"], fallback: :proceed_unauthenticated} when action == :favourites
46   )
47
48   plug(
49     OAuthScopesPlug,
50     %{fallback: :proceed_unauthenticated, scopes: ["read:accounts"]}
51     when action == :endorsements
52   )
53
54   plug(
55     OAuthScopesPlug,
56     %{scopes: ["read:accounts"]} when action == :birthdays
57   )
58
59   plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend)
60
61   plug(
62     :assign_account_by_id
63     when action in [:favourites, :endorsements, :subscribe, :unsubscribe]
64   )
65
66   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation
67
68   @doc "POST /api/v1/pleroma/accounts/confirmation_resend"
69   def confirmation_resend(conn, params) do
70     nickname_or_email = params[:email] || params[:nickname]
71
72     with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
73          {:ok, _} <- User.maybe_send_confirmation_email(user) do
74       json_response(conn, :no_content, "")
75     end
76   end
77
78   @doc "GET /api/v1/pleroma/accounts/:id/favourites"
79   def favourites(%{assigns: %{account: %{hide_favorites: true}}} = conn, _params) do
80     render_error(conn, :forbidden, "Can't get favorites")
81   end
82
83   def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
84     params =
85       params
86       |> Map.put(:type, "Create")
87       |> Map.put(:favorited_by, user.ap_id)
88       |> Map.put(:blocking_user, for_user)
89
90     recipients =
91       if for_user do
92         [Pleroma.Constants.as_public()] ++ [for_user.ap_id | User.following(for_user)]
93       else
94         [Pleroma.Constants.as_public()]
95       end
96
97     activities =
98       recipients
99       |> ActivityPub.fetch_activities(params)
100       |> Enum.reverse()
101
102     conn
103     |> add_link_headers(activities)
104     |> put_view(StatusView)
105     |> render("index.json",
106       activities: activities,
107       for: for_user,
108       as: :activity
109     )
110   end
111
112   @doc "GET /api/v1/pleroma/accounts/:id/endorsements"
113   def endorsements(%{assigns: %{user: for_user, account: user}} = conn, params) do
114     users =
115       user
116       |> User.endorsed_users_relation(_restrict_deactivated = true)
117       |> Pleroma.Repo.all()
118
119     conn
120     |> render("index.json",
121       for: for_user,
122       users: users,
123       as: :user,
124       embed_relationships: embed_relationships?(params)
125     )
126   end
127
128   @doc "POST /api/v1/pleroma/accounts/:id/subscribe"
129   def subscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
130     with {:ok, _subscription} <- User.subscribe(user, subscription_target) do
131       render(conn, "relationship.json", user: user, target: subscription_target)
132     else
133       {:error, message} -> json_response(conn, :forbidden, %{error: message})
134     end
135   end
136
137   @doc "POST /api/v1/pleroma/accounts/:id/unsubscribe"
138   def unsubscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
139     with {:ok, _subscription} <- User.unsubscribe(user, subscription_target) do
140       render(conn, "relationship.json", user: user, target: subscription_target)
141     else
142       {:error, message} -> json_response(conn, :forbidden, %{error: message})
143     end
144   end
145
146   @doc "GET /api/v1/pleroma/birthdays"
147   def birthdays(%{assigns: %{user: %User{} = user}} = conn, %{day: day, month: month} = _params) do
148     birthdays =
149       User.get_friends_birthdays_query(user, day, month)
150       |> Pleroma.Repo.all()
151
152     conn
153     |> render("index.json",
154       for: user,
155       users: birthdays,
156       as: :user
157     )
158   end
159 end