feat: application details structure

This commit is contained in:
Sebastian Pravda 2022-12-05 15:21:30 +01:00
parent 904f8732d6
commit 1262eda871
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
9 changed files with 267 additions and 202 deletions

View file

@ -240,21 +240,25 @@ mod tests {
} }
const CANDIDATE_DETAILS: &'static str = "{ const CANDIDATE_DETAILS: &'static str = "{
\"name\": \"idk\", \"candidate\": {
\"surname\": \"idk\", \"name\": \"idk\",
\"birthplace\": \"Praha 1\", \"surname\": \"idk\",
\"birthdate\": \"2015-09-18\", \"birthplace\": \"Praha 1\",
\"address\": \"Stefanikova jidelna\", \"birthdate\": \"2015-09-18\",
\"telephone\": \"000111222333\", \"address\": \"Stefanikova jidelna\",
\"citizenship\": \"Czech Republic\", \"telephone\": \"000111222333\",
\"email\": \"magor@magor.cz\", \"citizenship\": \"Czech Republic\",
\"sex\": \"MALE\", \"email\": \"magor@magor.cz\",
\"personalIdNumber\": \"0000000000\", \"sex\": \"MALE\",
\"study\": \"KB\", \"personalIdNumber\": \"0000000000\",
\"parentName\": \"maminka\", \"study\": \"KB\"
\"parentSurname\": \"chad\", },
\"parentTelephone\": \"420111222333\", \"parent\": {
\"parentEmail\": \"maminka@centrum.cz\" \"name\": \"maminka\",
\"surname\": \"chad\",
\"telephone\": \"420111222333\",
\"email\": \"maminka@centrum.cz\"
}
}"; }";
#[test] #[test]

View file

@ -1,4 +1,4 @@
use crate::{Mutation, models::candidate_details::EncryptedApplicationDetails}; use crate::{Mutation, models::candidate_details::{EncryptedCandidateDetails}};
use ::entity::candidate::{self}; use ::entity::candidate::{self};
use sea_orm::*; use sea_orm::*;
@ -44,20 +44,20 @@ impl Mutation {
pub async fn add_candidate_details( pub async fn add_candidate_details(
db: &DbConn, db: &DbConn,
user: candidate::Model, user: candidate::Model,
enc_details: EncryptedApplicationDetails, enc_candidate: EncryptedCandidateDetails,
) -> Result<candidate::Model, sea_orm::DbErr> { ) -> Result<candidate::Model, sea_orm::DbErr> {
let mut user: candidate::ActiveModel = user.into(); let mut user: candidate::ActiveModel = user.into();
user.name = Set(Some(enc_details.name.into())); user.name = Set(Some(enc_candidate.name.into()));
user.surname = Set(Some(enc_details.surname.into())); user.surname = Set(Some(enc_candidate.surname.into()));
user.birthplace = Set(Some(enc_details.birthplace.into())); user.birthplace = Set(Some(enc_candidate.birthplace.into()));
user.birthdate = Set(Some(enc_details.birthdate.into())); user.birthdate = Set(Some(enc_candidate.birthdate.into()));
user.address = Set(Some(enc_details.address.into())); user.address = Set(Some(enc_candidate.address.into()));
user.telephone = Set(Some(enc_details.telephone.into())); user.telephone = Set(Some(enc_candidate.telephone.into()));
user.citizenship = Set(Some(enc_details.citizenship.into())); user.citizenship = Set(Some(enc_candidate.citizenship.into()));
user.email = Set(Some(enc_details.email.into())); user.email = Set(Some(enc_candidate.email.into()));
user.sex = Set(Some(enc_details.sex.into())); user.sex = Set(Some(enc_candidate.sex.into()));
user.personal_identification_number = Set(enc_details.personal_id_number.into()); // TODO: do not set this here, it is already set in the create_candidate mutation??? user.personal_identification_number = Set(enc_candidate.personal_id_number.into()); // TODO: do not set this here, it is already set in the create_candidate mutation???
user.study = Set(Some(enc_details.study.into())); user.study = Set(Some(enc_candidate.study.into()));
user.updated_at = Set(chrono::offset::Local::now().naive_local()); user.updated_at = Set(chrono::offset::Local::now().naive_local());
@ -117,7 +117,7 @@ mod tests {
vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()], vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()],
).await.unwrap(); ).await.unwrap();
Mutation::add_candidate_details(&db, candidate, encrypted_details).await.unwrap(); Mutation::add_candidate_details(&db, candidate, encrypted_details.candidate).await.unwrap();
let candidate = Query::find_candidate_by_id(&db, APPLICATION_ID) let candidate = Query::find_candidate_by_id(&db, APPLICATION_ID)
.await .await

View file

@ -1,4 +1,4 @@
use crate::{Mutation, models::candidate_details::EncryptedApplicationDetails}; use crate::{Mutation, models::candidate_details::{EncryptedParentDetails}};
use ::entity::parent::{self, Model}; use ::entity::parent::{self, Model};
use sea_orm::*; use sea_orm::*;
@ -18,13 +18,13 @@ impl Mutation {
pub async fn add_parent_details( pub async fn add_parent_details(
db: &DbConn, db: &DbConn,
parent: Model, parent: Model,
enc_details: EncryptedApplicationDetails, // TODO: use seperate struct?? enc_parent: EncryptedParentDetails,
) -> Result<Model, sea_orm::DbErr> { ) -> Result<Model, sea_orm::DbErr> {
let mut user: parent::ActiveModel = parent.into(); let mut user: parent::ActiveModel = parent.into();
user.name = Set(Some(enc_details.parent_name.into())); user.name = Set(Some(enc_parent.name.into()));
user.surname = Set(Some(enc_details.parent_surname.into())); user.surname = Set(Some(enc_parent.surname.into()));
user.telephone = Set(Some(enc_details.parent_telephone.into())); user.telephone = Set(Some(enc_parent.telephone.into()));
user.email = Set(Some(enc_details.parent_email.into())); user.email = Set(Some(enc_parent.email.into()));
user.updated_at = Set(chrono::offset::Local::now().naive_local()); user.updated_at = Set(chrono::offset::Local::now().naive_local());
@ -88,7 +88,7 @@ mod tests {
.await .await
.unwrap(); .unwrap();
Mutation::add_parent_details(&db, parent, encrypted_details) Mutation::add_parent_details(&db, parent, encrypted_details.parent)
.await .await
.unwrap(); .unwrap();

View file

@ -27,11 +27,10 @@ pub struct BaseCandidateResponse {
pub submitted: bool, pub submitted: bool,
} }
/// Candidate details (admin and candidate endpoints)
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ApplicationDetails { pub struct CandidateDetails {
// Candidate // pub application_id: i32,
pub name: String, pub name: String,
pub surname: String, pub surname: String,
pub birthplace: String, pub birthplace: String,
@ -43,12 +42,49 @@ pub struct ApplicationDetails {
pub sex: String, pub sex: String,
pub study: String, pub study: String,
pub personal_id_number: String, pub personal_id_number: String,
// Parent
pub parent_name: String,
pub parent_surname: String,
pub parent_telephone: String,
pub parent_email: String,
} }
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ParentDetails {
// pub application_id: i32,
pub name: String,
pub surname: String,
pub telephone: String,
pub email: String,
}
/// Candidate details (admin and candidate endpoints)
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplicationDetails {
// Candidate
pub candidate: CandidateDetails,
pub parent: ParentDetails,
// pub opt_parent2: Option<ParentDetails>,
}
/* impl ApplicationDetails {
pub fn new_one_parent(
candidate: CandidateDetails,
parent: ParentDetails,
) -> Self {
Self {
candidate,
parent,
opt_parent2: None,
}
}
pub fn new_two_parents(
candidate: CandidateDetails,
parent: ParentDetails,
opt_parent2: ParentDetails,
) -> Self {
Self {
candidate,
parent,
opt_parent2: Some(opt_parent2),
}
}
} */
/// CSV export (admin endpoint) /// CSV export (admin endpoint)
#[derive(FromQueryResult, Serialize, Default)] #[derive(FromQueryResult, Serialize, Default)]

View file

@ -4,14 +4,15 @@ use entity::{candidate, parent};
use crate::{crypto, models::candidate::{CandidateWithParent, ApplicationDetails}, error::ServiceError}; use crate::{crypto, models::candidate::{CandidateWithParent, ApplicationDetails}, error::ServiceError};
use super::candidate::{CandidateDetails, ParentDetails};
pub const NAIVE_DATE_FMT: &str = "%Y-%m-%d"; pub const NAIVE_DATE_FMT: &str = "%Y-%m-%d";
#[derive(Clone)] #[derive(Clone)]
pub struct EncryptedString(String); pub struct EncryptedString(String);
#[derive(Clone)] #[derive(Clone)]
pub struct EncryptedApplicationDetails { pub struct EncryptedCandidateDetails {
// Candidate
pub name: EncryptedString, pub name: EncryptedString,
pub surname: EncryptedString, pub surname: EncryptedString,
pub birthplace: EncryptedString, pub birthplace: EncryptedString,
@ -23,12 +24,19 @@ pub struct EncryptedApplicationDetails {
pub sex: EncryptedString, pub sex: EncryptedString,
pub personal_id_number: EncryptedString, pub personal_id_number: EncryptedString,
pub study: String, pub study: String,
}
// Parent #[derive(Clone)]
pub parent_name: EncryptedString, pub struct EncryptedParentDetails {
pub parent_surname: EncryptedString, pub name: EncryptedString,
pub parent_telephone: EncryptedString, pub surname: EncryptedString,
pub parent_email: EncryptedString, pub telephone: EncryptedString,
pub email: EncryptedString,
}
#[derive(Clone)]
pub struct EncryptedApplicationDetails {
pub candidate: EncryptedCandidateDetails,
pub parent: EncryptedParentDetails,
} }
impl EncryptedString { impl EncryptedString {
@ -91,80 +99,89 @@ impl EncryptedApplicationDetails {
form: &ApplicationDetails, form: &ApplicationDetails,
recipients: Vec<String>, recipients: Vec<String>,
) -> Result<EncryptedApplicationDetails, ServiceError> { ) -> Result<EncryptedApplicationDetails, ServiceError> {
let birthdate_str = form.birthdate.format(NAIVE_DATE_FMT).to_string(); let birthdate_str = form.candidate.birthdate.format(NAIVE_DATE_FMT).to_string();
let d = tokio::try_join!( let d = tokio::try_join!(
EncryptedString::new(&form.name, &recipients), EncryptedString::new(&form.candidate.name, &recipients),
EncryptedString::new(&form.surname, &recipients), EncryptedString::new(&form.candidate.surname, &recipients),
EncryptedString::new(&form.birthplace, &recipients), EncryptedString::new(&form.candidate.birthplace, &recipients),
EncryptedString::new(&birthdate_str, &recipients), EncryptedString::new(&birthdate_str, &recipients),
EncryptedString::new(&form.address, &recipients), EncryptedString::new(&form.candidate.address, &recipients),
EncryptedString::new(&form.telephone, &recipients), EncryptedString::new(&form.candidate.telephone, &recipients),
EncryptedString::new(&form.citizenship, &recipients), EncryptedString::new(&form.candidate.citizenship, &recipients),
EncryptedString::new(&form.email, &recipients), EncryptedString::new(&form.candidate.email, &recipients),
EncryptedString::new(&form.sex, &recipients), EncryptedString::new(&form.candidate.sex, &recipients),
EncryptedString::new(&form.personal_id_number, &recipients), EncryptedString::new(&form.candidate.personal_id_number, &recipients),
EncryptedString::new(&form.parent_name, &recipients), EncryptedString::new(&form.parent.name, &recipients),
EncryptedString::new(&form.parent_surname, &recipients), EncryptedString::new(&form.parent.surname, &recipients),
EncryptedString::new(&form.parent_telephone, &recipients), EncryptedString::new(&form.parent.telephone, &recipients),
EncryptedString::new(&form.parent_email, &recipients), EncryptedString::new(&form.parent.email, &recipients),
)?; )?;
Ok(EncryptedApplicationDetails { Ok(EncryptedApplicationDetails {
name: d.0, candidate: EncryptedCandidateDetails {
surname: d.1, name: d.0,
birthplace: d.2, surname: d.1,
birthdate: d.3, birthplace: d.2,
address: d.4, birthdate: d.3,
telephone: d.5, address: d.4,
citizenship: d.6, telephone: d.5,
email: d.7, citizenship: d.6,
sex: d.8, email: d.7,
personal_id_number: d.9, sex: d.8,
study: form.study.clone(), personal_id_number: d.9,
study: form.candidate.study.clone(),
},
parent: EncryptedParentDetails {
name: d.10,
surname: d.11,
telephone: d.12,
email: d.13,
}
parent_name: d.10,
parent_surname: d.11,
parent_telephone: d.12,
parent_email: d.13,
}) })
} }
pub async fn decrypt(self, priv_key: String) -> Result<ApplicationDetails, ServiceError> { pub async fn decrypt(self, priv_key: String) -> Result<ApplicationDetails, ServiceError> {
let d = tokio::try_join!( let d = tokio::try_join!(
self.name.decrypt(&priv_key), // 0 self.candidate.name.decrypt(&priv_key), // 0
self.surname.decrypt(&priv_key), // 1 self.candidate.surname.decrypt(&priv_key), // 1
self.birthplace.decrypt(&priv_key), // 2 self.candidate.birthplace.decrypt(&priv_key), // 2
self.birthdate.decrypt(&priv_key), // 3 self.candidate.birthdate.decrypt(&priv_key), // 3
self.address.decrypt(&priv_key), // 4 self.candidate.address.decrypt(&priv_key), // 4
self.telephone.decrypt(&priv_key), // 5 self.candidate.telephone.decrypt(&priv_key), // 5
self.citizenship.decrypt(&priv_key), // 6 self.candidate.citizenship.decrypt(&priv_key), // 6
self.email.decrypt(&priv_key), // 7 self.candidate.email.decrypt(&priv_key), // 7
self.sex.decrypt(&priv_key), // 8 self.candidate.sex.decrypt(&priv_key), // 8
self.personal_id_number.decrypt(&priv_key),// 9 self.candidate.personal_id_number.decrypt(&priv_key),// 9
self.parent_name.decrypt(&priv_key), // 10 self.parent.name.decrypt(&priv_key), // 10
self.parent_surname.decrypt(&priv_key), // 11 self.parent.surname.decrypt(&priv_key), // 11
self.parent_telephone.decrypt(&priv_key), // 12 self.parent.telephone.decrypt(&priv_key), // 12
self.parent_email.decrypt(&priv_key), // 13 self.parent.email.decrypt(&priv_key), // 13
)?; )?;
Ok(ApplicationDetails { Ok(ApplicationDetails {
name: d.0, candidate: CandidateDetails {
surname: d.1, name: d.0,
birthplace: d.2, surname: d.1,
birthdate: NaiveDate::parse_from_str(&d.3, NAIVE_DATE_FMT).unwrap(), // TODO birthplace: d.2,
address: d.4, birthdate: NaiveDate::parse_from_str(&d.3, NAIVE_DATE_FMT).unwrap(), // TODO
telephone: d.5, address: d.4,
citizenship: d.6, telephone: d.5,
email: d.7, citizenship: d.6,
sex: d.8, email: d.7,
personal_id_number: d.9, sex: d.8,
study: self.study, personal_id_number: d.9,
study: self.candidate.study,
},
parent: ParentDetails {
name: d.10,
surname: d.11,
telephone: d.12,
email: d.13,
}
parent_name: d.10,
parent_surname: d.11,
parent_telephone: d.12,
parent_email: d.13,
}) })
} }
} }
@ -176,22 +193,26 @@ impl TryFrom<(candidate::Model, parent::Model)> for EncryptedApplicationDetails
(candidate, parent): (candidate::Model, parent::Model), (candidate, parent): (candidate::Model, parent::Model),
) -> Result<Self, Self::Error> { ) -> Result<Self, Self::Error> {
Ok(EncryptedApplicationDetails { Ok(EncryptedApplicationDetails {
name: EncryptedString::try_from(candidate.name)?, candidate: EncryptedCandidateDetails {
surname: EncryptedString::try_from(candidate.surname)?, name: EncryptedString::try_from(candidate.name)?,
birthplace: EncryptedString::try_from(candidate.birthplace)?, surname: EncryptedString::try_from(candidate.surname)?,
birthdate: EncryptedString::try_from(candidate.birthdate)?, birthplace: EncryptedString::try_from(candidate.birthplace)?,
address: EncryptedString::try_from(candidate.address)?, birthdate: EncryptedString::try_from(candidate.birthdate)?,
telephone: EncryptedString::try_from(candidate.telephone)?, address: EncryptedString::try_from(candidate.address)?,
citizenship: EncryptedString::try_from(candidate.citizenship)?, telephone: EncryptedString::try_from(candidate.telephone)?,
email: EncryptedString::try_from(candidate.email)?, citizenship: EncryptedString::try_from(candidate.citizenship)?,
sex: EncryptedString::try_from(candidate.sex)?, email: EncryptedString::try_from(candidate.email)?,
personal_id_number: EncryptedString::from(candidate.personal_identification_number), sex: EncryptedString::try_from(candidate.sex)?,
study: candidate.study.ok_or(ServiceError::CandidateDetailsNotSet)?, personal_id_number: EncryptedString::from(candidate.personal_identification_number),
study: candidate.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
},
parent: EncryptedParentDetails {
name: EncryptedString::try_from(parent.name)?,
surname: EncryptedString::try_from(parent.surname)?,
telephone: EncryptedString::try_from(parent.telephone)?,
email: EncryptedString::try_from(parent.email)?,
}
parent_name: EncryptedString::try_from(parent.name)?,
parent_surname: EncryptedString::try_from(parent.surname)?,
parent_telephone: EncryptedString::try_from(parent.telephone)?,
parent_email: EncryptedString::try_from(parent.email)?,
}) })
} }
} }
@ -203,22 +224,26 @@ impl TryFrom<CandidateWithParent> for EncryptedApplicationDetails {
cp: CandidateWithParent, cp: CandidateWithParent,
) -> Result<Self, Self::Error> { ) -> Result<Self, Self::Error> {
Ok(EncryptedApplicationDetails { Ok(EncryptedApplicationDetails {
name: EncryptedString::try_from(cp.name)?, candidate: EncryptedCandidateDetails {
surname: EncryptedString::try_from(cp.surname)?, name: EncryptedString::try_from(cp.name)?,
birthplace: EncryptedString::try_from(cp.birthplace)?, surname: EncryptedString::try_from(cp.surname)?,
birthdate: EncryptedString::try_from(cp.birthdate)?, birthplace: EncryptedString::try_from(cp.birthplace)?,
address: EncryptedString::try_from(cp.address)?, birthdate: EncryptedString::try_from(cp.birthdate)?,
telephone: EncryptedString::try_from(cp.telephone)?, address: EncryptedString::try_from(cp.address)?,
citizenship: EncryptedString::try_from(cp.citizenship)?, telephone: EncryptedString::try_from(cp.telephone)?,
email: EncryptedString::try_from(cp.email)?, citizenship: EncryptedString::try_from(cp.citizenship)?,
sex: EncryptedString::try_from(cp.sex)?, email: EncryptedString::try_from(cp.email)?,
personal_id_number: EncryptedString::try_from(cp.personal_identification_number)?, sex: EncryptedString::try_from(cp.sex)?,
study: cp.study.ok_or(ServiceError::CandidateDetailsNotSet)?, personal_id_number: EncryptedString::try_from(cp.personal_identification_number)?,
study: cp.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
},
parent: EncryptedParentDetails {
name: EncryptedString::try_from(cp.parent_name)?,
surname: EncryptedString::try_from(cp.parent_surname)?,
telephone: EncryptedString::try_from(cp.parent_telephone)?,
email: EncryptedString::try_from(cp.parent_email)?,
}
parent_name: EncryptedString::try_from(cp.parent_name)?,
parent_surname: EncryptedString::try_from(cp.parent_surname)?,
parent_telephone: EncryptedString::try_from(cp.parent_telephone)?,
parent_email: EncryptedString::try_from(cp.parent_email)?,
}) })
} }
} }
@ -240,7 +265,7 @@ pub mod tests {
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use crate::crypto; use crate::{crypto, models::candidate::{CandidateDetails, ParentDetails}};
use super::{ApplicationDetails, EncryptedApplicationDetails, EncryptedString}; use super::{ApplicationDetails, EncryptedApplicationDetails, EncryptedString};
@ -249,40 +274,44 @@ pub mod tests {
pub static APPLICATION_DETAILS: Lazy<Mutex<ApplicationDetails>> = Lazy::new(|| pub static APPLICATION_DETAILS: Lazy<Mutex<ApplicationDetails>> = Lazy::new(||
Mutex::new(ApplicationDetails { Mutex::new(ApplicationDetails {
name: "name".to_string(), candidate: CandidateDetails {
surname: "surname".to_string(), name: "name".to_string(),
birthplace: "birthplace".to_string(), surname: "surname".to_string(),
birthdate: chrono::NaiveDate::from_ymd(2000, 1, 1), birthplace: "birthplace".to_string(),
address: "address".to_string(), birthdate: chrono::NaiveDate::from_ymd(2000, 1, 1),
telephone: "telephone".to_string(), address: "address".to_string(),
citizenship: "citizenship".to_string(), telephone: "telephone".to_string(),
email: "email".to_string(), citizenship: "citizenship".to_string(),
sex: "sex".to_string(), email: "email".to_string(),
personal_id_number: "personal_id_number".to_string(), sex: "sex".to_string(),
study: "study".to_string(), personal_id_number: "personal_id_number".to_string(),
parent_email: "parent_email".to_string(), study: "study".to_string(),
parent_name: "parent_name".to_string(), },
parent_surname: "parent_surname".to_string(), parent: ParentDetails {
parent_telephone: "parent_telephone".to_string() email: "parent_email".to_string(),
name: "parent_name".to_string(),
surname: "parent_surname".to_string(),
telephone: "parent_telephone".to_string()
}
}) })
); );
pub fn assert_all_application_details(details: &ApplicationDetails) { pub fn assert_all_application_details(details: &ApplicationDetails) {
assert_eq!(details.name, "name"); assert_eq!(details.candidate.name, "name");
assert_eq!(details.surname, "surname"); assert_eq!(details.candidate.surname, "surname");
assert_eq!(details.birthplace, "birthplace"); assert_eq!(details.candidate.birthplace, "birthplace");
assert_eq!(details.birthdate, chrono::NaiveDate::from_ymd(2000, 1, 1)); assert_eq!(details.candidate.birthdate, chrono::NaiveDate::from_ymd(2000, 1, 1));
assert_eq!(details.address, "address"); assert_eq!(details.candidate.address, "address");
assert_eq!(details.telephone, "telephone"); assert_eq!(details.candidate.telephone, "telephone");
assert_eq!(details.citizenship, "citizenship"); assert_eq!(details.candidate.citizenship, "citizenship");
assert_eq!(details.email, "email"); assert_eq!(details.candidate.email, "email");
assert_eq!(details.sex, "sex"); assert_eq!(details.candidate.sex, "sex");
assert_eq!(details.study, "study"); assert_eq!(details.candidate.study, "study");
assert_eq!(details.personal_id_number, "personal_id_number"); assert_eq!(details.candidate.personal_id_number, "personal_id_number");
assert_eq!(details.parent_name, "parent_name"); assert_eq!(details.parent.name, "parent_name");
assert_eq!(details.parent_surname, "parent_surname"); assert_eq!(details.parent.surname, "parent_surname");
assert_eq!(details.parent_telephone, "parent_telephone"); assert_eq!(details.parent.telephone, "parent_telephone");
assert_eq!(details.parent_email, "parent_email"); assert_eq!(details.parent.email, "parent_email");
} }
#[tokio::test] #[tokio::test]
@ -295,19 +324,19 @@ pub mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.name.0, PRIVATE_KEY) crypto::decrypt_password_with_private_key(&encrypted_details.candidate.name.0, PRIVATE_KEY)
.await .await
.unwrap(), .unwrap(),
"name" "name"
); );
assert_eq!( assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.email.0, PRIVATE_KEY) crypto::decrypt_password_with_private_key(&encrypted_details.candidate.email.0, PRIVATE_KEY)
.await .await
.unwrap(), .unwrap(),
"email" "email"
); );
assert_eq!( assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.sex.0, PRIVATE_KEY) crypto::decrypt_password_with_private_key(&encrypted_details.candidate.sex.0, PRIVATE_KEY)
.await .await
.unwrap(), .unwrap(),
"sex" "sex"

View file

@ -15,12 +15,6 @@ impl ApplicationService {
personal_id_number: String, personal_id_number: String,
) -> Result<(candidate::Model, parent::Model), ServiceError> { ) -> Result<(candidate::Model, parent::Model), ServiceError> {
Ok( Ok(
/* tokio::try_join!( // TODO: try_join! is not working
CandidateService::create(db, application_id, plain_text_password, personal_id_number),
ParentService::create(db, application_id)
)? */
( (
CandidateService::create(db, application_id, plain_text_password, personal_id_number).await?, CandidateService::create(db, application_id, plain_text_password, personal_id_number).await?,
ParentService::create(db, application_id).await? ParentService::create(db, application_id).await?
@ -47,8 +41,8 @@ impl ApplicationService {
Ok( Ok(
tokio::try_join!( tokio::try_join!(
CandidateService::add_candidate_details(db, candidate, enc_details.clone()), CandidateService::add_candidate_details(db, candidate, enc_details.candidate),
ParentService::add_parent_details(db, parent, enc_details.clone()) ParentService::add_parent_details(db, parent, enc_details.parent)
)? )?
) )
} }

View file

@ -2,7 +2,7 @@ use entity::candidate;
use sea_orm::{prelude::Uuid, DbConn}; use sea_orm::{prelude::Uuid, DbConn};
use crate::{ use crate::{
models::candidate_details::{EncryptedApplicationDetails, EncryptedString}, models::candidate_details::{EncryptedApplicationDetails, EncryptedString, EncryptedCandidateDetails},
crypto::{self, hash_password}, crypto::{self, hash_password},
error::ServiceError, error::ServiceError,
Mutation, Query, models::candidate::{BaseCandidateResponse, CreateCandidateResponse}, utils::db::get_recipients, Mutation, Query, models::candidate::{BaseCandidateResponse, CreateCandidateResponse}, utils::db::get_recipients,
@ -150,9 +150,9 @@ impl CandidateService {
pub(in crate::services) async fn add_candidate_details( pub(in crate::services) async fn add_candidate_details(
db: &DbConn, db: &DbConn,
candidate: candidate::Model, candidate: candidate::Model,
enc_details: EncryptedApplicationDetails, enc_details: EncryptedCandidateDetails,
) -> Result<entity::candidate::Model, ServiceError> { ) -> Result<entity::candidate::Model, ServiceError> {
let model = Mutation::add_candidate_details(db, candidate, enc_details.clone()).await?; let model = Mutation::add_candidate_details(db, candidate, enc_details).await?;
Ok(model) Ok(model)
} }

View file

@ -1,7 +1,7 @@
use entity::{parent}; use entity::{parent};
use sea_orm::DbConn; use sea_orm::DbConn;
use crate::{error::ServiceError, Mutation, models::candidate_details::EncryptedApplicationDetails}; use crate::{error::ServiceError, Mutation, models::candidate_details::{EncryptedParentDetails}};
pub struct ParentService; pub struct ParentService;
@ -19,7 +19,7 @@ impl ParentService {
pub async fn add_parent_details( pub async fn add_parent_details(
db: &DbConn, db: &DbConn,
parent: parent::Model, parent: parent::Model,
enc_details: EncryptedApplicationDetails, enc_details: EncryptedParentDetails,
) -> Result<parent::Model, ServiceError> { ) -> Result<parent::Model, ServiceError> {
let parent = Mutation::add_parent_details(db, parent, enc_details) let parent = Mutation::add_parent_details(db, parent, enc_details)
.await?; .await?;

View file

@ -6,24 +6,26 @@ type Row = CandidateWithParent;
impl From<(i32, ApplicationDetails)> for Row { impl From<(i32, ApplicationDetails)> for Row {
fn from((application, d): (i32, ApplicationDetails)) -> Self { fn from((application, d): (i32, ApplicationDetails)) -> Self {
let c = d.candidate;
let p = d.parent;
Self { Self {
application, application,
name: Some(d.name), name: Some(c.name),
surname: Some(d.surname), surname: Some(c.surname),
birthplace: Some(d.birthplace), birthplace: Some(c.birthplace),
birthdate: Some(d.birthdate.to_string()), birthdate: Some(c.birthdate.to_string()),
address: Some(d.address), address: Some(c.address),
telephone: Some(d.telephone), telephone: Some(c.telephone),
citizenship: Some(d.citizenship), citizenship: Some(c.citizenship),
email: Some(d.email), email: Some(c.email),
sex: Some(d.sex), sex: Some(c.sex),
study: Some(d.study), study: Some(c.study),
personal_identification_number: Some(d.personal_id_number), personal_identification_number: Some(c.personal_id_number),
parent_name: Some(d.parent_name), parent_name: Some(p.name),
parent_surname: Some(d.parent_surname), parent_surname: Some(p.surname),
parent_telephone: Some(d.parent_telephone), parent_telephone: Some(p.telephone),
parent_email: Some(d.parent_email), parent_email: Some(p.email),
} }
} }
} }