use std::env; use rocket::{Request, http::Status, request::{FromRequest, Outcome}}; use reqwest::Client; pub struct AdminAuth(pub String); #[rocket::async_trait] impl<'r> FromRequest<'r> for AdminAuth { type Error = (); async fn from_request(req: &'r Request<'_>) -> Outcome { let use_admin_server = env::var("USE_ADMIN_AUTH") .map(|v| v == "true") .unwrap_or(false); if use_admin_server { let auth = match req.headers().get_one("Authorization") { Some(auth) => auth, None => return Outcome::Error((Status::BadRequest, ())), }; let auth_url = match env::var("ADMIN_AUTH_URL") { Ok(url) => url, Err(_) => return Outcome::Error((Status::InternalServerError, ())), }; let auth_token = match env::var("ADMIN_AUTH_TOKEN") { Ok(url) => url, Err(_) => return Outcome::Error((Status::InternalServerError, ())), }; let http = Client::new(); let response = http.get(format!("{}/api/v1/validate_token/boss", auth_url)) .header("Authorization", format!("InterServer {}", auth_token)) .header("Token", auth) .send() .await; match response { Ok(response) => { match response.error_for_status() { Ok(response) => match response.text().await { Ok(text) => return Outcome::Success(AdminAuth(text)), Err(_) => return Outcome::Error((Status::InternalServerError, ())) }, Err(_) => { return Outcome::Error((Status::Unauthorized, ())); } } }, Err(_) => return Outcome::Error((Status::InternalServerError, ())), } } else { let local_token = match env::var("ADMIN_AUTH_TOKEN") { Ok(token) => token, Err(_) => return Outcome::Error((Status::InternalServerError, ())) }; let token = match req.headers().get_one("Authorization") { Some(auth) => match auth.strip_prefix("Bearer ") { Some(token) => token, None => return Outcome::Error((Status::BadRequest, ())) }, None => return Outcome::Error((Status::BadRequest, ())), }; if token != local_token.as_str() { return Outcome::Error((Status::Unauthorized, ())) } Outcome::Success(AdminAuth("admin".to_string())) } } }