diff --git a/api/src/lib.rs b/api/src/lib.rs index df560b8..bb72f81 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -1,12 +1,9 @@ #[macro_use] extern crate rocket; +use rocket::{Rocket, Build}; use rocket::serde::json::Json; - use rocket::fairing::{self, AdHoc}; -use rocket::form::{ Form}; -use rocket::fs::{relative, FileServer}; -use rocket::response::{Flash, Redirect}; -use rocket::{Build, Rocket}; +use rocket::response::status::BadRequest; use portfolio_core::{Mutation, Query}; use migration::MigratorTrait; @@ -18,18 +15,21 @@ use pool::Db; pub use entity::candidate; pub use entity::candidate::Entity as Candidate; +use portfolio_core::crypto::{self, random_8_char_string}; + #[post("/", data = "")] -async fn create(conn: Connection<'_, Db>, post_form: Json) -> Flash { +async fn create(conn: Connection<'_, Db>, post_form: Json) -> Result> { let db = conn.into_inner(); - let form = post_form.into_inner(); - Mutation::create_candidate(db, form) + let plain_text_password = random_8_char_string(); + + Mutation::create_candidate(db, form, &plain_text_password) .await .expect("could not insert post"); - Flash::success(Redirect::to("/"), "Post successfully added.") + Ok(plain_text_password) } #[get("/hello")] diff --git a/core/Cargo.toml b/core/Cargo.toml index 3793774..098a79a 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -5,6 +5,9 @@ edition = "2021" [dependencies] portfolio-entity = { path = "../entity" } +rand = "0.8.5" +rust-argon2 = "1.0.0" +chrono = "0.4.22" [dependencies.sea-orm] version = "^0.10.0" diff --git a/core/src/crypto.rs b/core/src/crypto.rs new file mode 100644 index 0000000..31eb606 --- /dev/null +++ b/core/src/crypto.rs @@ -0,0 +1,25 @@ +use argon2::{self, Config}; +use rand::Rng; + +pub fn random_8_char_string() -> String { + rand::thread_rng() + .sample_iter(&rand::distributions::Alphanumeric) + .take(8) + .map(char::from) + .collect::() +} + +pub fn hash_password(password_plaint_text: &str) -> String { + let hash = argon2::hash_encoded( + password_plaint_text.as_bytes(), + b"secretlytestingeverything", + &Config::default() + ) + .unwrap(); + + hash +} + +pub fn verify_password(password_plaint_text: &str, hash: &str) -> bool { + argon2::verify_encoded(hash, password_plaint_text.as_bytes()).unwrap() +} \ No newline at end of file diff --git a/core/src/lib.rs b/core/src/lib.rs index 4a80f23..0ebcef0 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,5 +1,6 @@ mod mutation; mod query; +pub mod crypto; pub use mutation::*; pub use query::*; diff --git a/core/src/mutation.rs b/core/src/mutation.rs index f3f9e61..16ec10a 100644 --- a/core/src/mutation.rs +++ b/core/src/mutation.rs @@ -1,5 +1,6 @@ use ::entity::{candidate, candidate::Entity as Candidate}; use sea_orm::*; +use crate::crypto::{self, hash_password}; pub struct Mutation; @@ -7,7 +8,19 @@ impl Mutation { pub async fn create_candidate( db: &DbConn, form_data: candidate::Model, + plain_text_password: &String, ) -> Result { - todo!() + let hashed_password = hash_password(plain_text_password); + candidate::ActiveModel { + application: Set(145 as i32), // TODO NEFUNGUJE + code: Set(hashed_password), + public_key: Set("lorem ipsum pub key".to_string()), + private_key: Set("lorem ipsum priv key".to_string()), + created_at: Set(chrono::offset::Local::now().naive_local()), + updated_at: Set(chrono::offset::Local::now().naive_local()), + ..Default::default() + } + .save(db) + .await } } diff --git a/entity/src/admin.rs b/entity/src/admin.rs index 1dd8420..ccfab5a 100644 --- a/entity/src/admin.rs +++ b/entity/src/admin.rs @@ -1,10 +1,8 @@ //! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 use sea_orm::entity::prelude::*; -use rocket::serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "admin")] pub struct Model { #[sea_orm(primary_key)] diff --git a/entity/src/candidate.rs b/entity/src/candidate.rs index 7c20178..9638590 100644 --- a/entity/src/candidate.rs +++ b/entity/src/candidate.rs @@ -1,7 +1,8 @@ -//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0 -use chrono::{DateTime, NaiveDate, Local}; -use rocket::serde::{Deserialize, Serialize}; +//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 + use sea_orm::entity::prelude::*; +use rocket::serde::{self, Deserialize, Serialize}; + #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] @@ -9,26 +10,30 @@ use sea_orm::entity::prelude::*; 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, pub birth_surname: Option, pub birthplace: Option, - pub birthdate: Option, + pub birthdate: Option, pub address: Option, pub telephone: Option, - #[sea_orm(default_value="Česká republika")] pub citizenship: Option, pub email: Option, pub sex: Option, pub study: Option, pub personal_identification_number: Option, - #[sea_orm(column_type = "Text")] + #[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, - pub created_at: DateTime, - pub updated_at: DateTime, + #[serde(skip_deserializing, skip_serializing)] + pub created_at: DateTime, + #[serde(skip_deserializing, skip_serializing)] + pub updated_at: DateTime, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/entity/src/mod.rs b/entity/src/mod.rs new file mode 100644 index 0000000..642518a --- /dev/null +++ b/entity/src/mod.rs @@ -0,0 +1,7 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 + +pub mod prelude; + +pub mod admin; +pub mod candidate; +pub mod parent; diff --git a/entity/src/parent.rs b/entity/src/parent.rs index 48e1f7c..4cf47cc 100644 --- a/entity/src/parent.rs +++ b/entity/src/parent.rs @@ -1,10 +1,8 @@ -//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0 -use sea_orm::entity::prelude::*; -use chrono::{DateTime, Local}; -use rocket::serde::{Deserialize, Serialize}; +//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[sea_orm(table_name = "parent")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] @@ -13,8 +11,8 @@ pub struct Model { pub surname: Option, pub telephone: Option, pub email: Option, - pub created_at: DateTime, - pub updated_at: DateTime, + pub created_at: DateTime, + pub updated_at: DateTime, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/entity/src/prelude.rs b/entity/src/prelude.rs index eba3b7f..06a7e4b 100644 --- a/entity/src/prelude.rs +++ b/entity/src/prelude.rs @@ -1,3 +1,5 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 + pub use super::admin::Entity as Admin; pub use super::candidate::Entity as Candidate; pub use super::parent::Entity as Parent;