From a3901b84b73c36fb5263b438b4550be20bc0fd6c Mon Sep 17 00:00:00 2001 From: Noel Date: Thu, 13 Feb 2025 08:19:29 -0800 Subject: [PATCH] Fix tests in `charted-server::middleware::sesions` --- Cargo.lock | 32 +------------------ crates/core/src/api.rs | 2 +- crates/database/Cargo.toml | 2 -- crates/server/src/middleware/sessions.rs | 24 +++++++++++--- .../server/src/middleware/sessions/error.rs | 23 +++++++++---- .../src/middleware/sessions/tests/basic.rs | 29 ++++++++++++++--- src/charted/Cargo.toml | 1 - 7 files changed, 62 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6425f412f..72af6b99e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1133,7 +1133,6 @@ dependencies = [ "dotenvy", "eyre", "mimalloc", - "num_cpus", "tokio", ] @@ -1254,9 +1253,7 @@ dependencies = [ "eyre", "sea-orm", "sea-orm-migration", - "sqlx", "tracing", - "url", ] [[package]] @@ -3323,7 +3320,7 @@ dependencies = [ "tokio-util", "typed-builder", "uuid", - "webpki-roots 0.25.4", + "webpki-roots", ] [[package]] @@ -4257,7 +4254,6 @@ checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "aws-lc-rs", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -4995,18 +4991,13 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rustls 0.23.23", - "rustls-pemfile 2.2.0", "serde", "serde_json", "sha2", "smallvec", "thiserror 2.0.11", - "tokio", - "tokio-stream", "tracing", "url", - "webpki-roots 0.26.8", ] [[package]] @@ -5044,7 +5035,6 @@ dependencies = [ "sqlx-sqlite", "syn 2.0.98", "tempfile", - "tokio", "url", ] @@ -5487,17 +5477,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.13" @@ -6038,15 +6017,6 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" -[[package]] -name = "webpki-roots" -version = "0.26.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "which" version = "4.4.2" diff --git a/crates/core/src/api.rs b/crates/core/src/api.rs index 6fc6d0a48..5f192a432 100644 --- a/crates/core/src/api.rs +++ b/crates/core/src/api.rs @@ -188,7 +188,7 @@ pub struct Error { /// /// This field can be looked up from the documentation to give /// a better representation of the error. -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum ErrorCode { diff --git a/crates/database/Cargo.toml b/crates/database/Cargo.toml index 4e75a38f2..d296a12b6 100644 --- a/crates/database/Cargo.toml +++ b/crates/database/Cargo.toml @@ -32,6 +32,4 @@ charted-types = { workspace = true, features = ["__internal_db"] } eyre.workspace = true sea-orm.workspace = true sea-orm-migration.workspace = true -sqlx.workspace = true tracing = { workspace = true, features = ["log"] } -url.workspace = true diff --git a/crates/server/src/middleware/sessions.rs b/crates/server/src/middleware/sessions.rs index 4689bc86a..53266b3b1 100644 --- a/crates/server/src/middleware/sessions.rs +++ b/crates/server/src/middleware/sessions.rs @@ -128,6 +128,7 @@ impl Middleware { Some((_, pass)) if pass.contains(':') => { return Err(as_response(Error::msg( "received more than one `:` in basic auth input", + None, ))) } @@ -135,6 +136,7 @@ impl Middleware { None => { return Err(as_response(Error::msg( "input must be in the form of 'username:password'", + None, ))) } }; @@ -228,7 +230,12 @@ impl Middleware { .filter(|x| matches!(x, Value::String(_))) .and_then(Value::as_str) .map(Ulid::new) - .ok_or_else(|| as_response(Error::msg(format!("missing `{}` JWT claim", JWT_UID_FIELD))))? + .ok_or_else(|| { + as_response(Error::msg( + format!("missing `{}` JWT claim", JWT_UID_FIELD), + Some(api::ErrorCode::InvalidJwtClaim), + )) + })? .map_err(Error::DecodeUlid) .map_err(as_response)?; @@ -238,7 +245,12 @@ impl Middleware { .filter(|x| matches!(x, Value::String(_))) .and_then(Value::as_str) .map(Ulid::new) - .ok_or_else(|| as_response(Error::msg(format!("missing `{}` JWT claim", JWT_SID_FIELD))))? + .ok_or_else(|| { + as_response(Error::msg( + format!("missing `{}` JWT claim", JWT_SID_FIELD), + Some(api::ErrorCode::InvalidJwtClaim), + )) + })? .map_err(Error::DecodeUlid) .map_err(as_response)?; @@ -385,9 +397,10 @@ impl AsyncAuthorizeRequest for Middleware { Some((_, value)) if value.contains(' ') => { let space = value.chars().position(|x| x == ' ').unwrap_or_default(); return Box::pin(async move { - Err(as_response(Error::msg(format!( - "received extra space at {space} when parsing header" - )))) + Err(as_response(Error::msg( + format!("received extra space at {space} when parsing header"), + None, + ))) }); } @@ -400,6 +413,7 @@ impl AsyncAuthorizeRequest for Middleware { return Box::pin(async { Err(as_response(Error::msg( "auth header must be in the form of 'Type Value', i.e, 'ApiKey hjdjshdjs'", + None, ))) }) } diff --git a/crates/server/src/middleware/sessions/error.rs b/crates/server/src/middleware/sessions/error.rs index a80a327a2..03168c080 100644 --- a/crates/server/src/middleware/sessions/error.rs +++ b/crates/server/src/middleware/sessions/error.rs @@ -26,8 +26,14 @@ pub enum Error { UnknownAuthType(#[error(not(source))] Cow<'static, str>), DecodeBase64(base64::DecodeError), - #[display("{}", _0)] - Message(#[error(not(source))] Cow<'static, str>), + #[display("{}", message)] + Message { + #[error(not(source))] + message: Cow<'static, str>, + + #[error(not(source))] + code: Option, + }, DecodeUlid(charted_types::ulid::DecodeError), @@ -58,11 +64,14 @@ pub enum Error { impl Error { pub(crate) fn invalid_utf8() -> Self { - Error::msg("invalid utf-8 content") + Error::msg("invalid utf-8 content", Some(api::ErrorCode::InvalidUtf8)) } - pub(crate) fn msg>>(msg: M) -> Self { - Error::Message(msg.into()) + pub(crate) fn msg>>(msg: M, code: Option) -> Self { + Error::Message { + message: msg.into(), + code, + } } pub fn status_code(&self) -> StatusCode { @@ -71,7 +80,7 @@ impl Error { match self { E::MissingAuthorizationHeader | E::UnknownAuthType(_) - | E::Message(_) + | E::Message { .. } | E::DecodeBase64(_) | E::RefreshTokenRequired | E::DecodeUlid(_) @@ -97,7 +106,7 @@ impl Error { E::InvalidPassword => InvalidPassword, E::UnknownSession => UnknownSession, E::MissingAuthorizationHeader => MissingAuthorizationHeader, - E::Message(_) => InvalidAuthorizationParts, + E::Message { code, .. } => code.unwrap_or(api::ErrorCode::InvalidAuthorizationParts), E::UnknownAuthType(_) => InvalidAuthenticationType, E::DecodeBase64(_) => UnableToDecodeBase64, E::DecodeUlid(_) => UnableToDecodeUlid, diff --git a/crates/server/src/middleware/sessions/tests/basic.rs b/crates/server/src/middleware/sessions/tests/basic.rs index f3eb24e92..9d924336e 100644 --- a/crates/server/src/middleware/sessions/tests/basic.rs +++ b/crates/server/src/middleware/sessions/tests/basic.rs @@ -23,6 +23,7 @@ use axum::{ }; use base64::{engine::general_purpose::STANDARD, Engine}; use charted_core::api::{self, ErrorCode}; +use charted_types::name; use std::borrow::Cow; use tower::{Service, ServiceExt}; @@ -78,7 +79,11 @@ async fn decoding_error_missing_colon() { let body = consume_body::(res.into_body()).await; assert_eq!( body, - Error::Message(Cow::Borrowed("input must be in the form of 'username:password'")).into() + Error::Message { + message: Cow::Borrowed("input must be in the form of 'username:password'"), + code: None + } + .into() ); } @@ -107,7 +112,11 @@ async fn decoding_error_more_than_one_colon() { let body = consume_body::(res.into_body()).await; assert_eq!( body, - Error::Message(Cow::Borrowed("received more than one `:` in basic auth input")).into() + Error::Message { + message: Cow::Borrowed("received more than one `:` in basic auth input"), + code: None + } + .into() ); } @@ -136,7 +145,15 @@ async fn invalid_name_in_username() { let body = consume_body::(res.into_body()).await; assert_eq!( body, - Error::Message(Cow::Borrowed("invalid input (noelisTHEbEST!!!!~) for Name: invalid character '!' received (index 13 in input: \"noelisthebest!!!!~\")")).into() + Error::InvalidName { + input: Cow::Borrowed("noelisTHEbEST!!!!~"), + error: name::Error::InvalidCharacter { + input: Cow::Borrowed("noelisthebest!!!!~"), + at: 13, + ch: '!' + } + } + .into() ); } @@ -165,6 +182,10 @@ async fn empty_username() { let body = consume_body::(res.into_body()).await; assert_eq!( body, - Error::Message(Cow::Borrowed("invalid input () for Name: name cannot be empty")).into() + Error::InvalidName { + input: Cow::Borrowed(""), + error: name::Error::Empty, + } + .into() ); } diff --git a/src/charted/Cargo.toml b/src/charted/Cargo.toml index 0da4dd7f7..7afe5c8ce 100644 --- a/src/charted/Cargo.toml +++ b/src/charted/Cargo.toml @@ -35,5 +35,4 @@ color-eyre.workspace = true dotenvy = "0.15.7" eyre.workspace = true mimalloc = "0.1.43" -num_cpus.workspace = true tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }