kanidmd_core/https/apidocs/
mod.rs

1use axum::{middleware::from_fn, response::Redirect, routing::get, Router};
2use kanidm_proto::{attribute, internal, scim_v1, v1};
3use utoipa::{
4    openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme},
5    Modify, OpenApi,
6};
7use utoipa_swagger_ui::SwaggerUi;
8
9use super::{errors::WebError, ServerState};
10
11// pub(crate) mod path_schema;
12
13pub(crate) mod response_schema;
14#[cfg(test)]
15pub(crate) mod tests;
16
17struct SecurityAddon;
18
19impl Modify for SecurityAddon {
20    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
21        if let Some(components) = openapi.components.as_mut() {
22            components.add_security_scheme(
23                "token_jwt",
24                SecurityScheme::Http(
25                    HttpBuilder::new()
26                        .scheme(HttpAuthScheme::Bearer)
27                        .bearer_format("JWT")
28                        .build(),
29                ),
30            )
31        }
32    }
33}
34
35// docs for the derive macro are here: <https://docs.rs/utoipa-gen/3.5.0/utoipa_gen/derive.OpenApi.html#info-attribute-syntax>
36#[derive(OpenApi)]
37#[openapi(
38    servers(
39        (url="https://{host}:{port}",
40            variables(
41                ("host" = (default="localhost", description="Server's hostname")),
42                ("port" = (default="8443", description="Server HTTPS port")),
43            )
44        )
45    ),
46    external_docs(url = "https://kanidm.com/docs", description = "Kanidm documentation page"),
47
48    paths(
49        super::generic::status,
50        super::generic::robots_txt,
51
52        super::oauth2::oauth2_image_get,
53
54        super::v1::raw_create,
55        super::v1::raw_delete,
56        super::v1::raw_modify,
57        super::v1::raw_search,
58
59        super::v1_oauth2::oauth2_get,
60        super::v1_oauth2::oauth2_basic_post,
61        super::v1_oauth2::oauth2_public_post,
62        super::v1_oauth2::oauth2_id_get,
63        super::v1_oauth2::oauth2_id_patch,
64        super::v1_oauth2::oauth2_id_delete,
65        super::v1_oauth2::oauth2_id_image_post,
66        super::v1_oauth2::oauth2_id_image_delete,
67        super::v1_oauth2::oauth2_id_get_basic_secret,
68        super::v1_oauth2::oauth2_id_scopemap_post,
69        super::v1_oauth2::oauth2_id_scopemap_delete,
70        super::v1_oauth2::oauth2_id_sup_scopemap_post,
71        super::v1_oauth2::oauth2_id_sup_scopemap_delete,
72        super::v1_oauth2::oauth2_id_claimmap_join_post,
73        super::v1_oauth2::oauth2_id_claimmap_post,
74        super::v1_oauth2::oauth2_id_claimmap_delete,
75
76        super::v1_scim::scim_sync_post,
77        super::v1_scim::scim_sync_get,
78        super::v1_scim::scim_entry_get,
79        super::v1_scim::scim_entry_post,
80        super::v1_scim::scim_entry_put,
81        super::v1_scim::scim_entry_id_get,
82        super::v1_scim::scim_entry_id_delete,
83        super::v1_scim::scim_person_id_get,
84        super::v1_scim::scim_person_id_application_create_password,
85        super::v1_scim::scim_person_id_application_delete_password,
86        super::v1_scim::scim_person_id_message_send_test_get,
87        super::v1_scim::scim_application_get,
88        super::v1_scim::scim_application_post,
89        super::v1_scim::scim_application_id_get,
90        super::v1_scim::scim_application_id_delete,
91        super::v1_scim::scim_schema_attribute_get,
92        super::v1_scim::scim_schema_class_get,
93        super::v1_scim::scim_message_get,
94        super::v1_scim::scim_message_id_get,
95        super::v1_scim::scim_message_ready_get,
96        super::v1_scim::scim_message_id_sent_post,
97
98        super::v1::schema_get,
99        super::v1::whoami,
100        super::v1::whoami_uat,
101        super::v1::applinks_get,
102        super::v1::schema_attributetype_get,
103        super::v1::schema_attributetype_get_id,
104        super::v1::schema_classtype_get,
105        super::v1::schema_classtype_get_id,
106        super::v1::person_get,
107        super::v1::person_post,
108        super::v1::service_account_credential_generate,
109        super::v1::service_account_api_token_delete,
110        super::v1::service_account_api_token_get,
111        super::v1::service_account_api_token_post,
112        super::v1::person_search_id,
113        super::v1::person_id_get,
114        super::v1::person_id_patch,
115        super::v1::person_id_delete,
116        super::v1::person_id_get_attr,
117        super::v1::person_id_put_attr,
118        super::v1::person_id_post_attr,
119        super::v1::person_id_delete_attr,
120        super::v1::person_get_id_certificate,
121        super::v1::person_post_id_certificate,
122        super::v1::person_get_id_credential_status,
123        super::v1::person_id_credential_update_get,
124        super::v1::person_id_credential_update_intent_get,
125        super::v1::person_id_credential_update_intent_ttl_get,
126
127        super::v1::service_account_id_ssh_pubkeys_get,
128        super::v1::service_account_id_ssh_pubkeys_post,
129
130        super::v1::person_id_ssh_pubkeys_get,
131        super::v1::person_id_ssh_pubkeys_post,
132        super::v1::person_id_ssh_pubkeys_tag_get,
133        super::v1::person_id_ssh_pubkeys_tag_delete,
134
135        super::v1::person_id_radius_get,
136        super::v1::person_id_radius_post,
137        super::v1::person_id_radius_delete,
138        super::v1::person_id_radius_token_get,
139
140        super::v1::account_id_ssh_pubkeys_get,
141        // super::v1::account_id_radius_token_post,
142        super::v1::person_id_unix_post,
143        super::v1::person_id_unix_credential_put,
144        super::v1::person_id_unix_credential_delete,
145        super::v1::person_identify_user_post,
146        super::v1::service_account_get,
147        super::v1::service_account_post,
148        super::v1::service_account_id_get,
149        super::v1::service_account_id_delete,
150        super::v1::service_account_id_patch,
151        super::v1::service_account_id_get_attr,
152        super::v1::service_account_id_put_attr,
153        super::v1::service_account_id_post_attr,
154        super::v1::service_account_id_delete_attr,
155        super::v1::service_account_into_person,
156        // super::v1::service_account_api_token_post,
157        // super::v1::service_account_api_token_get,
158        // super::v1::service_account_api_token_delete,
159        // super::v1::service_account_credential_generate,
160        super::v1::service_account_id_credential_status_get,
161        super::v1::service_account_id_ssh_pubkeys_tag_get,
162        super::v1::service_account_id_ssh_pubkeys_tag_delete,
163        super::v1::service_account_id_unix_post,
164        super::v1::account_id_unix_auth_post,
165        // super::v1::account_id_unix_token,
166        super::v1::account_id_unix_token,
167        super::v1::account_id_radius_token_post,
168        super::v1::account_id_radius_token_get,
169        // super::v1::account_id_ssh_pubkeys_get,
170        super::v1::account_id_ssh_pubkeys_tag_get,
171        super::v1::account_id_user_auth_token_get,
172        super::v1::account_user_auth_token_delete,
173        super::v1::credential_update_exchange_intent,
174        super::v1::credential_update_status,
175        super::v1::credential_update_update,
176        super::v1::credential_update_commit,
177        super::v1::credential_update_cancel,
178        super::v1::domain_get,
179        super::v1::domain_attr_get,
180        super::v1::domain_attr_put,
181        super::v1::domain_attr_delete,
182        super::v1_domain::image_post,
183        super::v1_domain::image_delete,
184
185        super::v1::group_id_unix_token_get,
186        super::v1::group_id_unix_post,
187        super::v1::group_get,
188        super::v1::group_post,
189        super::v1::group_search_id,
190        super::v1::group_id_get,
191        super::v1::group_id_patch,
192        super::v1::group_id_delete,
193        super::v1::group_id_attr_delete,
194        super::v1::group_id_attr_get,
195        super::v1::group_id_attr_put,
196        super::v1::group_id_attr_post,
197        super::v1::system_get,
198        super::v1::system_attr_get,
199        super::v1::system_attr_post,
200        super::v1::system_attr_put,
201        super::v1::system_attr_delete,
202        super::v1::recycle_bin_get,
203        super::v1::recycle_bin_id_get,
204        super::v1::recycle_bin_revive_id_post,
205        super::v1::auth,
206        super::v1::auth_valid,
207        super::v1::logout,
208        super::v1::reauth,
209        super::v1_scim::sync_account_get,
210        super::v1_scim::sync_account_post,
211        super::v1_scim::sync_account_id_get,
212        super::v1_scim::sync_account_id_patch,
213        super::v1_scim::sync_account_id_attr_get,
214        super::v1_scim::sync_account_id_attr_put,
215        super::v1_scim::sync_account_id_finalise_get,
216        super::v1_scim::sync_account_id_terminate_get,
217        super::v1_scim::sync_account_token_post,
218        super::v1_scim::sync_account_token_delete,
219        super::v1::debug_ipinfo,
220        super::v1::public_jwk_key_id_get,
221
222    ),
223    components(
224        schemas(
225            attribute::Attribute,
226
227            scim_v1::ScimSyncState,
228            scim_v1::ScimSyncRequest,
229            scim_v1::ScimSyncRetentionMode,
230            scim_v1::ScimEntry,
231            scim_v1::ScimValue,
232            scim_v1::ScimMeta,
233            scim_v1::ScimAttr,
234            scim_v1::ScimApplicationPasswordCreate,
235            scim_v1::ScimApplicationPassword,
236            scim_v1::client::ScimEntryPostGeneric,
237
238            internal::ApiToken,
239            internal::ApiTokenPurpose,
240            internal::BackupCodesView,
241            internal::ConsistencyError,
242            internal::CreateRequest,
243            internal::CredentialDetail,
244            internal::CredentialDetailType,
245            internal::CredentialStatus,
246            internal::CUExtPortal,
247            internal::CUIntentToken,
248            internal::CURegState,
249            internal::CUSessionToken,
250            internal::CUStatus,
251            internal::DeleteRequest,
252            internal::Filter,
253            internal::Group,
254            internal::Modify,
255            internal::ModifyList,
256            internal::ModifyRequest,
257            internal::Oauth2ClaimMapJoin,
258            internal::OperationError,
259            internal::PasskeyDetail,
260            internal::PasswordFeedback,
261            internal::PluginError,
262            internal::RadiusAuthToken,
263            internal::SchemaError,
264            internal::SearchRequest,
265            internal::SearchResponse,
266            internal::TotpAlgo,
267            internal::TotpSecret,
268            internal::UatPurpose,
269            internal::UserAuthToken,
270            v1::AccountUnixExtend,
271            v1::ApiTokenGenerate,
272            v1::AuthAllowed,
273            v1::AuthCredential,
274            v1::AuthIssueSession,
275            v1::AuthMech,
276            v1::AuthRequest,
277            v1::AuthResponse,
278            v1::AuthState,
279            v1::AuthStep,
280            v1::Entry,
281            v1::GroupUnixExtend,
282            v1::PublicKeyKindSchema,
283            v1::SingleStringRequest,
284            v1::SshPublicKeySchema,
285            v1::KeyTypeKindSchema,
286            v1::KeyTypeSchema,
287            internal::UiHint,
288            v1::UatPurposeStatus,
289            v1::UatStatus,
290            v1::UatStatusState,
291            v1::UnixGroupToken,
292            v1::UnixUserToken,
293            v1::WhoamiResponse,
294            internal::CUCredState,
295            internal::CURegWarning,
296            internal::IdentifyUserResponse,
297            internal::AppLink,
298
299            internal::IdentifyUserRequest,
300            // terrible workaround for other things
301            response_schema::CreationChallengeResponse,
302
303            // terrible workaround for other things
304            response_schema::PublicKeyCredential,
305            // terrible workaround for other things
306            response_schema::RequestChallengeResponse,
307            // terrible workaround for other things
308            response_schema::Base64UrlSafeData,
309            // terrible workaround for other things
310            response_schema::BTreeSet,
311            // terrible workaround for other things
312            response_schema::Result,
313            // terrible workaround for other things
314            response_schema::ScimEntry,
315            //  workaround for the fact that BTreeSet can't be represented in JSON
316            response_schema::ProtoEntry,
317            // terrible workaround for other things
318            response_schema::Jwk,
319            response_schema::ScimComplexAttr,
320            WebError,
321        )
322    ),
323    modifiers(&SecurityAddon),
324    tags(
325        (name = "kanidm", description = "Kanidm API")
326    ),
327    info(
328        title = "Kanidm",
329        description = "API for interacting with the Kanidm system. This is a work in progress.",
330        contact( // <https://docs.rs/utoipa-gen/3.5.0/utoipa_gen/derive.OpenApi.html#info-attribute-syntax>
331            name="Kanidm Github",
332            url="https://github.com/kanidm/kanidm",
333        )
334    )
335)]
336pub(crate) struct ApiDoc;
337
338pub(crate) fn router() -> Router<ServerState> {
339    Router::new()
340        .route("/docs", get(Redirect::temporary("/docs/swagger-ui")))
341        .route("/docs/", get(Redirect::temporary("/docs/swagger-ui")))
342        .merge(SwaggerUi::new("/docs/swagger-ui").url("/docs/v1/openapi.json", ApiDoc::openapi()))
343        // overlay the version middleware because the client is sad without it
344        .layer(from_fn(super::middleware::version_middleware))
345}