From e2844a3866ffdde762abd24c29a8092ab4d880d9 Mon Sep 17 00:00:00 2001 From: EETagent Date: Sun, 30 Oct 2022 21:44:32 +0100 Subject: [PATCH] feat/refactor: rework guards, add upload data guards, code refactor --- api/src/guards/data/letter.rs | 43 +++++++++++++++++++ api/src/guards/data/mod.rs | 2 + api/src/guards/data/portfolio.rs | 43 +++++++++++++++++++ api/src/guards/mod.rs | 2 + .../request}/candidate_refresh_token.rs | 10 ++--- api/src/{guard => guards/request}/mod.rs | 0 api/src/lib.rs | 9 ++-- api/src/routes/mod.rs | 0 8 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 api/src/guards/data/letter.rs create mode 100644 api/src/guards/data/mod.rs create mode 100644 api/src/guards/data/portfolio.rs create mode 100644 api/src/guards/mod.rs rename api/src/{guard => guards/request}/candidate_refresh_token.rs (81%) rename api/src/{guard => guards/request}/mod.rs (100%) create mode 100644 api/src/routes/mod.rs diff --git a/api/src/guards/data/letter.rs b/api/src/guards/data/letter.rs new file mode 100644 index 0000000..0d3b3e8 --- /dev/null +++ b/api/src/guards/data/letter.rs @@ -0,0 +1,43 @@ +use rocket::data::{self, Data, FromData, ToByteUnit}; +use rocket::http::{ContentType, Status}; +use rocket::outcome::Outcome; +use rocket::request::Request; + +struct Letter(Vec); + +impl Into> for Letter { + fn into(self) -> Vec { + self.0 + } +} + +#[rocket::async_trait] +impl<'r> FromData<'r> for Letter { + type Error = Option; + + async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> { + let content_type_pdf = ContentType::new("application", "application/pdf"); + + if req.content_type() != Some(&content_type_pdf) { + return Outcome::Failure((Status::BadRequest, None)) + } + + let data = data.open(11.megabytes()); + + let data_bytes = data.into_bytes().await.unwrap(); + + if !data_bytes.is_complete() { + // TODO: Over limit + } + + let data_bytes = data_bytes.into_inner(); + + let is_pdf = portfolio_core::filetype::filetype_is_pdf(&data_bytes); + + if !is_pdf { + // TODO: Not ZIP + } + + Outcome::Success(Letter(data_bytes)) + } +} diff --git a/api/src/guards/data/mod.rs b/api/src/guards/data/mod.rs new file mode 100644 index 0000000..d305854 --- /dev/null +++ b/api/src/guards/data/mod.rs @@ -0,0 +1,2 @@ +pub mod portfolio; +pub mod letter; \ No newline at end of file diff --git a/api/src/guards/data/portfolio.rs b/api/src/guards/data/portfolio.rs new file mode 100644 index 0000000..8c3dd78 --- /dev/null +++ b/api/src/guards/data/portfolio.rs @@ -0,0 +1,43 @@ +use rocket::data::{self, Data, FromData, ToByteUnit}; +use rocket::http::{ContentType, Status}; +use rocket::outcome::Outcome; +use rocket::request::Request; + +struct Portfolio(Vec); + +impl Into> for Portfolio { + fn into(self) -> Vec { + self.0 + } +} + +#[rocket::async_trait] +impl<'r> FromData<'r> for Portfolio { + type Error = Option; + + async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> { + let content_type_pdf = ContentType::new("application", "application/zip"); + + if req.content_type() != Some(&content_type_pdf) { + return Outcome::Failure((Status::BadRequest, None)) + } + + let data = data.open(101.megabytes()); + + let data_bytes = data.into_bytes().await.unwrap(); + + if !data_bytes.is_complete() { + // TODO: Over limit + } + + let data_bytes = data_bytes.into_inner(); + + let is_pdf = portfolio_core::filetype::filetype_is_zip(&data_bytes); + + if !is_pdf { + // TODO: Not ZIP + } + + Outcome::Success(Portfolio(data_bytes)) + } +} diff --git a/api/src/guards/mod.rs b/api/src/guards/mod.rs new file mode 100644 index 0000000..0d72c60 --- /dev/null +++ b/api/src/guards/mod.rs @@ -0,0 +1,2 @@ +pub mod data; +pub mod request; \ No newline at end of file diff --git a/api/src/guard/candidate_refresh_token.rs b/api/src/guards/request/candidate_refresh_token.rs similarity index 81% rename from api/src/guard/candidate_refresh_token.rs rename to api/src/guards/request/candidate_refresh_token.rs index dee824d..cf91f1a 100644 --- a/api/src/guard/candidate_refresh_token.rs +++ b/api/src/guards/request/candidate_refresh_token.rs @@ -6,22 +6,22 @@ use rocket::request::{FromRequest, Request}; pub struct UUIDCookie(Uuid); -impl UUIDCookie { - pub fn value(self) -> Uuid { +impl Into for UUIDCookie { + fn into(self) -> Uuid { self.0 } } #[rocket::async_trait] impl<'r> FromRequest<'r> for UUIDCookie { - type Error = Status; - async fn from_request(req: &'r Request<'_>) -> Outcome { + type Error = Option; + async fn from_request(req: &'r Request<'_>) -> Outcome { let session_id = req.cookies().get("id").unwrap().name_value().1; println!("session_id: {}", session_id); match Uuid::parse_str(&session_id) { Ok(uuid) => Outcome::Success(UUIDCookie(uuid)), - Err(_) => return Outcome::Failure((Status::BadRequest, Status::BadRequest)), + Err(_) => return Outcome::Failure((Status::BadRequest, None)), } } } diff --git a/api/src/guard/mod.rs b/api/src/guards/request/mod.rs similarity index 100% rename from api/src/guard/mod.rs rename to api/src/guards/request/mod.rs diff --git a/api/src/lib.rs b/api/src/lib.rs index 33136ec..63e9dc3 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -18,8 +18,9 @@ use sea_orm_rocket::{Connection, Database}; mod pool; -mod guard; +mod guards; mod requests; +mod routes; use pool::Db; @@ -28,7 +29,7 @@ pub use entity::candidate::Entity as Candidate; use portfolio_core::crypto::random_8_char_string; -use crate::guard::candidate_refresh_token::UUIDCookie; +use crate::guards::request::candidate_refresh_token::UUIDCookie; fn custom_err_from_service_err(service_err: ServiceError) -> Custom { Custom(Status::from_code(service_err.0.code).unwrap_or_default(), service_err.1.to_string()) @@ -49,9 +50,9 @@ async fn create(conn: Connection<'_, Db>, post_form: Json) -> R } #[get("/whoami")] -async fn validate(conn: Connection<'_, Db>, uuid_cookie: Result) -> Result> { +async fn validate(conn: Connection<'_, Db>, uuid_cookie: Result>) -> Result> { let db = conn.into_inner(); - let user = CandidateService::auth_user_session(db, uuid_cookie.ok().unwrap().value()).await; + let user = CandidateService::auth_user_session(db, uuid_cookie.ok().unwrap().into()).await; match user { diff --git a/api/src/routes/mod.rs b/api/src/routes/mod.rs new file mode 100644 index 0000000..e69de29