From 43fe565fa23ec9440d57cf456a325ada919eae7f Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Sun, 6 Nov 2022 12:43:52 +0100 Subject: [PATCH] feat: json deserialization in core --- core/src/crypto.rs | 2 +- core/src/database/mutation/candidate.rs | 36 ++---- core/src/database/mutation/mod.rs | 2 +- core/src/services/candidate_service.rs | 152 ++++++++++++++---------- 4 files changed, 106 insertions(+), 86 deletions(-) diff --git a/core/src/crypto.rs b/core/src/crypto.rs index 8614a87..2b823db 100644 --- a/core/src/crypto.rs +++ b/core/src/crypto.rs @@ -344,7 +344,7 @@ mod tests { #[tokio::test] async fn test_verify_password() { - const HASH: &str = "$argon2i$v=19$m=6000,t=3,p=10$WE9xCQmmWdBK82R4SEjoqA$TZSc6PuLd4aWK2x2WAb+Lm9sLySqjK3KLbNyqyQmzPQ"; + const HASH: &str = "$argon2id$v=19$m=4096,t=3,p=1$c2VjcmV0bHl0ZXN0aW5nZXZlcnl0aGluZw$xEzH8wD/ZjzgZTDTl3YtzMFCfcVa5M5m9y6NfSyB1n4"; const PASSWORD: &str = "test"; let result = super::verify_password(PASSWORD.to_string(), HASH.to_string()) diff --git a/core/src/database/mutation/candidate.rs b/core/src/database/mutation/candidate.rs index 4c86b08..1d0d71d 100644 --- a/core/src/database/mutation/candidate.rs +++ b/core/src/database/mutation/candidate.rs @@ -1,6 +1,6 @@ -use crate::{Mutation}; +use crate::{Mutation, services::candidate_service::EncryptedAddUserData}; -use ::entity::candidate::{self, Model}; +use ::entity::candidate::{self}; use sea_orm::{*}; impl Mutation { @@ -28,29 +28,19 @@ impl Mutation { pub async fn add_candidate_details( db: &DbConn, - user: Model, - name: String, - surname: String, - birthplace: String, - birthdate: String, - address: String, - telephone: String, - citizenship: String, - email: String, - sex: String, - study: String, + user: candidate::Model, + enc_details: EncryptedAddUserData, ) -> Result { let mut user: candidate::ActiveModel = user.into(); - user.name = Set(Some(name)); - user.surname = Set(Some(surname)); - user.birthplace = Set(Some(birthplace)); - user.birthdate = Set(None); - user.address = Set(Some(address)); - user.telephone = Set(Some(telephone)); - user.citizenship = Set(Some(citizenship)); - user.email = Set(Some(email)); - user.sex = Set(Some(sex)); - user.study = Set(Some(study)); + user.name = Set(Some(enc_details.name)); + user.surname = Set(Some(enc_details.surname)); + user.birthplace = Set(Some(enc_details.birthplace)); + user.address = Set(Some(enc_details.address)); + user.telephone = Set(Some(enc_details.telephone)); + user.citizenship = Set(Some(enc_details.citizenship)); + user.email = Set(Some(enc_details.email)); + user.sex = Set(Some(enc_details.sex)); + user.study = Set(Some(enc_details.study)); user.updated_at = Set(chrono::offset::Local::now().naive_local()); diff --git a/core/src/database/mutation/mod.rs b/core/src/database/mutation/mod.rs index 80bf6e9..1a654a9 100644 --- a/core/src/database/mutation/mod.rs +++ b/core/src/database/mutation/mod.rs @@ -1,4 +1,4 @@ -pub struct Mutation; +pub(crate) struct Mutation; pub mod session; pub mod candidate; diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index f026edc..dbf7301 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -1,6 +1,7 @@ use chrono::NaiveDate; use entity::candidate; use sea_orm::{prelude::Uuid, DbConn}; +use serde::Deserialize; use crate::{ crypto::{self, hash_password}, @@ -12,6 +13,77 @@ use super::session_service::{AdminUser, SessionService}; const FIELD_OF_STUDY_PREFIXES: [&str; 3] = ["101", "102", "103"]; +pub(crate) struct EncryptedAddUserData { + pub name: String, + pub surname: String, + pub birthplace: String, + pub birthdate: NaiveDate, + pub address: String, + pub telephone: String, + pub citizenship: String, + pub email: String, + pub sex: String, + pub study: String, +} + +impl EncryptedAddUserData { + pub async fn encrypt_form(form: AddUserDetailsForm, recipients: Vec<&str>) -> EncryptedAddUserData { + let ( + Ok(name), + Ok(surname), + Ok(birthplace), + // Ok(enc_birthdate), + Ok(address), + Ok(telephone), + Ok(citizenship), + Ok(email), + Ok(sex), + Ok(study), + ) = tokio::join!( + crypto::encrypt_password_with_recipients(&form.name, &recipients), + crypto::encrypt_password_with_recipients(&form.surname, &recipients), + crypto::encrypt_password_with_recipients(&form.birthplace, &recipients), + // crypto::encrypt_password_with_recipients(&self.birthdate, &recipients), // TODO + crypto::encrypt_password_with_recipients(&form.address, &recipients), + crypto::encrypt_password_with_recipients(&form.telephone, &recipients), + crypto::encrypt_password_with_recipients(&form.citizenship, &recipients), + crypto::encrypt_password_with_recipients(&form.email, &recipients), + crypto::encrypt_password_with_recipients(&form.sex, &recipients), + crypto::encrypt_password_with_recipients(&form.study, &recipients), + ) else { + panic!("Failed to encrypt user details"); // TODO + }; + + EncryptedAddUserData { + name, + surname, + birthplace, + birthdate: NaiveDate::from_ymd(2000, 1, 1), + address, + telephone, + citizenship, + email, + sex, + study, + } + } +} + +#[derive(Debug, Deserialize)] +pub struct AddUserDetailsForm { + pub name: String, + pub surname: String, + pub birthplace: String, + pub birthdate: NaiveDate, + pub address: String, + pub telephone: String, + pub citizenship: String, + pub email: String, + pub sex: String, + pub study: String, +} + + pub struct CandidateService; impl CandidateService { @@ -72,16 +144,7 @@ impl CandidateService { pub async fn add_user_details( db: &DbConn, application_id: i32, - name: String, - surname: String, - birthplace: String, - birthdate: String, - address: String, - telephone: String, - citizenship: String, - email: String, - sex: String, - study: String, + form: AddUserDetailsForm, ) -> Result { let Ok(user) = Query::find_candidate_by_id(db, application_id).await else { return Err(ServiceError::DbError); @@ -102,43 +165,12 @@ impl CandidateService { recipients.append(&mut admin_public_keys_refrence); - let ( - enc_name, - enc_surname, - enc_birthplace, - enc_birthdate, - enc_address, - enc_telephone, - enc_citizenship, - enc_email, - enc_sex, - enc_study, - ) = tokio::join!( - crypto::encrypt_password_with_recipients(&name, &recipients), - crypto::encrypt_password_with_recipients(&surname, &recipients), - crypto::encrypt_password_with_recipients(&birthplace, &recipients), - crypto::encrypt_password_with_recipients(&birthdate, &recipients), - crypto::encrypt_password_with_recipients(&address, &recipients), - crypto::encrypt_password_with_recipients(&telephone, &recipients), - crypto::encrypt_password_with_recipients(&citizenship, &recipients), - crypto::encrypt_password_with_recipients(&email, &recipients), - crypto::encrypt_password_with_recipients(&sex, &recipients), - crypto::encrypt_password_with_recipients(&study, &recipients), - ); + let enc_details = EncryptedAddUserData::encrypt_form(form, recipients).await; Mutation::add_candidate_details( db, user_unwrapped, - enc_name.unwrap(), - enc_surname.unwrap(), - enc_birthplace.unwrap(), - enc_birthdate.unwrap(), - enc_address.unwrap(), - enc_telephone.unwrap(), - enc_citizenship.unwrap(), - enc_email.unwrap(), - enc_sex.unwrap(), - enc_study.unwrap(), + enc_details, ) .await .map_err(|_| ServiceError::DbError) @@ -179,7 +211,7 @@ mod tests { use chrono::NaiveDate; use sea_orm::{Database, DbConn}; - use crate::{crypto, services::candidate_service::CandidateService}; + use crate::{crypto, services::candidate_service::{CandidateService, AddUserDetailsForm}}; #[tokio::test] async fn test_application_id_validation() { @@ -255,23 +287,21 @@ mod tests { .ok() .unwrap(); - let candidate = CandidateService::add_user_details( - &db, - candidate.application, - "test".to_string(), - "a".to_string(), - "b".to_string(), - NaiveDate::from_ymd(1999, 1, 1).to_string(), - "test".to_string(), - "test".to_string(), - "test".to_string(), - "test".to_string(), - "test".to_string(), - "test".to_string(), - ) - .await - .ok() - .unwrap(); + let form = AddUserDetailsForm { + name: "test".to_string(), + surname: "a".to_string(), + birthplace: "b".to_string(), + birthdate: NaiveDate::from_ymd(1999, 1, 1), + address: "test".to_string(), + telephone: "test".to_string(), + citizenship: "test".to_string(), + email: "test".to_string(), + sex: "test".to_string(), + study: "test".to_string(), + }; + let candidate = CandidateService::add_user_details(&db, candidate.application, form).await.ok().unwrap(); + + assert!(candidate.name.is_some()); }