Started JWT token generation

pull/36/head
Jef Roosens 2021-08-21 13:46:41 +02:00
parent d90dbcdc2a
commit 6782fecc0d
Signed by: Jef Roosens
GPG Key ID: 955C0660072F691F
5 changed files with 203 additions and 9 deletions

163
Cargo.lock generated
View File

@ -107,6 +107,15 @@ dependencies = [
"constant_time_eq",
]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.7.0"
@ -137,6 +146,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time 0.1.44",
"winapi",
]
[[package]]
name = "const_fn"
version = "0.4.8"
@ -156,10 +178,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d"
dependencies = [
"percent-encoding",
"time",
"time 0.2.27",
"version_check",
]
[[package]]
name = "cpufeatures"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
@ -170,6 +201,16 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "crypto-mac"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
"generic-array",
"subtle",
]
[[package]]
name = "devise"
version = "0.3.1"
@ -238,6 +279,15 @@ dependencies = [
"migrations_macros",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]]
name = "discard"
version = "1.0.4"
@ -401,6 +451,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.3"
@ -452,6 +512,16 @@ dependencies = [
"libc",
]
[[package]]
name = "hmac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
dependencies = [
"crypto-mac",
"digest",
]
[[package]]
name = "http"
version = "0.2.4"
@ -542,6 +612,21 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "jwt"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7487a802642fa9b162acacad3ed52c7e47ed4108d5fac6125cc7742dfaf622bf"
dependencies = [
"base64",
"crypto-mac",
"digest",
"hmac",
"serde",
"serde_json",
"sha2",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -669,6 +754,25 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
@ -685,6 +789,12 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.36"
@ -961,7 +1071,7 @@ dependencies = [
"serde_json",
"state",
"tempfile",
"time",
"time 0.2.27",
"tokio",
"tokio-stream",
"tokio-util",
@ -1009,7 +1119,7 @@ dependencies = [
"smallvec",
"stable-pattern",
"state",
"time",
"time 0.2.27",
"tokio",
"uncased",
]
@ -1069,14 +1179,18 @@ checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
name = "rusty-bever"
version = "0.1.0"
dependencies = [
"chrono",
"diesel",
"diesel_migrations",
"hmac",
"jwt",
"openssl",
"rand",
"rocket",
"rocket_sync_db_pools",
"rust-argon2",
"serde",
"sha2",
"uuid",
]
@ -1159,6 +1273,19 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "sha2"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer",
"cfg-if",
"cpufeatures",
"digest",
"opaque-debug",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
@ -1272,6 +1399,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.74"
@ -1297,6 +1430,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "time"
version = "0.2.27"
@ -1441,6 +1585,12 @@ dependencies = [
"unchecked-index",
]
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "ubyte"
version = "0.10.1"
@ -1477,6 +1627,9 @@ name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"serde",
]
[[package]]
name = "vcpkg"
@ -1502,9 +1655,9 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"

View File

@ -23,7 +23,11 @@ openssl = "0.10.36"
# For password hashing & verification
rust-argon2 = "0.8.3"
rand = "0.8.4"
uuid = "0.8.2"
uuid = { version = "0.8.2", features = ["serde"] }
jwt = "0.14.0"
hmac = "*"
sha2 = "*"
chrono = "0.4.19"
# Backend web framework
[dependencies.rocket]

View File

@ -4,6 +4,16 @@ use crate::schema::users::dsl as users;
use argon2::verify_encoded;
use diesel::prelude::*;
use diesel::PgConnection;
use hmac::{Hmac, NewMac};
use jwt::SignWithKey;
use sha2::Sha256;
use std::collections::HashMap;
use chrono::Utc;
/// Expire time for the JWT tokens in seconds.
const JWT_EXP_SECONDS: i64 = 900;
/// Amount of bytes the refresh tokens should consist of
const REFRESH_TOKEN_N_BYTES: u32 = 64;
pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> Result<User, AuthError> {
// TODO handle non-"NotFound" Diesel errors accordingely
@ -20,3 +30,24 @@ pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> Resul
_ => Err(AuthError::InvalidPassword),
}
}
struct JWTResponse {
token: String,
refresh_token: String
}
pub fn generate_jwt_token(conn: &PgConnection, user: &User) -> JWTResponse {
// TODO actually use proper secret here
// TODO don't just unwrap here
let key: Hmac<Sha256> = Hmac::new_from_slice(b"some-secret").unwrap();
// Create the claims
let mut claims = HashMap::new();
claims.insert("id", user.id.to_string());
claims.insert("username", user.username);
claims.insert("exp", (Utc::now().timestamp() + JWT_EXP_SECONDS).to_string());
// Sign the claims into a new token
// TODO don't just unwrap here
let token = claims.sign_with_key(&key).unwrap();
}

View File

@ -1,11 +1,14 @@
use diesel::Queryable;
use uuid::Uuid;
use serde::Serialize;
#[derive(Queryable)]
#[derive(Queryable, Serialize)]
pub struct User {
id: Uuid,
username: String,
pub id: Uuid,
pub username: String,
#[serde(skip_serializing)]
pub password: String,
#[serde(skip_serializing)]
blocked: bool,
admin: bool,
}

View File

@ -11,9 +11,12 @@ struct Credentials {
#[post("/login", data = "<credentials>")]
async fn login(conn: RbDbConn, credentials: Json<Credentials>) {
let credentials = credentials.into_inner();
let user = conn
.run(move |c| verify_user(c, &credentials.username, &credentials.password))
.await;
user
}
// /refresh