diff --git a/server/src/auth.rs b/server/src/auth.rs index 8865fe9..69b4ffb 100644 --- a/server/src/auth.rs +++ b/server/src/auth.rs @@ -1,59 +1,60 @@ -use mysql_async::Pool; +use bcrypt; +use mysql_async::{Conn, Pool}; use mysql_async::prelude::{params, Queryable}; -use crate::db_types::{UBigInt, VarChar}; +use crate::db_types::{BigInt, Integer, UBigInt, VarChar}; use crate::routes; -pub const BCRYPT_COST: u32 = 14; +// used when we create a new users for the first time +pub const _BCRYPT_COST: u32 = 14; pub enum AuthReason { - Good, //passed regular check + Good, //passed regular check OpenAuth, // route does not require auth - NoKey, + NoKey, // key missing + BadKey, // key is bad } fn open_route(path: &str) -> bool { return path == routes::INVITE_JOIN } + +fn valid_user(secret: &str, row: &Option<(VarChar, VarChar, BigInt, Integer, UBigInt)>) -> bool { + match row { + Some(row) => { + if let Ok(result) = bcrypt::verify(secret, &row.0) { + return result; + } + return false; + }, + _ => return false + } +} + pub async fn wall_entry(path: &str, pool: &Pool, params: &mut serde_json::Value) -> Result { - use serde_json::json; // Start by Checking if the api key is in our keystore if open_route(path) { Ok(AuthReason::OpenAuth) } else { - if let Some(key) = params.get("secret") { - let key_str = key.as_str(); - let conn = pool.get_conn().await?; - // (id, name, secret) - type RowType = Option<(UBigInt, VarChar)>; - let db_result: Result<(_, RowType), mysql_async::error::Error> = conn - .first_exec(r"SELECT id, name FROM members WHERE secret = :secret ", mysql_async::params!{ "secret" => key_str}) - .await; - - match db_result { - Ok((_, row)) => { - match row{ - Some(user_row) => { - params["userid"] = json!(user_row.0); - params["username"] = json!(user_row.1); - Ok(AuthReason::Good) - }, - None => Ok(AuthReason::NoKey) - } + match (params.get("id"), params.get("secret")) { + (Some(id_v), Some(secret_v)) => { + let id = id_v.as_str().unwrap(); + let secret = secret_v.as_str().unwrap(); + let conn = pool.get_conn().await?; + let db_tup: (Conn, Option<(VarChar, VarChar, BigInt, Integer, UBigInt)>) = conn.first_exec( + "SELECT secret, name, joindate, status, permissions FROM members WHERE id = :id", + mysql_async::params!{"id" => id}).await?; + if valid_user(secret, &db_tup.1) { + Ok(AuthReason::Good) } - Err(e) => { - println!("\tIssue fetching auth data {:?}", e); - Ok(AuthReason::NoKey) + else { + Ok(AuthReason::BadKey) } + }, + _ => { + Ok(AuthReason::NoKey) } - - //let (_con, row): (_, Option<(UBigInt, VarChar)>) = conn - // .first_exec(r"SELECT userid, name FROM keys WHERE secret = :secret ", mysql_async::params!{ "secret" => key}) - // .await; - } - else { - Ok(AuthReason::NoKey) } } } @@ -66,6 +67,7 @@ pub fn generate_secret() -> String { use base64::{encode_config, URL_SAFE}; let mut buf: Vec = vec![0;64]; - getrandom(&mut buf); + getrandom(&mut buf).unwrap(); encode_config(buf,URL_SAFE) } + diff --git a/server/src/main.rs b/server/src/main.rs index c7b478a..c38bd05 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -98,7 +98,7 @@ async fn main_responder(request: Request) -> Result, hyper: // Deal with permissions errors at this point match auth_result { OpenAuth | Good => route_dispatcher(&pool, &mut response, &method, path, params).await, - NoKey => { + NoKey | BadKey => { println!("\tAUTH: NoKey/BadKey"); *response.status_mut() = StatusCode::UNAUTHORIZED },