1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-04-19 06:24:45 +00:00
deprecated-gotham-restful/src/openapi/handler.rs

104 lines
2.8 KiB
Rust
Raw Normal View History

use super::SECURITY_NAME;
2021-02-03 21:22:46 +00:00
use futures_util::{future, future::FutureExt};
use gotham::{
2020-09-17 12:25:58 +02:00
anyhow,
handler::{Handler, HandlerFuture, NewHandler},
helpers::http::response::create_response,
2021-02-03 21:22:46 +00:00
hyper::StatusCode,
state::State
};
use indexmap::IndexMap;
use mime::{APPLICATION_JSON, TEXT_PLAIN};
use openapiv3::{APIKeyLocation, OpenAPI, ReferenceOr, SecurityScheme};
use std::{
pin::Pin,
sync::{Arc, RwLock}
};
#[derive(Clone)]
pub struct OpenapiHandler {
openapi: Arc<RwLock<OpenAPI>>
}
impl OpenapiHandler {
pub fn new(openapi: Arc<RwLock<OpenAPI>>) -> Self {
Self { openapi }
}
}
impl NewHandler for OpenapiHandler {
type Instance = Self;
2020-09-17 12:25:58 +02:00
fn new_handler(&self) -> anyhow::Result<Self> {
Ok(self.clone())
}
}
#[cfg(feature = "auth")]
fn get_security(state: &mut State) -> IndexMap<String, ReferenceOr<SecurityScheme>> {
use crate::AuthSource;
use gotham::state::FromState;
let source = match AuthSource::try_borrow_from(state) {
Some(source) => source,
None => return Default::default()
};
let security_scheme = match source {
AuthSource::Cookie(name) => SecurityScheme::APIKey {
location: APIKeyLocation::Cookie,
name: name.to_string()
},
AuthSource::Header(name) => SecurityScheme::APIKey {
location: APIKeyLocation::Header,
name: name.to_string()
},
AuthSource::AuthorizationHeader => SecurityScheme::HTTP {
scheme: "bearer".to_owned(),
bearer_format: Some("JWT".to_owned())
}
};
let mut security_schemes: IndexMap<String, ReferenceOr<SecurityScheme>> = Default::default();
security_schemes.insert(SECURITY_NAME.to_owned(), ReferenceOr::Item(security_scheme));
security_schemes
}
#[cfg(not(feature = "auth"))]
fn get_security(state: &mut State) -> (Vec<SecurityRequirement>, IndexMap<String, ReferenceOr<SecurityScheme>>) {
Default::default()
}
impl Handler for OpenapiHandler {
fn handle(self, mut state: State) -> Pin<Box<HandlerFuture>> {
let openapi = match self.openapi.read() {
Ok(openapi) => openapi,
Err(e) => {
error!("Unable to acquire read lock for the OpenAPI specification: {}", e);
2021-02-03 21:22:46 +00:00
let res = create_response(&state, StatusCode::INTERNAL_SERVER_ERROR, TEXT_PLAIN, "");
return future::ok((state, res)).boxed();
}
};
let mut openapi = openapi.clone();
let security_schemes = get_security(&mut state);
let mut components = openapi.components.unwrap_or_default();
components.security_schemes = security_schemes;
openapi.components = Some(components);
match serde_json::to_string(&openapi) {
Ok(body) => {
2021-02-03 21:22:46 +00:00
let res = create_response(&state, StatusCode::OK, APPLICATION_JSON, body);
future::ok((state, res)).boxed()
},
Err(e) => {
error!("Unable to handle OpenAPI request due to error: {}", e);
2021-02-03 21:22:46 +00:00
let res = create_response(&state, StatusCode::INTERNAL_SERVER_ERROR, TEXT_PLAIN, "");
future::ok((state, res)).boxed()
}
}
}
}