diff --git a/backend/src/main.rs b/backend/src/main.rs index e4544e7..259e737 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,11 +1,12 @@ use rocket::fs::NamedFile; +use rocket::fs::TempFile; use rocket::http::Method; use rocket::http::Status; use rocket::response::Redirect; use rocket::response::{Responder, status}; use rocket::serde::{Deserialize, json::Json}; use rocket::uri; -use rocket::{self, get, launch, post, routes}; +use rocket::{self, get, launch, post, put, routes}; use rocket_cors::{AllowedOrigins, CorsOptions}; use std::env; use std::path::Path; @@ -16,6 +17,12 @@ use std::path::PathBuf; struct GenerationRequest<'r> { directory: &'r str, common_name: &'r str, + #[serde(default)] + email: &'r str, + #[serde(default)] + days: u32, + #[serde(default)] + use_openssl: Option, } #[derive(Responder)] @@ -90,11 +97,10 @@ async fn list_directories() -> Result>, status::Custom> let mut directories = Vec::new(); while let Ok(Some(entry)) = reader.next_entry().await { let path = entry.path(); - if check_is_valid_directory(&path).await.is_ok() { - if let Some(name) = path.file_name() { + if check_is_valid_directory(&path).await.is_ok() + && let Some(name) = path.file_name() { directories.push(name.to_str().unwrap().to_string()) } - } } Ok(Json(directories)) @@ -156,6 +162,37 @@ async fn get_file(directory: &str, file: &str) -> Result/", format = "plain", data = "")] +async fn put_file(directory: &str, name: &str, mut file: TempFile<'_>) -> status::Custom { + let dir = Path::new(&get_base_directory()).join(directory); + if check_is_valid_directory(&dir).await.is_err() { + return status::Custom( + Status::BadRequest, + "The specified directory is not valid".into(), + ); + } + + let dir = dir.join("config"); + let path = dir.join(name); + + // check if the file exists + match tokio::fs::metadata(&path).await { + Ok(meta) if meta.is_file() => {} + _ => { + return status::Custom(Status::NotFound, "The specified file is not found".into()); + } + } + + if let Err(msg) = file.persist_to(&path).await { + return status::Custom( + Status::InternalServerError, + format!("Failed to write file: {}", msg), + ); + } + + status::Custom(Status::NoContent, "".into()) +} + #[post("/generate", data = "")] async fn generate(request: Json>) -> Result { let dir = Path::new(&get_base_directory()).join(request.directory); @@ -163,12 +200,25 @@ async fn generate(request: Json>) -> Result 0 { + cmd.arg("--days").arg(request.days.to_string()); + } + // execute the command and check error code let status = cmd .status() @@ -225,7 +275,7 @@ fn rocket() -> _ { let cors = CorsOptions::default() .allowed_origins(AllowedOrigins::all()) .allowed_methods( - vec![Method::Get, Method::Post] + vec![Method::Get, Method::Post, Method::Put] .into_iter() .map(From::from) .collect(), @@ -235,7 +285,13 @@ fn rocket() -> _ { rocket::build() .mount( "/api/v1", - routes![list_directories, list_directory, get_file, generate], + routes![ + list_directories, + list_directory, + get_file, + put_file, + generate + ], ) .attach(cors.to_cors().unwrap()) .mount("/", routes![index_redirect, frontend])