From d9f4090c6a89efb32441b0a7ae5180a843c1e119 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Sun, 27 Nov 2022 12:08:35 +0100 Subject: [PATCH] feat: set personal id number when user is created --- core/src/candidate_details.rs | 7 +++++- core/src/database/mutation/candidate.rs | 8 +++---- core/src/database/query/candidate.rs | 4 ++-- core/src/database/query/parent.rs | 2 +- core/src/services/candidate_service.rs | 20 ++++++++++++----- entity/src/candidate.rs | 22 +++++++++---------- .../src/m20221024_121621_create_candidate.rs | 4 ++-- 7 files changed, 41 insertions(+), 26 deletions(-) diff --git a/core/src/candidate_details.rs b/core/src/candidate_details.rs index f235b08..fb3b071 100644 --- a/core/src/candidate_details.rs +++ b/core/src/candidate_details.rs @@ -46,6 +46,11 @@ impl TryFrom> for EncryptedString { } } } +impl From for EncryptedString { + fn from(s: String) -> Self { + Self(s) + } +} impl TryFrom> for EncryptedString { // TODO: take a look at this @@ -180,7 +185,7 @@ impl TryFrom<(candidate::Model, parent::Model)> for EncryptedApplicationDetails citizenship: EncryptedString::try_from(candidate.citizenship)?, email: EncryptedString::try_from(candidate.email)?, sex: EncryptedString::try_from(candidate.sex)?, - personal_id_number: EncryptedString::try_from(candidate.personal_identification_number)?, + personal_id_number: EncryptedString::from(candidate.personal_identification_number), study: candidate.study.ok_or(ServiceError::CandidateDetailsNotSet)?, parent_name: EncryptedString::try_from(parent.name)?, diff --git a/core/src/database/mutation/candidate.rs b/core/src/database/mutation/candidate.rs index 7921f74..a687ebe 100644 --- a/core/src/database/mutation/candidate.rs +++ b/core/src/database/mutation/candidate.rs @@ -8,13 +8,13 @@ impl Mutation { db: &DbConn, application_id: i32, hashed_password: String, - hashed_personal_id_number: String, + enc_personal_id_number: String, pubkey: String, encrypted_priv_key: String, ) -> Result { candidate::ActiveModel { application: Set(application_id), - personal_identification_number_hash: Set(hashed_personal_id_number), + personal_identification_number: Set(enc_personal_id_number), code: Set(hashed_password), public_key: Set(pubkey), private_key: Set(encrypted_priv_key), @@ -26,7 +26,7 @@ impl Mutation { .await } - pub async fn update_candidate_password_with_keys( + pub async fn update_candidate_password_and_keys( db: &DbConn, candidate: candidate::Model, new_password_hash: String, @@ -56,7 +56,7 @@ impl Mutation { user.citizenship = Set(Some(enc_details.citizenship.into())); user.email = Set(Some(enc_details.email.into())); user.sex = Set(Some(enc_details.sex.into())); - user.personal_identification_number = Set(Some(enc_details.personal_id_number.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.study = Set(Some(enc_details.study.into())); user.updated_at = Set(chrono::offset::Local::now().naive_local()); diff --git a/core/src/database/query/candidate.rs b/core/src/database/query/candidate.rs index 4a696dd..4bf96d6 100644 --- a/core/src/database/query/candidate.rs +++ b/core/src/database/query/candidate.rs @@ -132,7 +132,7 @@ mod tests { code: Set("test".to_string()), public_key: Set("test".to_string()), private_key: Set("test".to_string()), - personal_identification_number_hash: Set("test".to_string()), + personal_identification_number: Set("test".to_string()), created_at: Set(chrono::offset::Local::now().naive_local()), updated_at: Set(chrono::offset::Local::now().naive_local()), ..Default::default() @@ -141,7 +141,7 @@ mod tests { .await .unwrap(); - let candidate = Query::find_candidate_by_id(&db, candidate.application) + let candidate = Query::find_candidate_by_id(&db, candidate.application) .await .unwrap(); assert!(candidate.is_some()); diff --git a/core/src/database/query/parent.rs b/core/src/database/query/parent.rs index 665d9de..c53e443 100644 --- a/core/src/database/query/parent.rs +++ b/core/src/database/query/parent.rs @@ -35,7 +35,7 @@ mod tests { code: Set("test".to_string()), public_key: Set("test".to_string()), private_key: Set("test".to_string()), - personal_identification_number_hash: Set("test".to_string()), + personal_identification_number: Set("test".to_string()), created_at: Set(chrono::offset::Local::now().naive_local()), updated_at: Set(chrono::offset::Local::now().naive_local()), ..Default::default() diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index 4b1033f..ee4be52 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -76,14 +76,24 @@ impl CandidateService { return Err(ServiceError::UserAlreadyExists); } + let hashed_password = hash_password(plain_text_password.to_string()).await?; - + let (pubkey, priv_key_plain_text) = crypto::create_identity(); let encrypted_priv_key = crypto::encrypt_password(priv_key_plain_text, plain_text_password.to_string()).await?; - let hashed_personal_id_number = hash_password(personal_id_number).await?; + + let admin_public_keys = Query::get_all_admin_public_keys(db).await?; + let mut admin_public_keys_ref = admin_public_keys.iter().map(|s| &**s).collect(); + let mut recipients = vec![&*pubkey]; + recipients.append(&mut admin_public_keys_ref); + + let enc_personal_id_number = EncryptedString::new( + &personal_id_number, + &recipients, + ).await?; tokio::fs::create_dir_all(Self::get_file_store_path().join(&application_id.to_string()).join("cache")).await?; @@ -91,7 +101,7 @@ impl CandidateService { db, application_id, hashed_password, - hashed_personal_id_number, + enc_personal_id_number.to_string(), pubkey, encrypted_priv_key, ) @@ -120,11 +130,11 @@ impl CandidateService { SessionService::revoke_all_sessions(db, Some(id), None).await?; - Mutation::update_candidate_password_with_keys(db, candidate.clone(), new_password_hash, pubkey, encrypted_priv_key).await?; + Mutation::update_candidate_password_and_keys(db, candidate.clone(), new_password_hash, pubkey, encrypted_priv_key).await?; // user might no have filled his details yet, but personal id number is filled from beginning // TODO: make personal id number required - let personal_id_number = EncryptedString::try_from(candidate.personal_identification_number.clone())? + let personal_id_number = EncryptedString::from(candidate.personal_identification_number.clone()) .decrypt(&admin_private_key) .await?; diff --git a/entity/src/candidate.rs b/entity/src/candidate.rs index 6b7d5bd..fdfbc46 100644 --- a/entity/src/candidate.rs +++ b/entity/src/candidate.rs @@ -19,9 +19,9 @@ pub struct Model { pub email: Option, pub sex: Option, pub study: Option, - pub personal_identification_number: Option, - #[sea_orm(column_type = "Text")] - pub personal_identification_number_hash: String, + pub personal_identification_number: String, + #[sea_orm(column_type = "Text", nullable)] + pub personal_identification_number_hash: Option, pub public_key: String, pub private_key: String, pub created_at: DateTime, @@ -30,16 +30,10 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { - #[sea_orm(has_many = "super::parent::Entity")] - Parent, #[sea_orm(has_many = "super::session::Entity")] Session, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Parent.def() - } + #[sea_orm(has_many = "super::parent::Entity")] + Parent, } impl Related for Entity { @@ -48,4 +42,10 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Parent.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/migration/src/m20221024_121621_create_candidate.rs b/migration/src/m20221024_121621_create_candidate.rs index 66d6466..89e0522 100644 --- a/migration/src/m20221024_121621_create_candidate.rs +++ b/migration/src/m20221024_121621_create_candidate.rs @@ -30,8 +30,8 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Candidate::Email).string()) .col(ColumnDef::new(Candidate::Sex).string()) .col(ColumnDef::new(Candidate::Study).string()) - .col(ColumnDef::new(Candidate::PersonalIdentificationNumber).string()) - .col(ColumnDef::new(Candidate::PersonalIdentificationNumberHash).text().not_null()) + .col(ColumnDef::new(Candidate::PersonalIdentificationNumber).string().not_null()) + .col(ColumnDef::new(Candidate::PersonalIdentificationNumberHash).text()) .col(ColumnDef::new(Candidate::PublicKey).string().not_null()) .col(ColumnDef::new(Candidate::PrivateKey).string().not_null()) .col(ColumnDef::new(Candidate::CreatedAt).date_time().not_null())