Proof of concept for login

master
fernando 2024-02-15 11:47:51 -05:00
parent ee7297ab1f
commit da4019ec61
8 changed files with 264 additions and 16 deletions

171
Cargo.lock generated
View File

@ -80,6 +80,33 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "argon2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
dependencies = [
"base64ct",
"blake2",
"cpufeatures",
"password-hash",
]
[[package]]
name = "async-stream"
version = "0.3.5"
@ -201,6 +228,15 @@ dependencies = [
"serde",
]
[[package]]
name = "blake2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -210,6 +246,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "bytemuck"
version = "1.14.2"
@ -243,6 +285,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"windows-targets 0.52.0",
]
[[package]]
name = "cipher"
version = "0.4.4"
@ -276,6 +330,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
version = "0.2.12"
@ -410,6 +470,7 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
name = "eeg_internal"
version = "0.1.0"
dependencies = [
"argon2",
"maud",
"rocket",
"rocket_db_pools",
@ -807,6 +868,29 @@ dependencies = [
"want",
]
[[package]]
name = "iana-time-zone"
version = "0.1.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "idna"
version = "0.5.0"
@ -869,6 +953,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "js-sys"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -1183,6 +1276,17 @@ dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "password-hash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]]
name = "paste"
version = "1.0.14"
@ -1841,6 +1945,7 @@ dependencies = [
"atoi",
"byteorder",
"bytes",
"chrono",
"crc",
"crossbeam-queue",
"dotenvy",
@ -1925,6 +2030,7 @@ dependencies = [
"bitflags 2.4.2",
"byteorder",
"bytes",
"chrono",
"crc",
"digest",
"dotenvy",
@ -1966,6 +2072,7 @@ dependencies = [
"base64",
"bitflags 2.4.2",
"byteorder",
"chrono",
"crc",
"dotenvy",
"etcetera",
@ -2002,6 +2109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490"
dependencies = [
"atoi",
"chrono",
"flume",
"futures-channel",
"futures-core",
@ -2455,6 +2563,60 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.48",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
[[package]]
name = "webpki-roots"
version = "0.25.4"
@ -2498,6 +2660,15 @@ dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.0",
]
[[package]]
name = "windows-sys"
version = "0.48.0"

View File

@ -6,14 +6,13 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
argon2 = "0.5.3"
maud = { version = "0.26.0", features = ["rocket"] }
rocket = {version = "0.5.0", features = ["secrets"] }
serde = "1.0.196"
sqlx = { version = "0.7.3", features = ["postgres"] }
sqlx = { version = "0.7.3", features = ["mysql", "macros", "chrono"] }
[dependencies.rocket_db_pools]
version = "0.1.0"
features = ["sqlx_mysql"]
[default.databases.main]
url = "mysql://root:password@localhost:3306/eeg-administrative"

2
Rocket.toml Normal file
View File

@ -0,0 +1,2 @@
[default.databases.main]
url = "mysql://root:123456789@localhost:33306/eegsac_manager"

View File

@ -9,10 +9,12 @@ CREATE TABLE user (
user_names VARCHAR(50) NOT NULL,
user_surnames VARCHAR(50) NOT NULL,
user_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
user_creation DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_last_login DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- This is the hash & salt for a password "123456789"
-- $argon2id$v=19$m=65536,t=4,p=1$TE1wdklnMEpsMDAveWhzYw$nsKg2fALcXZ8AquM7jPGBUjM3Dyg5tgbDATKMeKPtfQ
-- insert into user (user_email, user_password, user_names, user_surnames) values ('fernando@eegsac.com', '$argon2id$v=19$m=65536,t=4,p=1$TE1wdklnMEpsMDAveWhzYw$nsKg2fALcXZ8AquM7jPGBUjM3Dyg5tgbDATKMeKPtfQ', 'Fernando', 'Araoz');

View File

@ -1,11 +1,17 @@
use maud::Markup;
use rocket::{
form::Form,
http::{CookieJar, Status},
State,
use rocket::{form::Form, http::CookieJar, State};
use rocket_db_pools::Connection;
use argon2::{
password_hash::{PasswordHash, PasswordVerifier},
Argon2,
};
use crate::auth::session::{SessionData, Sessions};
use crate::{
auth::session::{SessionData, Sessions},
model::user::User,
DefaultDB,
};
#[derive(FromForm)]
pub struct LoginData {
@ -14,9 +20,42 @@ pub struct LoginData {
}
#[get("/login")]
pub fn login(sessions: &State<Sessions>, cookies: &CookieJar<'_>) -> &'static str {
let session_id = sessions.insert(SessionData::new(1));
cookies.add_private(("rocket_session_id", session_id.to_string()));
pub async fn login(
sessions: &State<Sessions>,
cookies: &CookieJar<'_>,
mut db: Connection<DefaultDB>,
) -> String {
// This data should come from a post request
let login_data = LoginData {
email: "fernando@eegsac.com".into(),
password: "123456789".into(),
};
":D"
// Get person from db
let person_result = User::get_by_email(&mut **db, &login_data.email).await;
let person = match person_result {
Ok(p) => p,
Err(reason) => return reason,
};
// Validate password
let parsed_hash = match PasswordHash::new(&person.user_password) {
Ok(h) => h,
Err(err) => {
println!("Error al parsear el hash: {:?}", err);
return format!("Error al parsear el hash: {:?}", err);
}
};
let password_correct = Argon2::default()
.verify_password(login_data.password.as_bytes(), &parsed_hash)
.is_ok();
if password_correct {
let session_id = sessions.insert(SessionData::new(person.user_id));
cookies.add_private(("rocket_session_id", session_id.to_string()));
":D".into()
} else {
"Contraseña incorrecta".into()
}
}

View File

@ -4,15 +4,22 @@ mod auth;
mod controller;
mod model;
mod view;
use rocket_db_pools::Database;
#[macro_use]
extern crate rocket;
/// The default database pool.
#[derive(Database)]
#[database("main")]
pub struct DefaultDB(sqlx::MySqlPool);
#[launch]
fn rocket() -> _ {
rocket::build()
.manage(auth::session::Sessions::new())
.register("/", catchers![view::not_authorized])
.attach(DefaultDB::init())
.mount("/", routes![controller::index,])
.mount(
"/f",

View File

@ -1 +1 @@
pub mod user;

28
src/model/user.rs Normal file
View File

@ -0,0 +1,28 @@
use sqlx::{types::chrono::NaiveDateTime, MySqlConnection};
pub struct User {
pub user_id: i32,
pub user_email: String,
pub user_password: String,
pub user_names: String,
pub user_surnames: String,
pub user_creation: NaiveDateTime,
pub user_last_login: NaiveDateTime,
}
impl User {
pub async fn get_by_email(db: &mut MySqlConnection, email: &str) -> Result<User, String> {
let result = sqlx::query_as!(User, "SELECT * FROM user where user_email = ?", email)
.fetch_one(db)
.await;
match result {
Ok(user) => Ok(user),
Err(sqlx::Error::RowNotFound) => Err("Usuario no encontrado".into()),
Err(err) => {
eprintln!("Error: {:?}", err);
Err("Error al buscar el usuario".into())
}
}
}
}