73 lines
2.3 KiB
Rust
73 lines
2.3 KiB
Rust
use lazy_static::lazy_static;
|
|
use okapi::openapi3::{Object, SecurityRequirement, SecurityScheme, SecuritySchemeData};
|
|
use rocket::{
|
|
http::Status,
|
|
request::{self, FromRequest},
|
|
Request,
|
|
};
|
|
use rocket_okapi::{
|
|
gen::OpenApiGenerator,
|
|
request::{OpenApiFromRequest, RequestHeaderInput},
|
|
};
|
|
|
|
lazy_static! {
|
|
static ref API_KEYS: Vec<String> = {
|
|
serde_json::from_str(
|
|
&std::fs::read_to_string("api_keys.json").expect("api_keys.json does not exist"),
|
|
)
|
|
.expect("api_keys.json is not valid")
|
|
};
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub struct ApiKey;
|
|
|
|
#[rocket::async_trait]
|
|
impl<'r> FromRequest<'r> for ApiKey {
|
|
type Error = ApiKey;
|
|
|
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
|
if req
|
|
.headers()
|
|
.get("X-API-Key")
|
|
.any(|k| API_KEYS.contains(&String::from(k)))
|
|
{
|
|
request::Outcome::Success(ApiKey)
|
|
} else {
|
|
request::Outcome::Failure((Status::Unauthorized, ApiKey))
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> OpenApiFromRequest<'a> for ApiKey {
|
|
fn from_request_input(
|
|
_gen: &mut OpenApiGenerator,
|
|
_name: String,
|
|
_required: bool,
|
|
) -> rocket_okapi::Result<RequestHeaderInput> {
|
|
// Setup global requirement for Security scheme
|
|
let security_scheme = SecurityScheme {
|
|
description: Some("Requires an API key to access".to_owned()),
|
|
// Setup data requirements.
|
|
// This can be part of the `header`, `query` or `cookie`.
|
|
// In this case the header `x-api-key: mykey` needs to be set.
|
|
data: SecuritySchemeData::ApiKey {
|
|
name: "x-api-key".to_owned(),
|
|
location: "header".to_owned(),
|
|
},
|
|
extensions: Object::default(),
|
|
};
|
|
// Add the requirement for this route/endpoint
|
|
// This can change between routes.
|
|
let mut security_req = SecurityRequirement::new();
|
|
// Each security requirement needs to be met before access is allowed.
|
|
security_req.insert("ApiKeyAuth".to_owned(), Vec::new());
|
|
// These vvvvvvv-----^^^^^^^^^^ values need to match exactly!
|
|
Ok(RequestHeaderInput::Security(
|
|
"ApiKeyAuth".to_owned(),
|
|
security_scheme,
|
|
security_req,
|
|
))
|
|
}
|
|
}
|