Compare commits

..

No commits in common. "master" and "main" have entirely different histories.
master ... main

19 changed files with 75 additions and 857 deletions

414
Cargo.lock generated
View File

@ -17,41 +17,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes",
"cipher",
"ctr",
"ghash",
"subtle",
]
[[package]]
name = "ahash"
version = "0.8.7"
@ -80,33 +45,6 @@ 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"
@ -228,15 +166,6 @@ 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"
@ -246,12 +175,6 @@ 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"
@ -285,28 +208,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "const-oid"
version = "0.9.6"
@ -319,23 +220,11 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8"
dependencies = [
"aes-gcm",
"base64",
"hkdf",
"percent-encoding",
"rand",
"sha2",
"subtle",
"time",
"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"
@ -382,19 +271,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"rand_core",
"typenum",
]
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]]
name = "der"
version = "0.7.8"
@ -470,13 +349,8 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
name = "eeg_internal"
version = "0.1.0"
dependencies = [
"argon2",
"dotenvy",
"env_logger",
"log",
"maud",
"rocket",
"rocket_db_pools",
"serde",
"sqlx",
]
@ -499,19 +373,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "env_logger"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
dependencies = [
"humantime",
"is-terminal",
"log",
"regex",
"termcolor",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -718,16 +579,6 @@ dependencies = [
"wasi",
]
[[package]]
name = "ghash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]]
name = "gimli"
version = "0.28.1"
@ -860,12 +711,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.28"
@ -890,29 +735,6 @@ 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"
@ -940,15 +762,6 @@ version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]]
name = "is-terminal"
version = "0.4.10"
@ -975,15 +788,6 @@ 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"
@ -1263,12 +1067,6 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "overload"
version = "0.1.1"
@ -1298,17 +1096,6 @@ 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"
@ -1392,18 +1179,6 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
[[package]]
name = "polyval"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -1573,20 +1348,6 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "ring"
version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
dependencies = [
"cc",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted",
"windows-sys 0.48.0",
]
[[package]]
name = "rocket"
version = "0.5.0"
@ -1641,28 +1402,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "rocket_db_pools"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0ebde3e24cbe917062b862136fd532d1ace80e0377a2f5fed541fadd764f1e5"
dependencies = [
"rocket",
"rocket_db_pools_codegen",
"sqlx",
"version_check",
]
[[package]]
name = "rocket_db_pools_codegen"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "184a6f59eed0bf3d1cccb091960a2a1c89efa829b8a41158b269985a9c1bee95"
dependencies = [
"devise",
"quote",
]
[[package]]
name = "rocket_http"
version = "0.5.0"
@ -1729,36 +1468,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"ring",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.14"
@ -1783,16 +1492,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "serde"
version = "1.0.196"
@ -1967,7 +1666,6 @@ dependencies = [
"atoi",
"byteorder",
"bytes",
"chrono",
"crc",
"crossbeam-queue",
"dotenvy",
@ -1986,19 +1684,14 @@ dependencies = [
"once_cell",
"paste",
"percent-encoding",
"rustls",
"rustls-pemfile",
"serde",
"serde_json",
"sha2",
"smallvec",
"sqlformat",
"thiserror",
"tokio",
"tokio-stream",
"tracing",
"url",
"webpki-roots",
]
[[package]]
@ -2037,7 +1730,6 @@ dependencies = [
"sqlx-sqlite",
"syn 1.0.109",
"tempfile",
"tokio",
"url",
]
@ -2052,7 +1744,6 @@ dependencies = [
"bitflags 2.4.2",
"byteorder",
"bytes",
"chrono",
"crc",
"digest",
"dotenvy",
@ -2094,7 +1785,6 @@ dependencies = [
"base64",
"bitflags 2.4.2",
"byteorder",
"chrono",
"crc",
"dotenvy",
"etcetera",
@ -2131,7 +1821,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490"
dependencies = [
"atoi",
"chrono",
"flume",
"futures-channel",
"futures-core",
@ -2217,15 +1906,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.56"
@ -2528,22 +2208,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "universal-hash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"subtle",
]
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.0"
@ -2594,66 +2258,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "whoami"
version = "1.4.1"
@ -2676,15 +2280,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -2700,15 +2295,6 @@ 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,16 +6,7 @@ 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"] }
rocket = "0.5.0"
serde = "1.0.196"
sqlx = { version = "0.7.3", features = ["mysql", "macros", "chrono"] }
log = "0.4.20"
env_logger = "0.10.0"
dotenvy = "0.15.7"
[dependencies.rocket_db_pools]
version = "0.1.0"
features = ["sqlx_mysql"]
sqlx = { version = "0.7.3", features = ["postgres"] }

View File

@ -1,5 +0,0 @@
[release]
secret_key = "CEvBmqk0FHgrtiIbitcTe+citXkWgo2fUfya+EoFiQ0="
[default.databases.main]
url = "mysql://root:123456789@localhost:33306/eegsac_manager"

View File

@ -1,20 +1,18 @@
-- MySQL schema for the database
-- PostgreSQL schema for the database
-- User table
CREATE TABLE user (
user_id INT PRIMARY KEY AUTO_INCREMENT,
CREATE TABLE user (
user_id SERIAL PRIMARY KEY,
user_email VARCHAR(50) NOT NULL,
user_password VARCHAR(255) NOT NULL,
user_names VARCHAR(50) NOT NULL,
user_surnames VARCHAR(50) NOT NULL,
user_creation DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_last_login DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
user_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
user_last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- This sentence creates the first user, the super admin, with a password "123456789"
-- TODO: Change the password for the super admin to a secure one
insert into user (user_email, user_password, user_names, user_surnames)
values ('administracion@eegsac.com', '$argon2id$v=19$m=65536,t=4,p=1$TE1wdklnMEpsMDAveWhzYw$nsKg2fALcXZ8AquM7jPGBUjM3Dyg5tgbDATKMeKPtfQ', 'Administracion', 'EEGSAC');

View File

@ -1,44 +0,0 @@
use rocket::State;
use rocket::{
http::Status,
request::{FromRequest, Outcome, Request},
};
pub mod session;
use session::SessionData;
use session::Sessions;
#[derive(Debug, Clone)]
pub struct RegularUser(pub SessionData);
#[rocket::async_trait]
impl<'r> FromRequest<'r> for RegularUser {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, ()> {
// get the session id from the cookie
let session_opt = req.cookies().get_private("rocket_session_id");
let session_id_str = match session_opt {
Some(s) => s.value().to_owned(),
None => return Outcome::Forward(Status::Unauthorized),
};
let session_id = match session_id_str.parse::<usize>() {
Ok(s) => s,
Err(_) => return Outcome::Forward(Status::Unauthorized),
};
let sessions_outcome = req.guard::<&State<Sessions>>().await;
let sessions = match sessions_outcome {
Outcome::Success(s) => s,
_ => return Outcome::Error((Status::InternalServerError, ())),
};
match sessions.get(session_id) {
Some(s) => Outcome::Success(RegularUser(s.clone())),
None => Outcome::Forward(Status::Unauthorized),
}
}
}

View File

@ -1,92 +0,0 @@
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{collections::HashMap, sync::Mutex};
pub struct Sessions {
sessions: Mutex<HashMap<usize, SessionData>>,
next_id: AtomicUsize,
}
impl Sessions {
pub fn new() -> Self {
Sessions {
sessions: Mutex::new(HashMap::new()),
next_id: AtomicUsize::new(0),
}
}
/// Insert a new session into the map and return its id.
/// This id can be used to retrieve the session later.
/// It is meant to be encrypted and sent to the client as a cookie.
pub fn insert(&self, session_data: SessionData) -> usize {
let next_session_id = self.next_id.fetch_add(1, Ordering::Relaxed);
let mut map = self.sessions.lock().unwrap();
map.insert(next_session_id, session_data);
next_session_id
}
pub fn get(&self, session_id: usize) -> Option<SessionData> {
let mut map = self.sessions.lock().unwrap();
// Remove expired sessions
// current unix time in seconds
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs();
let keys = map.keys().cloned().collect::<Vec<_>>();
for key in keys {
if map.get(&key).unwrap().expires_at < current_time {
map.remove(&key);
}
}
// Get the session & extend its duration
let new_session = match map.get(&session_id) {
Some(s) => s.extend_duration(current_time),
None => return None,
};
let returned_session = new_session.clone();
// Update the session in the map
map.insert(session_id, new_session);
Some(returned_session)
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SessionData {
pub user_id: i32,
pub expires_at: u64,
}
impl SessionData {
// Create a new session with a duration set to 1 hour
pub fn new(user_id: i32) -> Self {
let expires_at = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs()
+ 3600;
SessionData {
user_id,
expires_at,
}
}
pub fn extend_duration(&self, current_time: u64) -> Self {
SessionData {
user_id: self.user_id,
expires_at: current_time + 3600,
}
}
}

View File

@ -1,61 +0,0 @@
use maud::Markup;
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},
model::user::User,
DefaultDB,
};
#[derive(FromForm)]
pub struct LoginData {
email: String,
password: String,
}
#[get("/login")]
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(),
};
// 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

@ -1,22 +1,3 @@
use maud::{html, Markup};
use rocket::http::CookieJar;
use crate::auth::RegularUser;
pub mod login;
pub mod register;
pub mod user;
#[get("/")]
pub fn index(user: RegularUser) -> Markup {
let RegularUser(user) = user;
html! {
"Logged in with user id: " (user.user_id) " :D"
}
}
#[get("/", rank = 2)]
pub fn index_login() -> Markup {
crate::view::login::login()
}

View File

@ -1,8 +0,0 @@
use maud::Markup;
use crate::auth::RegularUser;
#[get("/register")]
pub fn get(user: RegularUser) -> Markup {
crate::view::register::register()
}

View File

@ -1,4 +1,4 @@
use maud::{html, Markup};
use maud::{Markup, html};
use rocket::{form::Form, http::Status};
#[derive(FromForm, Debug)]
@ -15,30 +15,26 @@ pub async fn create_user(user: Form<UserCreate>) -> (Status, Markup) {
let email_domain = user.user_email.split('@').collect::<Vec<&str>>()[1];
if email_domain != "eegsac.com" {
return (
Status::BadRequest,
html! {
div id="user_create_response"
class="bg-red-500 text-white p-2 rounded transition-opacity"
classes="add opacity-0:5s, add hidden:1s"
{
"El dominio del correo electrónico debe ser eegsac.com"
}
},
);
return (Status::BadRequest, html! {
div id="user_create_response"
class="bg-red-500 text-white p-2 rounded transition-opacity"
classes="add opacity-0:5s, add hidden:1s"
{
"El dominio del correo electrónico debe ser eegsac.com"
}
});
}
(
Status::Ok,
html! {
div id="user_create_response"
class="bg-green-700 text-white p-2 rounded transition-opacity"
classes="add opacity-0:5s, add hidden:1s"
// Reset the form state
x-init="user_name = ''; user_surname = ''; user_email = ''; user_password = '';"
{
"Registrado con éxito"
}
},
)
(Status::Ok, html! {
div id="user_create_response"
class="bg-green-700 text-white p-2 rounded transition-opacity"
classes="add opacity-0:5s, add hidden:1s"
// Reset the form state
x-init="user_name = ''; user_surname = ''; user_email = ''; user_password = '';"
{
"Registrado con éxito"
}
})
}

View File

@ -1,36 +1,19 @@
use rocket::fs::FileServer;
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,
controller::index_login,
controller::register::get,
],
)
.mount(
"/f",
routes![controller::user::create_user, controller::login::login,],
)
.mount("/", routes![
view::index,
])
.mount("/f", routes![
controller::user::create_user,
])
.mount("/static", FileServer::from("static"))
}

View File

@ -1 +0,0 @@
pub mod user;

View File

@ -1,28 +0,0 @@
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())
}
}
}
}

View File

@ -1 +0,0 @@

View File

@ -1,9 +0,0 @@
use maud::{html, Markup};
use super::default_skeleton;
pub fn login() -> Markup {
default_skeleton(html! {
"NOT LOGGED IN! :O"
})
}

View File

@ -1,11 +1,7 @@
use maud::{html, Markup, DOCTYPE};
use rocket::Request;
pub mod fragments;
pub mod login;
pub mod register;
pub fn default_skeleton(content: Markup) -> Markup {
#[get("/")]
pub fn index() -> Markup {
html! {
(DOCTYPE)
html lang="es" {
@ -20,40 +16,43 @@ pub fn default_skeleton(content: Markup) -> Markup {
script defer src="https://unpkg.com/htmx.org/dist/ext/loading-states.js" {}
}
body hx-ext="response-targets, class-tools, loading-states" {
(content)
}
}
}
}
#[catch(401)]
pub fn not_authorized(req: &Request) -> Markup {
// get the uri from the request
let uri = req.uri().to_string();
// If the uri starts with "/f", then we are dealing with an API request
// and we should return a fragment
if uri.starts_with("/f") {
html! {
p style="background-color: rgb(248, 113, 113); color: white; padding: 0.5rem; border-radius: 0.5rem;"
{
"Tu sesión ha expirado, o no tienes permiso para ver esta página."
" Por favor, inicia sesión o contacta al administrador."
}
}
}
// Otherwise, we are dealing with a regular request and we should return a full page
else {
default_skeleton(html! {
div class="container mx-auto" {
p style="background-color: rgb(248, 113, 113); color: white; padding: 0.5rem; border-radius: 0.5rem;"
{
"Tu sesión ha expirado, o no tienes permiso para realizar esta acción. "
"Por favor inicia sesión."
h1 { "Registrar nuevo usuario" }
div
x-data="{user_name: '', user_surname: '', user_email: '', user_password: ''}"
{
form
hx-post="/f/user"
hx-target="#user_create_response"
hx-target-400="#user_create_response"
hx-swap="outerHTML"
{
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="text" name="user_name" placeholder="Nombres"
data-loading-disable x-model="user_name";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="text" name="user_surname" placeholder="Apellidos"
data-loading-disable x-model="user_surname";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="email" name="user_email" placeholder="Correo electrónico"
data-loading-disable x-model="user_email";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="password" name="user_password" placeholder="Contraseña"
data-loading-disable x-model="user_password";
br;
button
class="bg-pink-300 text-black py-2 px-4 rounded-full cursor-pointer inline-block my-2 disabled:opacity-50"
data-loading-class="animate-pulse" type="submit"
{
"Registrar"
}
}
br;
"Si crees que esto es un error, contacta al administrador."
div id="user_create_response" {}
}
}
})
}
}
}

View File

@ -1,44 +0,0 @@
use maud::{html, Markup};
use super::default_skeleton;
pub fn register() -> Markup {
default_skeleton(html! {
h1 { "Registrar nuevo usuario del sistema" }
div
x-data="{user_name: '', user_surname: '', user_email: '', user_password: ''}"
{
form
hx-post="/f/user"
hx-target="#user_create_response"
hx-target-400="#user_create_response"
hx-swap="outerHTML"
{
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="text" name="user_name" placeholder="Nombres"
data-loading-disable x-model="user_name";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="text" name="user_surname" placeholder="Apellidos"
data-loading-disable x-model="user_surname";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="email" name="user_email" placeholder="Correo electrónico"
data-loading-disable x-model="user_email";
br;
input class="bg-c-bg text-c-on-bg border border-c-on-bg disabled:opacity-50"
required type="password" name="user_password" placeholder="Contraseña"
data-loading-disable x-model="user_password";
br;
button
class="bg-pink-300 text-black py-2 px-4 rounded-full cursor-pointer inline-block my-2 disabled:opacity-50"
data-loading-class="animate-pulse" type="submit"
{
"Registrar"
}
}
br;
div id="user_create_response" {}
}
})
}

View File

@ -9,7 +9,7 @@
@media (prefers-color-scheme: light) {
:root {
--c-bg: #f8f8fa;
--c-bg: #fafaf0;
--c-on-bg: #101010;
}
}

View File

@ -1,8 +1,5 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
corePlugins: {
container: false
},
content: [
"./src/**/*.{html,rs}",
],
@ -14,25 +11,5 @@ module.exports = {
}
},
},
plugins: [
function ({ addComponents }) {
addComponents({
'.container': {
width: '95%',
'@screen sm': {
maxWidth: '640px',
},
'@screen md': {
maxWidth: '768px',
},
'@screen lg': {
maxWidth: '1024px',
},
'@screen xl': {
maxWidth: '1280px',
},
}
})
}
],
plugins: [],
}