-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathmod.rs
More file actions
113 lines (105 loc) · 3.31 KB
/
Copy pathmod.rs
File metadata and controls
113 lines (105 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
//! # v4 API.
use axum::{
Json,
extract::{OriginalUri, Request, State},
http::{HeaderMap, StatusCode, header},
response::IntoResponse,
};
use utoipa::OpenApi;
use utoipa_axum::{router::OpenApiRouter, routes};
use crate::api::error::KeystoneApiError;
use crate::federation::api as federation;
use crate::k8s_auth::api as k8s_auth;
use crate::keystone::ServiceState;
pub mod auth;
pub mod group;
pub mod project;
pub mod role;
pub mod role_assignment;
pub mod spiffe;
pub mod token;
pub mod user;
use crate::api::types::*;
/// OpenApi specification for v4.
#[derive(OpenApi)]
#[openapi(
nest(
(path = "federation", api = federation::ApiDoc),
(path = "k8s_auth", api = k8s_auth::ApiDoc),
(path = "tokens", api = token::ApiDoc),
(path = "spiffe", api = spiffe::ApiDoc),
(path = "projects", api = project::ApiDoc),
),
)]
pub struct ApiDoc;
pub(super) fn openapi_router() -> OpenApiRouter<ServiceState> {
OpenApiRouter::new()
.nest("/auth", auth::openapi_router())
.nest("/groups", group::openapi_router())
.nest("/federation", federation::openapi_router())
.nest("/k8s_auth", k8s_auth::openapi_router())
.nest("/role_assignments", role_assignment::openapi_router())
.nest("/roles", role::openapi_router())
.nest("/projects", project::openapi_router())
.nest("/tokens", token::openapi_router())
.nest("/users", user::openapi_router())
.nest("/spiffe", spiffe::openapi_router())
.routes(routes!(version))
}
/// Version discovery endpoint
#[utoipa::path(
get,
path = "/",
description = "Version discovery",
responses(
(status = OK, description = "Versions", body = SingleVersion),
),
tag = "version"
)]
async fn version(
headers: HeaderMap,
OriginalUri(uri): OriginalUri,
State(state): State<ServiceState>,
_req: Request,
) -> Result<impl IntoResponse, KeystoneApiError> {
let host = state
.config_manager
.config
.read()
.await
.default
.public_endpoint
.clone()
.map(|x| x.to_string())
.or_else(|| {
headers
.get(header::HOST)
.and_then(|header| header.to_str().map(|val| format!("http://{val}")).ok())
})
.unwrap_or_else(|| "http://localhost".to_string());
let link = Link {
rel: "self".into(),
href: format!("{}{}", host, uri.path()),
};
let version = VersionBuilder::default()
.id("v4.0")
.status(VersionStatus::Stable)
.links(vec![link])
.media_types(vec![MediaType::default()])
.build()?;
let res = SingleVersion { version };
Ok((StatusCode::OK, Json(res)).into_response())
}