From 601b2d4f42e36ebb9db251543ea4d6471db7c7f9 Mon Sep 17 00:00:00 2001 From: Patrick Michl Date: Tue, 26 Apr 2022 23:03:45 +0200 Subject: [PATCH] add password hashing and simple ci --- .drone.yml | 9 +++ Cargo.lock | 55 +++++++++++++++++++ Cargo.toml | 18 +++--- src/api/client_server/auth.rs | 12 +++- src/api/client_server/errors/api_error.rs | 2 +- .../errors/registration_error.rs | 2 +- src/models/users.rs | 2 +- src/types/mod.rs | 2 +- 8 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..5bcfd2a --- /dev/null +++ b/.drone.yml @@ -0,0 +1,9 @@ +kind: pipeline +type: docker +name: check + +steps: +- name: cargo check + image: rust:latest + commands: + - cargo check \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index beb981d..ebf3dfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,17 @@ version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +[[package]] +name = "argon2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27e27b63e4a34caee411ade944981136fdfa535522dc9944d6700196cbd899f" +dependencies = [ + "base64ct", + "blake2", + "password-hash", +] + [[package]] name = "async-trait" version = "0.1.53" @@ -105,12 +116,27 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "blake2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.2" @@ -212,6 +238,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -572,7 +599,9 @@ name = "matrix" version = "0.1.0" dependencies = [ "anyhow", + "argon2", "axum", + "rand_core", "serde", "sqlx", "thiserror", @@ -715,6 +744,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "password-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + [[package]] name = "paste" version = "1.0.7" @@ -783,6 +823,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -1081,6 +1130,12 @@ dependencies = [ "unicode-normalization", ] +[[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.91" diff --git a/Cargo.toml b/Cargo.toml index a57a17b..4615aad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tokio = { version = "1.17.0", features = ["full"] } -axum = "0.5.3" -tracing = "0.1.34" -tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } -serde = {version = "1.0.136", features = ["derive"] } -tower-http = { version = "0.2.5", features = ["cors", "trace"]} -sqlx = { version = "0.5.13", features = ["sqlite", "macros", "runtime-tokio-rustls"] } +tokio = { version = "1.17", features = ["full"] } +axum = "0.5" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +serde = {version = "1.0", features = ["derive"] } +tower-http = { version = "0.2", features = ["cors", "trace"]} +sqlx = { version = "0.5", features = ["sqlite", "macros", "runtime-tokio-rustls"] } anyhow = "1.0" -thiserror = "1.0" \ No newline at end of file +thiserror = "1.0" +argon2 = "0.4" +rand_core = { version = "0.6", features = ["std"] } \ No newline at end of file diff --git a/src/api/client_server/auth.rs b/src/api/client_server/auth.rs index 3971d6d..06fea9e 100644 --- a/src/api/client_server/auth.rs +++ b/src/api/client_server/auth.rs @@ -1,11 +1,13 @@ use std::{collections::HashMap, sync::Arc}; +use argon2::{password_hash::SaltString, Argon2, PasswordHasher}; use axum::{ extract::Query, http::StatusCode, routing::{get, post}, Extension, Json, }; +use rand_core::OsRng; use sqlx::SqlitePool; use crate::responses::registration::RegistrationResponse; @@ -17,7 +19,7 @@ use crate::{ models::users::User, requests::registration::RegistrationRequest, responses::username_available::UsernameAvailable, - types::{authentication_data::AuthenticationData, matrix_user_id::UserId}, + types::{authentication_data::AuthenticationData, user_id::UserId}, Config, }; @@ -79,14 +81,18 @@ async fn post_register( .then(|| ()) .ok_or(RegistrationError::UserIdTaken)?; - let password = auth_data.password(); + let salt = SaltString::generate(OsRng); + let argon2 = Argon2::default(); + let pw_hash = argon2 + .hash_password(auth_data.password().as_bytes(), &salt)? + .to_string(); let display_name = match body.initial_device_display_name() { Some(display_name) => display_name.as_ref(), None => "Random displayname", }; - let user = User::create(&db, &user_id, &user_id.to_string(), password).await?; + let user = User::create(&db, &user_id, &user_id.to_string(), &pw_hash).await?; let device = Device::create(&db, &user, "test", display_name).await?; (user, device) diff --git a/src/api/client_server/errors/api_error.rs b/src/api/client_server/errors/api_error.rs index a665a05..1d920c8 100644 --- a/src/api/client_server/errors/api_error.rs +++ b/src/api/client_server/errors/api_error.rs @@ -96,7 +96,7 @@ impl IntoResponse for ApiError { )), ) .into_response() - } + }, ApiError::Generic(err) => ( StatusCode::INTERNAL_SERVER_ERROR, Json(ErrorResponse::new( diff --git a/src/api/client_server/errors/registration_error.rs b/src/api/client_server/errors/registration_error.rs index c03749c..5805abc 100644 --- a/src/api/client_server/errors/registration_error.rs +++ b/src/api/client_server/errors/registration_error.rs @@ -7,5 +7,5 @@ pub enum RegistrationError { #[error("The desired user ID is not a valid user name")] InvalidUserId, #[error("The desired user ID is already taken")] - UserIdTaken, + UserIdTaken } diff --git a/src/models/users.rs b/src/models/users.rs index 4e56a07..332051d 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,6 +1,6 @@ use sqlx::SqlitePool; -use crate::types::matrix_user_id::UserId; +use crate::types::user_id::UserId; pub struct User { id: i64, diff --git a/src/types/mod.rs b/src/types/mod.rs index e6d839d..4859701 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -3,5 +3,5 @@ pub mod error_code; pub mod flow; pub mod identifier; pub mod identifier_type; -pub mod matrix_user_id; +pub mod user_id; pub mod user_interactive_authorization;