Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ async-stream = "0.3"
async-trait = "0.1"
axum = { version = "0.8", default-features = false }
backtrace = "0.3.76"
blake3 = "1.8.3"
bytes = "1.11"
cargo_toml = "0.22"
chrono = { version = "0.4.44", default-features = false }
Expand All @@ -85,7 +86,6 @@ darling = "0.23"
deadpool-redis = { version = "0.23", default-features = false }
derive_builder = "0.20"
derive_more = "2"
digest = "0.10"
email_address = "0.2.9"
fake = "4"
fantoccini = "0.22"
Expand All @@ -97,7 +97,6 @@ glob = "0.3"
grass = { version = "0.13.4", default-features = false }
heck = "0.5"
hex = "0.4"
hmac = "0.12"
http = "1.4"
http-body = "1"
http-body-util = "0.1.3"
Expand Down Expand Up @@ -130,7 +129,6 @@ serde_html_form = { version = "0.4", default-features = false }
serde_json = "1"
serde_path_to_error = "0.1.20"
serde_urlencoded = "0.7"
sha2 = "0.10"
sqlx = { version = "0.8", default-features = false }
subtle = { version = "2", default-features = false }
swagger-ui-redist = { version = "0.1" }
Expand Down
4 changes: 1 addition & 3 deletions cot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ aide = { workspace = true, optional = true }
askama = { workspace = true, features = ["std"] }
async-trait.workspace = true
axum = { workspace = true, features = ["http1", "tokio"] }
blake3.workspace = true
bytes.workspace = true
chrono = { workspace = true, features = ["alloc", "serde", "clock"] }
chrono-tz.workspace = true
Expand All @@ -30,14 +31,12 @@ cot_macros.workspace = true
deadpool-redis = { workspace = true, features = ["tokio-comp", "rt_tokio_1"], optional = true }
derive_builder.workspace = true
derive_more = { workspace = true, features = ["debug", "deref", "display", "from"] }
digest.workspace = true
email_address.workspace = true
fake = { workspace = true, optional = true, features = ["derive", "chrono"] }
form_urlencoded.workspace = true
futures-core.workspace = true
futures-util.workspace = true
hex.workspace = true
hmac.workspace = true
http-body-util.workspace = true
http.workspace = true
humantime.workspace = true
Expand All @@ -55,7 +54,6 @@ sea-query = { workspace = true, optional = true }
sea-query-binder = { workspace = true, features = ["with-chrono", "runtime-tokio"], optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, optional = true }
sha2.workspace = true
sqlx = { workspace = true, features = ["runtime-tokio", "chrono"], optional = true }
subtle = { workspace = true, features = ["std"] }
swagger-ui-redist = { workspace = true, optional = true }
Expand Down
28 changes: 10 additions & 18 deletions cot/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,12 @@ pub trait User {
/// use cot::auth::{SessionAuthHash, User, UserId};
/// use cot::common_types::Password;
/// use cot::config::SecretKey;
/// use hmac::{Hmac, Mac};
/// use sha2::Sha512;
///
/// struct MyUser {
/// id: i64,
/// password: Password,
/// }
///
/// type SessionAuthHmac = Hmac<Sha512>;
///
/// impl User for MyUser {
/// fn id(&self) -> Option<UserId> {
/// Some(UserId::Int(self.id))
Expand All @@ -211,12 +207,12 @@ pub trait User {
/// // thanks to this, the session hash is invalidated when the user changes their password
/// // and the user is automatically logged out
///
/// let mut mac = SessionAuthHmac::new_from_slice(secret_key.as_bytes())
/// .expect("HMAC can take key of any size");
/// mac.update(self.password.as_str().as_bytes());
/// let hmac_data = mac.finalize().into_bytes();
/// const SESSION_AUTH_HASH_CONTEXT: &'static str = "cot.rs session auth hash v1";
///
/// let key = blake3::derive_key(SESSION_AUTH_HASH_CONTEXT, secret_key.as_bytes());
/// let hash = blake3::keyed_hash(&key, self.password.as_str().as_bytes());
///
/// Some(SessionAuthHash::new(&hmac_data))
/// Some(SessionAuthHash::new(hash.as_slice()))
/// }
/// }
/// ```
Expand Down Expand Up @@ -350,16 +346,12 @@ impl User for AnonymousUser {}
/// use cot::auth::{SessionAuthHash, User, UserId};
/// use cot::common_types::Password;
/// use cot::config::SecretKey;
/// use hmac::{Hmac, Mac};
/// use sha2::Sha512;
///
/// struct MyUser {
/// id: i64,
/// password: Password,
/// }
///
/// type SessionAuthHmac = Hmac<Sha512>;
///
/// impl User for MyUser {
/// fn id(&self) -> Option<UserId> {
/// Some(UserId::Int(self.id))
Expand All @@ -381,12 +373,12 @@ impl User for AnonymousUser {}
/// // thanks to this, the session hash is invalidated when the user changes their password
/// // and the user is automatically logged out
///
/// let mut mac = SessionAuthHmac::new_from_slice(secret_key.as_bytes())
/// .expect("HMAC can take key of any size");
/// mac.update(self.password.as_str().as_bytes());
/// let hmac_data = mac.finalize().into_bytes();
/// const SESSION_AUTH_HASH_CONTEXT: &'static str = "cot.rs session auth hash v1";
///
/// let key = blake3::derive_key(SESSION_AUTH_HASH_CONTEXT, secret_key.as_bytes());
/// let hash = blake3::keyed_hash(&key, self.password.as_str().as_bytes());
///
/// Some(SessionAuthHash::new(&hmac_data))
/// Some(SessionAuthHash::new(hash.as_slice()))
/// }
/// }
/// ```
Expand Down
14 changes: 5 additions & 9 deletions cot/src/auth/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ use async_trait::async_trait;
// can figure out it's an autogenerated field
use cot::db::Auto;
use cot_macros::AdminModel;
use hmac::{Hmac, Mac};
use sha2::Sha512;
use thiserror::Error;

use crate::App;
Expand Down Expand Up @@ -345,8 +343,6 @@ impl DatabaseUser {
}
}

type SessionAuthHmac = Hmac<Sha512>;

impl User for DatabaseUser {
fn id(&self) -> Option<UserId> {
Some(UserId::Int(self.id()))
Expand All @@ -365,12 +361,12 @@ impl User for DatabaseUser {
}

fn session_auth_hash(&self, secret_key: &SecretKey) -> Option<SessionAuthHash> {
let mut mac = SessionAuthHmac::new_from_slice(secret_key.as_bytes())
.expect("HMAC can take key of any size");
mac.update(self.password.as_str().as_bytes());
let hmac_data = mac.finalize().into_bytes();
const SESSION_AUTH_HASH_CONTEXT: &str = "cot.rs session auth hash v1";

let key = blake3::derive_key(SESSION_AUTH_HASH_CONTEXT, secret_key.as_bytes());
let hash = blake3::keyed_hash(&key, self.password.as_str().as_bytes());

Some(SessionAuthHash::new(&hmac_data))
Some(SessionAuthHash::new(hash.as_slice()))
}
}

Expand Down
3 changes: 1 addition & 2 deletions cot/src/static_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use std::time::Duration;

use bytes::Bytes;
use cot_core::error::impl_into_cot_error;
use digest::Digest;
use futures_core::ready;
use http::{Request, header};
use pin_project_lite::pin_project;
Expand Down Expand Up @@ -128,7 +127,7 @@ impl StaticFiles {

#[must_use]
fn file_hash(file: &StaticFile) -> String {
hex::encode(&sha2::Sha256::digest(&file.content).as_slice()[0..6])
hex::encode(&blake3::hash(file.content.as_ref()).as_slice()[0..6])
}

#[must_use]
Expand Down
1 change: 1 addition & 0 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ allow = [
"0BSD",
"Apache-2.0 WITH LLVM-exception",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"BSL-1.0",
"CDLA-Permissive-2.0",
Expand Down
Loading