move to 2.5.5
[anni] / lib / pleroma / web / api_spec / operations / filter_operation.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.ApiSpec.FilterOperation do
6   alias OpenApiSpex.Operation
7   alias OpenApiSpex.Schema
8   alias Pleroma.Web.ApiSpec.Helpers
9   alias Pleroma.Web.ApiSpec.Schemas.ApiError
10   alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
11
12   def open_api_operation(action) do
13     operation = String.to_existing_atom("#{action}_operation")
14     apply(__MODULE__, operation, [])
15   end
16
17   def index_operation do
18     %Operation{
19       tags: ["Filters"],
20       summary: "All filters",
21       operationId: "FilterController.index",
22       security: [%{"oAuth" => ["read:filters"]}],
23       responses: %{
24         200 => Operation.response("Filters", "application/json", array_of_filters()),
25         403 => Operation.response("Error", "application/json", ApiError)
26       }
27     }
28   end
29
30   def create_operation do
31     %Operation{
32       tags: ["Filters"],
33       summary: "Create a filter",
34       operationId: "FilterController.create",
35       requestBody: Helpers.request_body("Parameters", create_request(), required: true),
36       security: [%{"oAuth" => ["write:filters"]}],
37       responses: %{
38         200 => Operation.response("Filter", "application/json", filter()),
39         403 => Operation.response("Error", "application/json", ApiError)
40       }
41     }
42   end
43
44   def show_operation do
45     %Operation{
46       tags: ["Filters"],
47       summary: "Filter",
48       parameters: [id_param()],
49       operationId: "FilterController.show",
50       security: [%{"oAuth" => ["read:filters"]}],
51       responses: %{
52         200 => Operation.response("Filter", "application/json", filter()),
53         403 => Operation.response("Error", "application/json", ApiError),
54         404 => Operation.response("Error", "application/json", ApiError)
55       }
56     }
57   end
58
59   def update_operation do
60     %Operation{
61       tags: ["Filters"],
62       summary: "Update a filter",
63       parameters: [id_param()],
64       operationId: "FilterController.update",
65       requestBody: Helpers.request_body("Parameters", update_request(), required: true),
66       security: [%{"oAuth" => ["write:filters"]}],
67       responses: %{
68         200 => Operation.response("Filter", "application/json", filter()),
69         403 => Operation.response("Error", "application/json", ApiError)
70       }
71     }
72   end
73
74   def delete_operation do
75     %Operation{
76       tags: ["Filters"],
77       summary: "Remove a filter",
78       parameters: [id_param()],
79       operationId: "FilterController.delete",
80       security: [%{"oAuth" => ["write:filters"]}],
81       responses: %{
82         200 =>
83           Operation.response("Filter", "application/json", %Schema{
84             type: :object,
85             description: "Empty object"
86           }),
87         403 => Operation.response("Error", "application/json", ApiError)
88       }
89     }
90   end
91
92   defp id_param do
93     Operation.parameter(:id, :path, :string, "Filter ID", example: "123", required: true)
94   end
95
96   defp filter do
97     %Schema{
98       title: "Filter",
99       type: :object,
100       properties: %{
101         id: %Schema{type: :string},
102         phrase: %Schema{type: :string, description: "The text to be filtered"},
103         context: %Schema{
104           type: :array,
105           items: %Schema{type: :string, enum: ["home", "notifications", "public", "thread"]},
106           description: "The contexts in which the filter should be applied."
107         },
108         expires_at: %Schema{
109           type: :string,
110           format: :"date-time",
111           description:
112             "When the filter should no longer be applied. String (ISO 8601 Datetime), or null if the filter does not expire.",
113           nullable: true
114         },
115         irreversible: %Schema{
116           type: :boolean,
117           description:
118             "Should matching entities in home and notifications be dropped by the server?"
119         },
120         whole_word: %Schema{
121           type: :boolean,
122           description: "Should the filter consider word boundaries?"
123         }
124       },
125       example: %{
126         "id" => "5580",
127         "phrase" => "@twitter.com",
128         "context" => [
129           "home",
130           "notifications",
131           "public",
132           "thread"
133         ],
134         "whole_word" => false,
135         "expires_at" => nil,
136         "irreversible" => true
137       }
138     }
139   end
140
141   defp array_of_filters do
142     %Schema{
143       title: "ArrayOfFilters",
144       description: "Array of Filters",
145       type: :array,
146       items: filter(),
147       example: [
148         %{
149           "id" => "5580",
150           "phrase" => "@twitter.com",
151           "context" => [
152             "home",
153             "notifications",
154             "public",
155             "thread"
156           ],
157           "whole_word" => false,
158           "expires_at" => nil,
159           "irreversible" => true
160         },
161         %{
162           "id" => "6191",
163           "phrase" => ":eurovision2019:",
164           "context" => [
165             "home"
166           ],
167           "whole_word" => true,
168           "expires_at" => "2019-05-21T13:47:31.333Z",
169           "irreversible" => false
170         }
171       ]
172     }
173   end
174
175   defp create_request do
176     %Schema{
177       title: "FilterCreateRequest",
178       allOf: [
179         update_request(),
180         %Schema{
181           type: :object,
182           properties: %{
183             irreversible: %Schema{
184               allOf: [BooleanLike],
185               description:
186                 "Should the server irreversibly drop matching entities from home and notifications?",
187               default: false
188             }
189           }
190         }
191       ],
192       example: %{
193         "phrase" => "knights",
194         "context" => ["home"]
195       }
196     }
197   end
198
199   defp update_request do
200     %Schema{
201       title: "FilterUpdateRequest",
202       type: :object,
203       properties: %{
204         phrase: %Schema{type: :string, description: "The text to be filtered"},
205         context: %Schema{
206           type: :array,
207           items: %Schema{type: :string, enum: ["home", "notifications", "public", "thread"]},
208           description:
209             "Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified."
210         },
211         irreversible: %Schema{
212           allOf: [BooleanLike],
213           nullable: true,
214           description:
215             "Should the server irreversibly drop matching entities from home and notifications?"
216         },
217         whole_word: %Schema{
218           allOf: [BooleanLike],
219           nullable: true,
220           description: "Consider word boundaries?",
221           default: true
222         },
223         expires_in: %Schema{
224           nullable: true,
225           type: :integer,
226           description:
227             "Number of seconds from now the filter should expire. Otherwise, null for a filter that doesn't expire."
228         }
229       },
230       required: [:phrase, :context],
231       example: %{
232         "phrase" => "knights",
233         "context" => ["home"]
234       }
235     }
236   end
237 end