Improve OpenAPI schema
[akkoma] / lib / pleroma / web / api_spec / operations / account_operation.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ApiSpec.AccountOperation do
6 alias OpenApiSpex.Operation
7 alias OpenApiSpex.Reference
8 alias OpenApiSpex.Schema
9 alias Pleroma.Web.ApiSpec.Schemas.Account
10 alias Pleroma.Web.ApiSpec.Schemas.AccountCreateRequest
11 alias Pleroma.Web.ApiSpec.Schemas.AccountCreateResponse
12 alias Pleroma.Web.ApiSpec.Schemas.AccountFollowsRequest
13 alias Pleroma.Web.ApiSpec.Schemas.AccountMuteRequest
14 alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship
15 alias Pleroma.Web.ApiSpec.Schemas.AccountRelationshipsResponse
16 alias Pleroma.Web.ApiSpec.Schemas.AccountsResponse
17 alias Pleroma.Web.ApiSpec.Schemas.AccountUpdateCredentialsRequest
18 alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
19 alias Pleroma.Web.ApiSpec.Schemas.ListsResponse
20 alias Pleroma.Web.ApiSpec.Schemas.StatusesResponse
21 alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
22
23 import Pleroma.Web.ApiSpec.Helpers
24
25 @spec open_api_operation(atom) :: Operation.t()
26 def open_api_operation(action) do
27 operation = String.to_existing_atom("#{action}_operation")
28 apply(__MODULE__, operation, [])
29 end
30
31 @spec create_operation() :: Operation.t()
32 def create_operation do
33 %Operation{
34 tags: ["accounts"],
35 summary: "Register an account",
36 description:
37 "Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.",
38 operationId: "AccountController.create",
39 requestBody: request_body("Parameters", AccountCreateRequest, required: true),
40 responses: %{
41 200 => Operation.response("Account", "application/json", AccountCreateResponse)
42 }
43 }
44 end
45
46 def verify_credentials_operation do
47 %Operation{
48 tags: ["accounts"],
49 description: "Test to make sure that the user token works.",
50 summary: "Verify account credentials",
51 operationId: "AccountController.verify_credentials",
52 security: [%{"oAuth" => ["read:accounts"]}],
53 responses: %{
54 200 => Operation.response("Account", "application/json", Account)
55 }
56 }
57 end
58
59 def update_credentials_operation do
60 %Operation{
61 tags: ["accounts"],
62 summary: "Update account credentials",
63 description: "Update the user's display and preferences.",
64 operationId: "AccountController.update_credentials",
65 security: [%{"oAuth" => ["write:accounts"]}],
66 requestBody: request_body("Parameters", AccountUpdateCredentialsRequest, required: true),
67 responses: %{
68 200 => Operation.response("Account", "application/json", Account)
69 }
70 }
71 end
72
73 def relationships_operation do
74 %Operation{
75 tags: ["accounts"],
76 summary: "Check relationships to other accounts",
77 operationId: "AccountController.relationships",
78 description: "Find out whether a given account is followed, blocked, muted, etc.",
79 security: [%{"oAuth" => ["read:follows"]}],
80 parameters: [
81 Operation.parameter(
82 :id,
83 :query,
84 %Schema{
85 oneOf: [%Schema{type: :array, items: %Schema{type: :string}}, %Schema{type: :string}]
86 },
87 "Account IDs",
88 example: "123"
89 )
90 ],
91 responses: %{
92 200 => Operation.response("Account", "application/json", AccountRelationshipsResponse)
93 }
94 }
95 end
96
97 def show_operation do
98 %Operation{
99 tags: ["accounts"],
100 summary: "Account",
101 operationId: "AccountController.show",
102 description: "View information about a profile.",
103 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
104 responses: %{
105 200 => Operation.response("Account", "application/json", Account)
106 }
107 }
108 end
109
110 def statuses_operation do
111 %Operation{
112 tags: ["accounts"],
113 summary: "Statuses",
114 operationId: "AccountController.statuses",
115 description:
116 "Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)",
117 parameters:
118 [
119 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
120 Operation.parameter(:pinned, :query, BooleanLike, "Include only pinned statuses"),
121 Operation.parameter(:tagged, :query, :string, "With tag"),
122 Operation.parameter(
123 :only_media,
124 :query,
125 BooleanLike,
126 "Include only statuses with media attached"
127 ),
128 Operation.parameter(
129 :with_muted,
130 :query,
131 BooleanLike,
132 "Include statuses from muted acccounts."
133 ),
134 Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"),
135 Operation.parameter(
136 :exclude_visibilities,
137 :query,
138 %Schema{type: :array, items: VisibilityScope},
139 "Exclude visibilities"
140 )
141 ] ++ pagination_params(),
142 responses: %{
143 200 => Operation.response("Statuses", "application/json", StatusesResponse)
144 }
145 }
146 end
147
148 def followers_operation do
149 %Operation{
150 tags: ["accounts"],
151 summary: "Followers",
152 operationId: "AccountController.followers",
153 security: [%{"oAuth" => ["read:accounts"]}],
154 description:
155 "Accounts which follow the given account, if network is not hidden by the account owner.",
156 parameters:
157 [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
158 responses: %{
159 200 => Operation.response("Accounts", "application/json", AccountsResponse)
160 }
161 }
162 end
163
164 def following_operation do
165 %Operation{
166 tags: ["accounts"],
167 summary: "Following",
168 operationId: "AccountController.following",
169 security: [%{"oAuth" => ["read:accounts"]}],
170 description:
171 "Accounts which the given account is following, if network is not hidden by the account owner.",
172 parameters:
173 [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(),
174 responses: %{200 => Operation.response("Accounts", "application/json", AccountsResponse)}
175 }
176 end
177
178 def lists_operation do
179 %Operation{
180 tags: ["accounts"],
181 summary: "Lists containing this account",
182 operationId: "AccountController.lists",
183 security: [%{"oAuth" => ["read:lists"]}],
184 description: "User lists that you have added this account to.",
185 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
186 responses: %{200 => Operation.response("Lists", "application/json", ListsResponse)}
187 }
188 end
189
190 def follow_operation do
191 %Operation{
192 tags: ["accounts"],
193 summary: "Follow",
194 operationId: "AccountController.follow",
195 security: [%{"oAuth" => ["follow", "write:follows"]}],
196 description: "Follow the given account",
197 parameters: [
198 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
199 Operation.parameter(
200 :reblogs,
201 :query,
202 BooleanLike,
203 "Receive this account's reblogs in home timeline? Defaults to true."
204 )
205 ],
206 responses: %{
207 200 => Operation.response("Relationship", "application/json", AccountRelationship)
208 }
209 }
210 end
211
212 def unfollow_operation do
213 %Operation{
214 tags: ["accounts"],
215 summary: "Unfollow",
216 operationId: "AccountController.unfollow",
217 security: [%{"oAuth" => ["follow", "write:follows"]}],
218 description: "Unfollow the given account",
219 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
220 responses: %{
221 200 => Operation.response("Relationship", "application/json", AccountRelationship)
222 }
223 }
224 end
225
226 def mute_operation do
227 %Operation{
228 tags: ["accounts"],
229 summary: "Mute",
230 operationId: "AccountController.mute",
231 security: [%{"oAuth" => ["follow", "write:mutes"]}],
232 requestBody: request_body("Parameters", AccountMuteRequest),
233 description:
234 "Mute the given account. Clients should filter statuses and notifications from this account, if received (e.g. due to a boost in the Home timeline).",
235 parameters: [
236 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
237 Operation.parameter(
238 :notifications,
239 :query,
240 %Schema{allOf: [BooleanLike], default: true},
241 "Mute notifications in addition to statuses? Defaults to `true`."
242 )
243 ],
244 responses: %{
245 200 => Operation.response("Relationship", "application/json", AccountRelationship)
246 }
247 }
248 end
249
250 def unmute_operation do
251 %Operation{
252 tags: ["accounts"],
253 summary: "Unmute",
254 operationId: "AccountController.unmute",
255 security: [%{"oAuth" => ["follow", "write:mutes"]}],
256 description: "Unmute the given account.",
257 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
258 responses: %{
259 200 => Operation.response("Relationship", "application/json", AccountRelationship)
260 }
261 }
262 end
263
264 def block_operation do
265 %Operation{
266 tags: ["accounts"],
267 summary: "Block",
268 operationId: "AccountController.block",
269 security: [%{"oAuth" => ["follow", "write:blocks"]}],
270 description:
271 "Block the given account. Clients should filter statuses from this account if received (e.g. due to a boost in the Home timeline)",
272 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
273 responses: %{
274 200 => Operation.response("Relationship", "application/json", AccountRelationship)
275 }
276 }
277 end
278
279 def unblock_operation do
280 %Operation{
281 tags: ["accounts"],
282 summary: "Unblock",
283 operationId: "AccountController.unblock",
284 security: [%{"oAuth" => ["follow", "write:blocks"]}],
285 description: "Unblock the given account.",
286 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
287 responses: %{
288 200 => Operation.response("Relationship", "application/json", AccountRelationship)
289 }
290 }
291 end
292
293 def follows_operation do
294 %Operation{
295 tags: ["accounts"],
296 summary: "Follows",
297 operationId: "AccountController.follows",
298 security: [%{"oAuth" => ["follow", "write:follows"]}],
299 requestBody: request_body("Parameters", AccountFollowsRequest, required: true),
300 responses: %{
301 200 => Operation.response("Account", "application/json", Account)
302 }
303 }
304 end
305
306 def mutes_operation do
307 %Operation{
308 tags: ["accounts"],
309 summary: "Muted accounts",
310 operationId: "AccountController.mutes",
311 description: "Accounts the user has muted.",
312 security: [%{"oAuth" => ["follow", "read:mutes"]}],
313 responses: %{
314 200 => Operation.response("Accounts", "application/json", AccountsResponse)
315 }
316 }
317 end
318
319 def blocks_operation do
320 %Operation{
321 tags: ["accounts"],
322 summary: "Blocked users",
323 operationId: "AccountController.blocks",
324 description: "View your blocks. See also accounts/:id/{block,unblock}",
325 security: [%{"oAuth" => ["read:blocks"]}],
326 responses: %{
327 200 => Operation.response("Accounts", "application/json", AccountsResponse)
328 }
329 }
330 end
331
332 def endorsements_operation do
333 %Operation{
334 tags: ["accounts"],
335 summary: "Endorsements",
336 operationId: "AccountController.endorsements",
337 description: "Not implemented",
338 security: [%{"oAuth" => ["read:accounts"]}],
339 responses: %{
340 200 => Operation.response("Empry array", "application/json", %Schema{type: :array})
341 }
342 }
343 end
344
345 def identity_proofs_operation do
346 %Operation{
347 tags: ["accounts"],
348 summary: "Identity proofs",
349 operationId: "AccountController.identity_proofs",
350 description: "Not implemented",
351 responses: %{
352 200 => Operation.response("Empry array", "application/json", %Schema{type: :array})
353 }
354 }
355 end
356 end