ezidam: added cors, http basic auth request guard
This commit is contained in:
parent
3ce6154dfa
commit
dd69fc99ea
6 changed files with 128 additions and 0 deletions
|
|
@ -12,6 +12,8 @@ erased-serde = "0.3"
|
|||
url = { workspace = true }
|
||||
identicon-rs = "4.0"
|
||||
futures = "0.3"
|
||||
base64 = "0.21.0"
|
||||
rocket_cors = "0.6.0-alpha2"
|
||||
|
||||
# local crates
|
||||
database_pool = { path = "../database_pool" }
|
||||
|
|
|
|||
15
crates/ezidam/src/cors.rs
Normal file
15
crates/ezidam/src/cors.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use rocket::{Build, Rocket};
|
||||
use rocket_cors::{Cors, CorsOptions};
|
||||
|
||||
fn cors() -> Cors {
|
||||
CorsOptions {
|
||||
allow_credentials: true,
|
||||
..Default::default()
|
||||
}
|
||||
.to_cors()
|
||||
.expect("Failed to configure CORS")
|
||||
}
|
||||
|
||||
pub fn rocket(rocket_builder: Rocket<Build>) -> Rocket<Build> {
|
||||
rocket_builder.attach(cors())
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
mod basic_auth;
|
||||
mod completed_setup;
|
||||
mod jwt;
|
||||
mod need_setup;
|
||||
|
|
@ -7,3 +8,4 @@ pub use self::jwt::*;
|
|||
pub use completed_setup::CompletedSetup;
|
||||
pub use need_setup::NeedSetup;
|
||||
pub use refresh_token::RefreshToken;
|
||||
pub use basic_auth::BasicAuth;
|
||||
|
|
|
|||
67
crates/ezidam/src/guards/basic_auth.rs
Normal file
67
crates/ezidam/src/guards/basic_auth.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
use base64::Engine;
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{FromRequest, Outcome};
|
||||
use rocket::Request;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BasicAuth {
|
||||
pub id: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BasicAuthError {
|
||||
BadCount,
|
||||
Invalid,
|
||||
Empty,
|
||||
Base64Decode,
|
||||
InvalidUtf8,
|
||||
Format,
|
||||
}
|
||||
|
||||
impl BasicAuth {
|
||||
fn from_base64(raw: &str) -> Result<Self, BasicAuthError> {
|
||||
// Make sure format is `Basic base64_string`
|
||||
if !raw.starts_with("Basic ") {
|
||||
return Err(BasicAuthError::Invalid);
|
||||
}
|
||||
|
||||
// Extract base64 encoded string
|
||||
let (_, base64) = raw.split_once(' ').ok_or(BasicAuthError::Empty)?;
|
||||
|
||||
// Decode base64 to bytes
|
||||
let decoded_bytes = base64::engine::general_purpose::URL_SAFE
|
||||
.decode(base64)
|
||||
.map_err(|_| BasicAuthError::Base64Decode)?;
|
||||
|
||||
// Convert bytes to string slice
|
||||
let decoded_str =
|
||||
std::str::from_utf8(&decoded_bytes).map_err(|_| BasicAuthError::InvalidUtf8)?;
|
||||
|
||||
// Extract id and password
|
||||
let (id, password) = decoded_str.split_once(':').ok_or(BasicAuthError::Format)?;
|
||||
|
||||
Ok(Self {
|
||||
id: id.to_string(),
|
||||
password: password.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'r> FromRequest<'r> for BasicAuth {
|
||||
type Error = BasicAuthError;
|
||||
|
||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
let keys: Vec<_> = request.headers().get("Authorization").collect();
|
||||
|
||||
match keys.len() {
|
||||
0 => Outcome::Forward(()),
|
||||
1 => match BasicAuth::from_base64(keys[0]) {
|
||||
Ok(auth_header) => Outcome::Success(auth_header),
|
||||
Err(e) => Outcome::Failure((Status::BadRequest, e)),
|
||||
},
|
||||
_ => Outcome::Failure((Status::BadRequest, BasicAuthError::BadCount)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
use rocket::{Build, Rocket};
|
||||
|
||||
mod cache;
|
||||
mod cors;
|
||||
mod database;
|
||||
mod error;
|
||||
mod file_from_bytes;
|
||||
|
|
@ -48,6 +49,9 @@ pub fn rocket_setup(rocket_builder: Rocket<Build>) -> Rocket<Build> {
|
|||
// Routes
|
||||
let rocket_builder = routes::routes(rocket_builder);
|
||||
|
||||
// CORS
|
||||
let rocket_builder = cors::rocket(rocket_builder);
|
||||
|
||||
// Errors
|
||||
let rocket_builder = catchers::register(rocket_builder);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue