feat: set personal id number when user is created

This commit is contained in:
Sebastian Pravda 2022-11-27 12:08:35 +01:00
parent 8a9b7a4ae4
commit d9f4090c6a
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
7 changed files with 41 additions and 26 deletions

View file

@ -46,6 +46,11 @@ impl TryFrom<Option<String>> for EncryptedString {
}
}
}
impl From<String> for EncryptedString {
fn from(s: String) -> Self {
Self(s)
}
}
impl TryFrom<Option<NaiveDate>> 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)?,

View file

@ -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::Model, DbErr> {
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());

View file

@ -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());

View file

@ -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()

View file

@ -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?;

View file

@ -19,9 +19,9 @@ pub struct Model {
pub email: Option<String>,
pub sex: Option<String>,
pub study: Option<String>,
pub personal_identification_number: Option<String>,
#[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<String>,
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<super::parent::Entity> for Entity {
fn to() -> RelationDef {
Relation::Parent.def()
}
#[sea_orm(has_many = "super::parent::Entity")]
Parent,
}
impl Related<super::session::Entity> for Entity {
@ -48,4 +42,10 @@ impl Related<super::session::Entity> for Entity {
}
}
impl Related<super::parent::Entity> for Entity {
fn to() -> RelationDef {
Relation::Parent.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -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())