diff --git a/api/src/lib.rs b/api/src/lib.rs index 1a066a6..33136ec 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -5,7 +5,7 @@ use std::net::SocketAddr; use portfolio_core::error::ServiceError; use portfolio_core::services::candidate_service::CandidateService; -use requests::LoginRequest; +use requests::{LoginRequest, RegisterRequest}; use rocket::http::Status; use rocket::{Rocket, Build}; use rocket::serde::json::Json; @@ -35,13 +35,13 @@ fn custom_err_from_service_err(service_err: ServiceError) -> Custom { } #[post("/", data = "")] -async fn create(conn: Connection<'_, Db>, post_form: Json) -> Result> { +async fn create(conn: Connection<'_, Db>, post_form: Json) -> Result> { let db = conn.into_inner(); let form = post_form.into_inner(); let plain_text_password = random_8_char_string(); - Mutation::create_candidate(db, form, &plain_text_password) + Mutation::create_candidate(db, form.application_id, &plain_text_password, form.personal_id_number) .await .expect("Could not insert candidate"); diff --git a/api/src/requests.rs b/api/src/requests.rs index 9c86d49..032af26 100644 --- a/api/src/requests.rs +++ b/api/src/requests.rs @@ -6,4 +6,11 @@ use rocket::serde::{Serialize, Deserialize}; pub struct LoginRequest { pub application_id: i32, pub password: String, +} + +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct RegisterRequest { + pub application_id: i32, + pub personal_id_number: String, } \ No newline at end of file diff --git a/core/Cargo.toml b/core/Cargo.toml index 22a29bc..db5c1bd 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -7,10 +7,6 @@ publish = false [dependencies] chrono = "^0.4" -# serialization & deserialization -serde = { version = "^1.0", features = ["derive"] } -serde_json = "^1.0" - portfolio-entity = { path = "../entity" } # env diff --git a/core/src/mutation.rs b/core/src/mutation.rs index d127342..ba914fa 100644 --- a/core/src/mutation.rs +++ b/core/src/mutation.rs @@ -1,3 +1,5 @@ +use std::vec; + use chrono::{Utc, Duration}; use ::entity::{candidate, session}; use sea_orm::{*, prelude::Uuid}; @@ -8,17 +10,23 @@ pub struct Mutation; impl Mutation { pub async fn create_candidate( db: &DbConn, - form_data: candidate::Model, + application_id: i32, plain_text_password: &String, + personal_id_number: String, ) -> Result { // TODO: unwrap pro testing.. let hashed_password = hash_password(plain_text_password.to_string()).await.unwrap(); let (pubkey, priv_key_plain_text) = crypto::create_identity(); - let encrypted_priv_key = crypto::encrypt_password_age(&priv_key_plain_text, &plain_text_password.to_string()).await.unwrap(); + let encrypted_priv_key = crypto::encrypt_password(priv_key_plain_text, plain_text_password.to_string()).await.unwrap(); + + let encrypted_personal_id_number = crypto::encrypt_password_with_recipients( + &personal_id_number, vec![&pubkey] + ).await.unwrap(); candidate::ActiveModel { - application: Set(form_data.application), + application: Set(application_id), + personal_identification_number: Set(encrypted_personal_id_number), code: Set(hashed_password), public_key: Set(pubkey), private_key: Set(encrypted_priv_key), @@ -65,7 +73,6 @@ impl Mutation { #[cfg(test)] mod tests { use sea_orm::{Database, DbConn}; - use serde_json::json; use crate::{Mutation, crypto}; @@ -89,19 +96,16 @@ mod tests { async fn test_encrypt_decrypt_private_key_with_passphrase() { let db = get_memory_sqlite_connection().await; - let form = serde_json::from_value(json!({ - "application": 5555555, - })).unwrap(); let plain_text_password = "test".to_string(); let secret_message = "trnka".to_string(); - let candidate = Mutation::create_candidate(&db, form, &plain_text_password).await.unwrap(); + let candidate = Mutation::create_candidate(&db, 5555555, &plain_text_password, "".to_string()).await.unwrap(); let encrypted_message = crypto::encrypt_password_with_recipients(&secret_message, vec![&candidate.public_key]).await.unwrap(); - let private_key_plain_text = crypto::decrypt_password_age(&candidate.private_key, &plain_text_password).await.unwrap(); + let private_key_plain_text = crypto::decrypt_password(candidate.private_key, plain_text_password).await.unwrap(); let decrypted_message = crypto::decrypt_password_with_private_key(&encrypted_message, &private_key_plain_text).await.unwrap(); diff --git a/core/src/query.rs b/core/src/query.rs index 35f0883..0c0c440 100644 --- a/core/src/query.rs +++ b/core/src/query.rs @@ -50,6 +50,7 @@ mod tests { code: Set("test".to_string()), public_key: Set("test".to_string()), private_key: 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 73486e7..91bdd83 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -92,7 +92,6 @@ impl CandidateService { mod tests { use entity::candidate; use sea_orm::{DbConn, Database, sea_query::TableCreateStatement, DbBackend, Schema, ConnectionTrait, prelude::Uuid}; - use serde_json::json; use crate::{crypto, Mutation, services::candidate_service::CandidateService}; @@ -117,11 +116,7 @@ mod tests { let db = get_memory_sqlite_connection().await; - let form = serde_json::from_value(json!({ - "application": 5555555, - })).unwrap(); - - let candidate = Mutation::create_candidate(&db, form, &SECRET.to_string()).await.unwrap(); + let candidate = Mutation::create_candidate(&db, 5555555, &SECRET.to_string(), "".to_string()).await.unwrap(); assert_eq!(candidate.application, 5555555); assert_ne!(candidate.code, SECRET.to_string()); @@ -132,11 +127,7 @@ mod tests { async fn test_candidate_session_correct_password() { let db = &get_memory_sqlite_connection().await; - let form = serde_json::from_value(json!({ - "application": 5555555, - })).unwrap(); - - Mutation::create_candidate(&db, form, &"Tajny_kod".to_string()).await.unwrap(); + Mutation::create_candidate(&db, 5555555, &"Tajny_kod".to_string(), "".to_string()).await.unwrap(); // correct password let session = CandidateService::new_session( @@ -159,11 +150,7 @@ mod tests { async fn test_candidate_session_incorrect_password() { let db = &get_memory_sqlite_connection().await; - let form = serde_json::from_value(json!({ - "application": 5555555, - })).unwrap(); - - let candidate_form = Mutation::create_candidate(&db, form, &"Tajny_kod".to_string()).await.unwrap(); + let candidate_form = Mutation::create_candidate(&db, 5555555, &"Tajny_kod".to_string(), "".to_string()).await.unwrap(); // incorrect password assert!( diff --git a/entity/Cargo.toml b/entity/Cargo.toml index 1b3a166..af3e744 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -9,7 +9,6 @@ name = "entity" path = "src/lib.rs" [dependencies] -serde = { version = "^1.0", features = ["derive"] } chrono = "^0.4" [dependencies.sea-orm] diff --git a/entity/src/candidate.rs b/entity/src/candidate.rs index 221a80e..4861e7c 100644 --- a/entity/src/candidate.rs +++ b/entity/src/candidate.rs @@ -1,13 +1,10 @@ use sea_orm::entity::prelude::*; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "candidate")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub application: i32, - #[serde(skip_deserializing, skip_serializing)] pub code: String, pub name: Option, pub surname: Option, @@ -20,16 +17,12 @@ pub struct Model { pub email: Option, pub sex: Option, pub study: Option, - pub personal_identification_number: Option, + pub personal_identification_number: String, #[sea_orm(column_type = "Text", nullable)] pub personal_identification_number_hash: Option, - #[serde(skip_deserializing, skip_serializing)] pub public_key: String, - #[serde(skip_deserializing, skip_serializing)] pub private_key: String, - #[serde(skip_deserializing, skip_serializing)] pub created_at: DateTime, - #[serde(skip_deserializing, skip_serializing)] pub updated_at: DateTime, } diff --git a/migration/src/m20221024_121621_create_candidate.rs b/migration/src/m20221024_121621_create_candidate.rs index 929838b..5483c3a 100644 --- a/migration/src/m20221024_121621_create_candidate.rs +++ b/migration/src/m20221024_121621_create_candidate.rs @@ -30,7 +30,7 @@ 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::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()) diff --git a/migration/src/main.rs b/migration/src/main.rs index f054dea..85be8cc 100644 --- a/migration/src/main.rs +++ b/migration/src/main.rs @@ -3,4 +3,4 @@ use sea_orm_migration::prelude::*; #[tokio::main] async fn main() { cli::run_cli(migration::Migrator).await; -} +} \ No newline at end of file