feat: json deserialization in core

This commit is contained in:
Sebastian Pravda 2022-11-06 12:43:52 +01:00 committed by Sebastian Pravda
parent 1049f1fd4d
commit 43fe565fa2
4 changed files with 106 additions and 86 deletions

View file

@ -344,7 +344,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_verify_password() { 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"; const PASSWORD: &str = "test";
let result = super::verify_password(PASSWORD.to_string(), HASH.to_string()) let result = super::verify_password(PASSWORD.to_string(), HASH.to_string())

View file

@ -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::{*}; use sea_orm::{*};
impl Mutation { impl Mutation {
@ -28,29 +28,19 @@ impl Mutation {
pub async fn add_candidate_details( pub async fn add_candidate_details(
db: &DbConn, db: &DbConn,
user: Model, user: candidate::Model,
name: String, enc_details: EncryptedAddUserData,
surname: String,
birthplace: String,
birthdate: String,
address: String,
telephone: String,
citizenship: String,
email: String,
sex: String,
study: String,
) -> 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(name)); user.name = Set(Some(enc_details.name));
user.surname = Set(Some(surname)); user.surname = Set(Some(enc_details.surname));
user.birthplace = Set(Some(birthplace)); user.birthplace = Set(Some(enc_details.birthplace));
user.birthdate = Set(None); user.address = Set(Some(enc_details.address));
user.address = Set(Some(address)); user.telephone = Set(Some(enc_details.telephone));
user.telephone = Set(Some(telephone)); user.citizenship = Set(Some(enc_details.citizenship));
user.citizenship = Set(Some(citizenship)); user.email = Set(Some(enc_details.email));
user.email = Set(Some(email)); user.sex = Set(Some(enc_details.sex));
user.sex = Set(Some(sex)); user.study = Set(Some(enc_details.study));
user.study = Set(Some(study));
user.updated_at = Set(chrono::offset::Local::now().naive_local()); user.updated_at = Set(chrono::offset::Local::now().naive_local());

View file

@ -1,4 +1,4 @@
pub struct Mutation; pub(crate) struct Mutation;
pub mod session; pub mod session;
pub mod candidate; pub mod candidate;

View file

@ -1,6 +1,7 @@
use chrono::NaiveDate; use chrono::NaiveDate;
use entity::candidate; use entity::candidate;
use sea_orm::{prelude::Uuid, DbConn}; use sea_orm::{prelude::Uuid, DbConn};
use serde::Deserialize;
use crate::{ use crate::{
crypto::{self, hash_password}, crypto::{self, hash_password},
@ -12,6 +13,77 @@ use super::session_service::{AdminUser, SessionService};
const FIELD_OF_STUDY_PREFIXES: [&str; 3] = ["101", "102", "103"]; 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; pub struct CandidateService;
impl CandidateService { impl CandidateService {
@ -72,16 +144,7 @@ impl CandidateService {
pub async fn add_user_details( pub async fn add_user_details(
db: &DbConn, db: &DbConn,
application_id: i32, application_id: i32,
name: String, form: AddUserDetailsForm,
surname: String,
birthplace: String,
birthdate: String,
address: String,
telephone: String,
citizenship: String,
email: String,
sex: String,
study: String,
) -> Result<entity::candidate::Model, ServiceError> { ) -> Result<entity::candidate::Model, ServiceError> {
let Ok(user) = Query::find_candidate_by_id(db, application_id).await else { let Ok(user) = Query::find_candidate_by_id(db, application_id).await else {
return Err(ServiceError::DbError); return Err(ServiceError::DbError);
@ -102,43 +165,12 @@ impl CandidateService {
recipients.append(&mut admin_public_keys_refrence); recipients.append(&mut admin_public_keys_refrence);
let ( let enc_details = EncryptedAddUserData::encrypt_form(form, recipients).await;
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),
);
Mutation::add_candidate_details( Mutation::add_candidate_details(
db, db,
user_unwrapped, user_unwrapped,
enc_name.unwrap(), enc_details,
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(),
) )
.await .await
.map_err(|_| ServiceError::DbError) .map_err(|_| ServiceError::DbError)
@ -179,7 +211,7 @@ mod tests {
use chrono::NaiveDate; use chrono::NaiveDate;
use sea_orm::{Database, DbConn}; use sea_orm::{Database, DbConn};
use crate::{crypto, services::candidate_service::CandidateService}; use crate::{crypto, services::candidate_service::{CandidateService, AddUserDetailsForm}};
#[tokio::test] #[tokio::test]
async fn test_application_id_validation() { async fn test_application_id_validation() {
@ -255,23 +287,21 @@ mod tests {
.ok() .ok()
.unwrap(); .unwrap();
let candidate = CandidateService::add_user_details( let form = AddUserDetailsForm {
&db, name: "test".to_string(),
candidate.application, surname: "a".to_string(),
"test".to_string(), birthplace: "b".to_string(),
"a".to_string(), birthdate: NaiveDate::from_ymd(1999, 1, 1),
"b".to_string(), address: "test".to_string(),
NaiveDate::from_ymd(1999, 1, 1).to_string(), telephone: "test".to_string(),
"test".to_string(), citizenship: "test".to_string(),
"test".to_string(), email: "test".to_string(),
"test".to_string(), sex: "test".to_string(),
"test".to_string(), study: "test".to_string(),
"test".to_string(), };
"test".to_string(), let candidate = CandidateService::add_user_details(&db, candidate.application, form).await.ok().unwrap();
)
.await
.ok()
.unwrap();
assert!(candidate.name.is_some()); assert!(candidate.name.is_some());
} }