From 7b4707fae6ba87846ef57ad3d985b1aff68fc86d Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Tue, 8 Nov 2022 01:22:10 +0100 Subject: [PATCH] feat: get candidate details --- api/src/lib.rs | 1 + api/src/requests.rs | 6 ++++ api/src/routes/candidate.rs | 47 ++++++++++++++++++++++++++ core/src/crypto.rs | 10 +++--- core/src/services/candidate_service.rs | 13 ++++--- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/api/src/lib.rs b/api/src/lib.rs index cd1550d..0df83fc 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -42,6 +42,7 @@ async fn start() -> Result<(), rocket::Error> { routes::candidate::login, routes::candidate::whoami, routes::candidate::fill_details, + routes::candidate::get_details, ], ) .mount( diff --git a/api/src/requests.rs b/api/src/requests.rs index 088321e..5288901 100644 --- a/api/src/requests.rs +++ b/api/src/requests.rs @@ -21,4 +21,10 @@ pub struct RegisterRequest { pub struct AdminLoginRequest { pub admin_id: i32, pub password: String, +} + +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct PasswordRequest { + pub password: String, } \ No newline at end of file diff --git a/api/src/routes/candidate.rs b/api/src/routes/candidate.rs index 1f2ccfb..6f32225 100644 --- a/api/src/routes/candidate.rs +++ b/api/src/routes/candidate.rs @@ -8,6 +8,7 @@ use rocket::serde::json::Json; use sea_orm_rocket::Connection; +use crate::requests::PasswordRequest; use crate::{guards::request::auth::CandidateAuth, pool::Db, requests}; #[post("/login", data = "")] @@ -70,3 +71,49 @@ pub async fn fill_details( Ok("Details added".to_string()) } + +#[post("/get_details", data = "")] +pub async fn get_details( + conn: Connection<'_, Db>, + password_form: Json, + session: CandidateAuth, +) -> Result, Custom> { + let db = conn.into_inner(); + let candidate: entity::candidate::Model = session.into(); + let password = password_form.password.clone(); + + // let handle = tokio::spawn(async move { + let details = CandidateService::decrypt_details(db, candidate.application, password).await.map_err(|e| { + Custom( + Status::from_code(e.code()).unwrap_or_default(), + e.message(), + ) + }); + + details.map(|d| Json(d)) +} + +// #[post("/details", data = "")] +// pub async fn get_details( +// conn: Connection<'_, Db>, +// password_form: Json, +// session: CandidateAuth, +// ) -> Result> { +// let db = conn.into_inner(); +// let candidate: entity::candidate::Model = session.into(); +// let password = password_form.password.clone(); + +// let details = CandidateService::decrypt_details(db, candidate.application, password).await; + +// if details.is_err() { +// // TODO cleanup +// let e = details.err().unwrap(); +// return Err(Custom( +// Status::from_code(e.code()).unwrap_or_default(), +// e.message(), +// )); +// } + +// // Ok(Json(details.unwrap())) +// Ok("coming soon".to_string()) +// } diff --git a/core/src/crypto.rs b/core/src/crypto.rs index 8614a87..ec1a973 100644 --- a/core/src/crypto.rs +++ b/core/src/crypto.rs @@ -11,6 +11,8 @@ use std::iter; use std::path::Path; use std::str::FromStr; +use crate::error::ServiceError; + /// Foolproof random 8 char string /// only uppercase letters (except for 0 and O) and numbers /// TODO tests @@ -265,14 +267,14 @@ pub async fn encrypt_password_with_recipients( pub async fn decrypt_password_with_private_key( password_encrypted: &str, key: &str, -) -> Result> { - let encrypted = base64::decode(password_encrypted)?; +) -> Result { + let encrypted = base64::decode(password_encrypted).unwrap(); let mut decrypt_buffer = Vec::new(); - age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await?; + age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await.unwrap(); - Ok(String::from_utf8(decrypt_buffer)?) + Ok(String::from_utf8(decrypt_buffer).ok().unwrap()) } pub async fn encrypt_file_with_recipients>( diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index 6f6fd5c..53bf992 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -1,6 +1,6 @@ use entity::candidate; use sea_orm::{prelude::Uuid, DbConn}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use crate::{ crypto::{self, hash_password}, @@ -169,7 +169,7 @@ impl EncryptedUserDetails { } } -#[derive(Debug, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct UserDetails { pub name: String, pub surname: String, @@ -273,11 +273,10 @@ impl CandidateService { candidate_id: i32, password: String, ) -> Result { - // compare passwords // TODO: login in api?? // TODO: dedicated function - let candidate = Query::find_candidate_by_id(db, candidate_id) - .await - .map_err(|_| ServiceError::DbError)? - .ok_or(ServiceError::UserNotFound)?; + let candidate = match Query::find_candidate_by_id(db, candidate_id).await { + Ok(candidate) => candidate.unwrap(), + Err(_) => return Err(ServiceError::DbError), // TODO: logging + }; match crypto::verify_password((&password).to_string(), candidate.code.clone()).await { Ok(valid) => {