Can restrict access with token
This commit is contained in:
parent
5de894ccce
commit
2f9deca1e3
38
src/main.rs
38
src/main.rs
@ -1,6 +1,8 @@
|
|||||||
use actix_web::{App, HttpResponse, HttpServer, Responder, web};
|
use actix_web::{App, HttpResponse, HttpServer, Responder, web};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
|
const SCHEMA_FILE: &str = "schema.yaml";
|
||||||
|
|
||||||
/// Simple swagger UI server - serves OpenAPI file
|
/// Simple swagger UI server - serves OpenAPI file
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
@ -12,6 +14,10 @@ struct Args {
|
|||||||
/// Listen address
|
/// Listen address
|
||||||
#[clap(short, long, default_value = "0.0.0.0:8000")]
|
#[clap(short, long, default_value = "0.0.0.0:8000")]
|
||||||
listen_address: String,
|
listen_address: String,
|
||||||
|
|
||||||
|
/// Access token, optional
|
||||||
|
#[clap(short, long)]
|
||||||
|
token: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
@ -19,12 +25,32 @@ struct HandlerPath {
|
|||||||
filename: Option<String>,
|
filename: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct HandlerQuery {
|
||||||
|
token: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
struct Schema(String);
|
struct Schema(String);
|
||||||
|
|
||||||
async fn handler(path: web::Path<HandlerPath>, schema: web::Data<Schema>) -> impl Responder {
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
struct AccessToken(Option<String>);
|
||||||
|
|
||||||
|
async fn handler(path: web::Path<HandlerPath>,
|
||||||
|
query: web::Query<HandlerQuery>,
|
||||||
|
schema: web::Data<Schema>,
|
||||||
|
access_token: web::Data<AccessToken>) -> impl Responder {
|
||||||
let filename: &str = path.filename.as_deref().unwrap_or("index.html");
|
let filename: &str = path.filename.as_deref().unwrap_or("index.html");
|
||||||
|
|
||||||
|
if filename.eq("index.html") || filename.eq(SCHEMA_FILE) {
|
||||||
|
if let Some(tok) = access_token.0.as_ref() {
|
||||||
|
if !query.token.as_deref().unwrap_or_default().eq(tok) {
|
||||||
|
return HttpResponse::Unauthorized()
|
||||||
|
.body("Please indicate as query parameter the 'token'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ext = filename
|
let ext = filename
|
||||||
.rsplit_once('.')
|
.rsplit_once('.')
|
||||||
.map(|r| r.1).unwrap_or_default();
|
.map(|r| r.1).unwrap_or_default();
|
||||||
@ -39,7 +65,7 @@ async fn handler(path: web::Path<HandlerPath>, schema: web::Data<Schema>) -> imp
|
|||||||
_ => "text/plain"
|
_ => "text/plain"
|
||||||
};
|
};
|
||||||
|
|
||||||
let filebytes = if filename.eq("schema.yaml") {
|
let filebytes = if filename.eq(SCHEMA_FILE) {
|
||||||
Some(schema.0.as_bytes().to_vec())
|
Some(schema.0.as_bytes().to_vec())
|
||||||
} else {
|
} else {
|
||||||
swagger_ui::Assets::get(filename).map(|f| f.to_vec())
|
swagger_ui::Assets::get(filename).map(|f| f.to_vec())
|
||||||
@ -51,7 +77,10 @@ async fn handler(path: web::Path<HandlerPath>, schema: web::Data<Schema>) -> imp
|
|||||||
|
|
||||||
if filename.eq("index.html") {
|
if filename.eq("index.html") {
|
||||||
bytes = String::from_utf8_lossy(&bytes).to_string()
|
bytes = String::from_utf8_lossy(&bytes).to_string()
|
||||||
.replace("https://petstore.swagger.io/v2/swagger.json", "/schema.yaml")
|
.replace(
|
||||||
|
"https://petstore.swagger.io/v2/swagger.json",
|
||||||
|
&format!("/{}?token={}", SCHEMA_FILE, access_token.0.as_deref().unwrap_or_default()),
|
||||||
|
)
|
||||||
.as_bytes().to_vec();
|
.as_bytes().to_vec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,9 +102,12 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let schema = Schema(std::fs::read_to_string(args.schema)
|
let schema = Schema(std::fs::read_to_string(args.schema)
|
||||||
.expect("Failed to read schema!"));
|
.expect("Failed to read schema!"));
|
||||||
|
|
||||||
|
let access_token = AccessToken(args.token);
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(schema.clone()))
|
.app_data(web::Data::new(schema.clone()))
|
||||||
|
.app_data(web::Data::new(access_token.clone()))
|
||||||
|
|
||||||
.route("/", web::get().to(handler))
|
.route("/", web::get().to(handler))
|
||||||
.route("/{filename}", web::get().to(handler))
|
.route("/{filename}", web::get().to(handler))
|
||||||
|
Loading…
Reference in New Issue
Block a user