diff --git a/src/callers/login.rs b/src/callers/login.rs index 8026e81..84e790a 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -3,6 +3,8 @@ pub mod request { #[derive(Default, Deserialize, Serialize)] pub struct Request { + pub username: String, + pub password: String, } } @@ -29,13 +31,50 @@ pub mod endpoint { axum::Extension(pool): axum::Extension, Json(payload): Json, ) -> (StatusCode, Json) { - let mut usr = icarus_models::user::User::default(); + let usr = icarus_models::user::User { + username: payload.username, + password: payload.password, + ..Default::default() + }; + // usr.username = payload.username; + // usr.password = payload.password; - ( - StatusCode::OK, - Json(response::Response { - message: String::from("Not implemented"), - }), - ) + // Check if user exists + let user_exists = repo::user::exists(&pool, &usr.username).await.unwrap(); + if !user_exists { + // End + } + let user = repo::user::get(&pool, &usr.username).await.unwrap(); + let salt = repo::salt::get(&pool, &user.salt_id).await.unwrap(); + let salt_literal = salt.salt.clone(); + let salt_str = hashing::get_salt(&salt_literal).unwrap(); + + // Check if password is correct + let hash_password = hashing::hash_password(&usr.password, &salt_str).unwrap(); + if hashing::verify_password(&usr.password, hash_password.clone()).unwrap() { + println!("Do work"); + } + + // Create token + let key = token_stuff::get_key().unwrap(); + let token_literal = token_stuff::create_token(&key).unwrap(); + + let result = token_stuff::verify_token(&key, &token_literal); + + if result { + ( + StatusCode::OK, + Json(response::Response { + message: String::from("Not implemented"), + }), + ) + } else { + ( + StatusCode::BAD_REQUEST, + Json(response::Response { + message: String::from("Not implemented"), + }), + ) + } } } diff --git a/src/hashing/mod.rs b/src/hashing/mod.rs index 1386d0c..a3fbbd4 100644 --- a/src/hashing/mod.rs +++ b/src/hashing/mod.rs @@ -15,6 +15,10 @@ pub fn generate_salt() -> Result { Ok(salt) } +pub fn get_salt(s: &str) -> Result { + SaltString::from_b64(s) +} + pub fn hash_password( password: &String, salt: &SaltString, diff --git a/src/lib.rs b/src/lib.rs index 08bc22a..ea7dde2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,6 @@ pub mod db_pool { } mod token_stuff { - use dotenvy; use josekit::{ self, jws::{JwsHeader, alg::hmac::HmacJwsAlgorithm::Hs256}, @@ -49,7 +48,6 @@ mod token_stuff { }; pub const TOKENTYPE: &str = "JWT"; - pub const TESTKEY: &str = "dfsdferferf"; pub const KEY_ENV: &str = "SECRET_KEY"; pub fn get_key() -> Result { @@ -65,12 +63,11 @@ mod token_stuff { let mut payload = JwtPayload::new(); payload.set_subject("Something random"); - let mut key: String = String::new(); - if provided_key.is_empty() { - key = get_key().unwrap(); + let key: String = if provided_key.is_empty() { + get_key().unwrap() } else { - key = provided_key.clone(); - } + provided_key.to_owned() + }; let signer = Hs256.signer_from_bytes(key.as_bytes()).unwrap(); let jwt = josekit::jwt::encode_with_signer(&payload, &header, &signer).unwrap(); @@ -80,7 +77,7 @@ mod token_stuff { pub fn verify_token(key: &String, token: &String) -> bool { let ver = Hs256.verifier_from_bytes(key.as_bytes()).unwrap(); - let (payload, _header) = jwt::decode_with_verifier(&token, &ver).unwrap(); + let (payload, _header) = jwt::decode_with_verifier(token, &ver).unwrap(); match payload.subject() { Some(_sub) => true, None => false, diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 049a840..b8a8c8c 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -7,6 +7,41 @@ pub mod user { pub date_created: Option, } + pub async fn get( + pool: &sqlx::PgPool, + username: &String, + ) -> Result { + let result = sqlx::query( + r#" + SELECT * FROM "user" WHERE username = $1 + "#, + ) + .bind(username) + .fetch_optional(pool) + .await; + + match result { + Ok(r) => match r { + Some(r) => Ok(icarus_models::user::User { + id: r.try_get("id")?, + username: r.try_get("username")?, + password: r.try_get("password")?, + email: r.try_get("email")?, + email_verified: r.try_get("email_verified")?, + phone: r.try_get("phone")?, + salt_id: r.try_get("salt_id")?, + firstname: r.try_get("firstname")?, + lastname: r.try_get("lastname")?, + date_created: r.try_get("date_created")?, + last_login: r.try_get("last_login")?, + status: r.try_get("status")?, + }), + None => Err(sqlx::Error::RowNotFound), + }, + Err(e) => Err(e), + } + } + pub async fn exists(pool: &sqlx::PgPool, username: &String) -> Result { let result = sqlx::query( r#" @@ -72,6 +107,31 @@ pub mod salt { pub id: uuid::Uuid, } + pub async fn get( + pool: &sqlx::PgPool, + id: &uuid::Uuid, + ) -> Result { + let result = sqlx::query( + r#" + SELECT * FROM "salt" WHERE id = $1 + "#, + ) + .bind(id) + .fetch_optional(pool) + .await; + + match result { + Ok(r) => match r { + Some(r) => Ok(icarus_models::user::salt::Salt { + id: r.try_get("id")?, + salt: r.try_get("salt")?, + }), + None => Err(sqlx::Error::RowNotFound), + }, + Err(e) => Err(e), + } + } + pub async fn insert( pool: &sqlx::PgPool, salt: &icarus_models::user::salt::Salt,