Fix API spec, add app schema
[akkoma] / lib / pleroma / web / api_spec / operations / app_operation.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ApiSpec.AppOperation do
6 alias OpenApiSpex.Operation
7 alias OpenApiSpex.Schema
8 alias Pleroma.Web.ApiSpec.Helpers
9 alias Pleroma.Web.ApiSpec.Schemas.App
10
11 @spec open_api_operation(atom) :: Operation.t()
12 def open_api_operation(action) do
13 operation = String.to_existing_atom("#{action}_operation")
14 apply(__MODULE__, operation, [])
15 end
16
17 @spec index_operation() :: Operation.t()
18 def index_operation do
19 %Operation{
20 tags: ["Applications"],
21 summary: "List applications",
22 description: "List the OAuth applications for the current user",
23 operationId: "AppController.index",
24 responses: %{
25 200 => Operation.response("Array of App", "application/json", array_of_apps())
26 }
27 }
28 end
29
30 @spec create_operation() :: Operation.t()
31 def create_operation do
32 %Operation{
33 tags: ["Applications"],
34 summary: "Create an application",
35 description: "Create a new application to obtain OAuth2 credentials",
36 operationId: "AppController.create",
37 requestBody: Helpers.request_body("Parameters", create_request(), required: true),
38 responses: %{
39 200 => Operation.response("App", "application/json", create_response()),
40 422 =>
41 Operation.response(
42 "Unprocessable Entity",
43 "application/json",
44 %Schema{
45 type: :object,
46 description:
47 "If a required parameter is missing or improperly formatted, the request will fail.",
48 properties: %{
49 error: %Schema{type: :string}
50 },
51 example: %{
52 "error" => "Validation failed: Redirect URI must be an absolute URI."
53 }
54 }
55 )
56 }
57 }
58 end
59
60 def verify_credentials_operation do
61 %Operation{
62 tags: ["Applications"],
63 summary: "Verify the application works",
64 description: "Confirm that the app's OAuth2 credentials work.",
65 operationId: "AppController.verify_credentials",
66 security: [%{"oAuth" => ["read"]}],
67 responses: %{
68 200 =>
69 Operation.response("App", "application/json", %Schema{
70 type: :object,
71 description:
72 "If the Authorization header was provided with a valid token, you should see your app returned as an Application entity.",
73 properties: %{
74 name: %Schema{type: :string},
75 vapid_key: %Schema{type: :string},
76 website: %Schema{type: :string, nullable: true}
77 },
78 example: %{
79 "name" => "My App",
80 "vapid_key" =>
81 "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=",
82 "website" => "https://myapp.com/"
83 }
84 }),
85 422 =>
86 Operation.response(
87 "Unauthorized",
88 "application/json",
89 %Schema{
90 type: :object,
91 description:
92 "If the Authorization header contains an invalid token, is malformed, or is not present, an error will be returned indicating an authorization failure.",
93 properties: %{
94 error: %Schema{type: :string}
95 },
96 example: %{
97 "error" => "The access token is invalid."
98 }
99 }
100 )
101 }
102 }
103 end
104
105 defp create_request do
106 %Schema{
107 title: "AppCreateRequest",
108 description: "POST body for creating an app",
109 type: :object,
110 properties: %{
111 client_name: %Schema{type: :string, description: "A name for your application."},
112 redirect_uris: %Schema{
113 type: :string,
114 description:
115 "Where the user should be redirected after authorization. To display the authorization code to the user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in this parameter."
116 },
117 scopes: %Schema{
118 type: :string,
119 description: "Space separated list of scopes",
120 default: "read"
121 },
122 website: %Schema{
123 type: :string,
124 nullable: true,
125 description: "A URL to the homepage of your app"
126 }
127 },
128 required: [:client_name, :redirect_uris],
129 example: %{
130 "client_name" => "My App",
131 "redirect_uris" => "https://myapp.com/auth/callback",
132 "website" => "https://myapp.com/"
133 }
134 }
135 end
136
137 defp create_response do
138 %Schema{
139 title: "AppCreateResponse",
140 description: "Response schema for an app",
141 type: :object,
142 properties: %{
143 id: %Schema{type: :string},
144 name: %Schema{type: :string},
145 client_id: %Schema{type: :string},
146 client_secret: %Schema{type: :string},
147 redirect_uri: %Schema{type: :string},
148 vapid_key: %Schema{type: :string},
149 website: %Schema{type: :string, nullable: true}
150 },
151 example: %{
152 "id" => "123",
153 "name" => "My App",
154 "client_id" => "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM",
155 "client_secret" => "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw",
156 "vapid_key" =>
157 "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=",
158 "website" => "https://myapp.com/"
159 }
160 }
161 end
162
163 defp array_of_apps do
164 %Schema{type: :array, items: App, example: [App.schema().example]}
165 end
166 end