Compare commits

..

5 Commits

Author SHA1 Message Date
Lennart
18882b2175 version 0.9.11 2025-10-07 22:15:24 +02:00
Lennart
580922fd6b improve error output 2025-10-07 22:14:40 +02:00
Lennart
69274a9f5d chore: Update opentelemetry 2025-10-05 17:17:56 +02:00
Lennart
ef9642ae81 version 0.9.10 2025-10-02 21:05:32 +02:00
Lennart
1c192a452f oidc: Output error when provider discovery fails 2025-10-02 21:04:59 +02:00
8 changed files with 91 additions and 44 deletions

81
Cargo.lock generated
View File

@@ -2144,9 +2144,9 @@ dependencies = [
[[package]] [[package]]
name = "opentelemetry" name = "opentelemetry"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6" checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@@ -2158,9 +2158,9 @@ dependencies = [
[[package]] [[package]]
name = "opentelemetry-http" name = "opentelemetry-http"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d" checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@@ -2171,9 +2171,9 @@ dependencies = [
[[package]] [[package]]
name = "opentelemetry-otlp" name = "opentelemetry-otlp"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
dependencies = [ dependencies = [
"http", "http",
"opentelemetry", "opentelemetry",
@@ -2190,27 +2190,28 @@ dependencies = [
[[package]] [[package]]
name = "opentelemetry-proto" name = "opentelemetry-proto"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc" checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
dependencies = [ dependencies = [
"opentelemetry", "opentelemetry",
"opentelemetry_sdk", "opentelemetry_sdk",
"prost", "prost",
"tonic", "tonic",
"tonic-prost",
] ]
[[package]] [[package]]
name = "opentelemetry-semantic-conventions" name = "opentelemetry-semantic-conventions"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2" checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846"
[[package]] [[package]]
name = "opentelemetry_sdk" name = "opentelemetry_sdk"
version = "0.30.0" version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b" checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-executor", "futures-executor",
@@ -2218,7 +2219,6 @@ dependencies = [
"opentelemetry", "opentelemetry",
"percent-encoding", "percent-encoding",
"rand 0.9.2", "rand 0.9.2",
"serde_json",
"thiserror 2.0.16", "thiserror 2.0.16",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@@ -2548,9 +2548,9 @@ dependencies = [
[[package]] [[package]]
name = "prost" name = "prost"
version = "0.13.5" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d"
dependencies = [ dependencies = [
"bytes", "bytes",
"prost-derive", "prost-derive",
@@ -2558,9 +2558,9 @@ dependencies = [
[[package]] [[package]]
name = "prost-derive" name = "prost-derive"
version = "0.13.5" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"itertools 0.14.0", "itertools 0.14.0",
@@ -2989,7 +2989,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical" name = "rustical"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"argon2", "argon2",
@@ -3032,7 +3032,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_caldav" name = "rustical_caldav"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-std", "async-std",
"async-trait", "async-trait",
@@ -3072,7 +3072,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_carddav" name = "rustical_carddav"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
@@ -3104,7 +3104,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_dav" name = "rustical_dav"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
@@ -3129,7 +3129,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_dav_push" name = "rustical_dav_push"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
@@ -3154,7 +3154,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_frontend" name = "rustical_frontend"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"askama", "askama",
"askama_web", "askama_web",
@@ -3187,7 +3187,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_ical" name = "rustical_ical"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"axum", "axum",
"chrono", "chrono",
@@ -3205,7 +3205,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_oidc" name = "rustical_oidc"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
@@ -3216,11 +3216,12 @@ dependencies = [
"serde", "serde",
"thiserror 2.0.16", "thiserror 2.0.16",
"tower-sessions", "tower-sessions",
"tracing",
] ]
[[package]] [[package]]
name = "rustical_store" name = "rustical_store"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@@ -3254,7 +3255,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_store_sqlite" name = "rustical_store_sqlite"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",
@@ -3275,7 +3276,7 @@ dependencies = [
[[package]] [[package]]
name = "rustical_xml" name = "rustical_xml"
version = "0.9.9" version = "0.9.11"
dependencies = [ dependencies = [
"quick-xml", "quick-xml",
"thiserror 2.0.16", "thiserror 2.0.16",
@@ -4192,9 +4193,9 @@ checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
[[package]] [[package]]
name = "tonic" name = "tonic"
version = "0.13.1" version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9" checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64 0.22.1", "base64 0.22.1",
@@ -4207,7 +4208,7 @@ dependencies = [
"hyper-util", "hyper-util",
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"prost", "sync_wrapper",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tower", "tower",
@@ -4216,6 +4217,17 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "tonic-prost"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67"
dependencies = [
"bytes",
"prost",
"tonic",
]
[[package]] [[package]]
name = "tower" name = "tower"
version = "0.5.2" version = "0.5.2"
@@ -4388,15 +4400,16 @@ dependencies = [
[[package]] [[package]]
name = "tracing-opentelemetry" name = "tracing-opentelemetry"
version = "0.31.0" version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c" checksum = "1e6e5658463dd88089aba75c7791e1d3120633b1bfde22478b28f625a9bb1b8e"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"once_cell",
"opentelemetry", "opentelemetry",
"opentelemetry_sdk", "opentelemetry_sdk",
"rustversion",
"smallvec", "smallvec",
"thiserror 2.0.16",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log",

View File

@@ -2,7 +2,7 @@
members = ["crates/*"] members = ["crates/*"]
[workspace.package] [workspace.package]
version = "0.9.9" version = "0.9.11"
edition = "2024" edition = "2024"
description = "A CalDAV server" description = "A CalDAV server"
documentation = "https://lennart-k.github.io/rustical/" documentation = "https://lennart-k.github.io/rustical/"
@@ -164,15 +164,15 @@ async-trait = { workspace = true }
uuid.workspace = true uuid.workspace = true
axum.workspace = true axum.workspace = true
opentelemetry = { version = "0.30", optional = true } opentelemetry = { version = "0.31", optional = true }
opentelemetry-otlp = { version = "0.30", optional = true, features = [ opentelemetry-otlp = { version = "0.31", optional = true, features = [
"grpc-tonic", "grpc-tonic",
] } ] }
opentelemetry_sdk = { version = "0.30", features = [ opentelemetry_sdk = { version = "0.31", features = [
"rt-tokio", "rt-tokio",
], optional = true } ], optional = true }
opentelemetry-semantic-conventions = { version = "0.30", optional = true } opentelemetry-semantic-conventions = { version = "0.31", optional = true }
tracing-opentelemetry = { version = "0.31", optional = true } tracing-opentelemetry = { version = "0.32", optional = true }
tracing-subscriber = { version = "0.3", features = [ tracing-subscriber = { version = "0.3", features = [
"env-filter", "env-filter",
"fmt", "fmt",

View File

@@ -11,7 +11,7 @@ use rustical_ical::CalendarObject;
use rustical_store::CalendarStore; use rustical_store::CalendarStore;
use rustical_store::auth::Principal; use rustical_store::auth::Principal;
use std::str::FromStr; use std::str::FromStr;
use tracing::{debug, instrument}; use tracing::{debug, error, instrument};
#[instrument(skip(cal_store))] #[instrument(skip(cal_store))]
pub async fn get_event<C: CalendarStore>( pub async fn get_event<C: CalendarStore>(
@@ -85,7 +85,14 @@ pub async fn put_event<C: CalendarStore>(
return Err(Error::PreconditionFailed(Precondition::ValidCalendarData)); return Err(Error::PreconditionFailed(Precondition::ValidCalendarData));
} }
}; };
assert_eq!(object.get_id(), object_id); if object.get_id() != object_id {
error!(
"Calendar object UID and file name not matching: UID={}, filename={}",
object.get_id(),
object_id
);
return Err(Error::PreconditionFailed(Precondition::MatchingUid));
}
cal_store cal_store
.put_object(principal, calendar_id, object, overwrite) .put_object(principal, calendar_id, object, overwrite)
.await?; .await?;

View File

@@ -12,6 +12,8 @@ pub enum Precondition {
#[error("valid-calendar-data")] #[error("valid-calendar-data")]
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")] #[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
ValidCalendarData, ValidCalendarData,
#[error("matching-uid")]
MatchingUid,
} }
impl IntoResponse for Precondition { impl IntoResponse for Precondition {
@@ -83,6 +85,12 @@ impl Error {
impl IntoResponse for Error { impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {
if matches!(
self.status_code(),
StatusCode::INTERNAL_SERVER_ERROR | StatusCode::PRECONDITION_FAILED
) {
error!("{self}");
}
(self.status_code(), self.to_string()).into_response() (self.status_code(), self.to_string()).into_response()
} }
} }

View File

@@ -1,3 +1,4 @@
use axum::body::Body;
use http::StatusCode; use http::StatusCode;
use rustical_xml::XmlError; use rustical_xml::XmlError;
use thiserror::Error; use thiserror::Error;
@@ -59,7 +60,12 @@ impl Error {
impl axum::response::IntoResponse for Error { impl axum::response::IntoResponse for Error {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {
use axum::body::Body; if matches!(
self.status_code(),
StatusCode::INTERNAL_SERVER_ERROR | StatusCode::PRECONDITION_FAILED
) {
error!("{self}");
}
let mut resp = axum::response::Response::builder().status(self.status_code()); let mut resp = axum::response::Response::builder().status(self.status_code());
if matches!(&self, &Error::Unauthorized) { if matches!(&self, &Error::Unauthorized) {

View File

@@ -17,3 +17,4 @@ axum.workspace = true
tower-sessions = "0.14" tower-sessions = "0.14"
axum-extra.workspace = true axum-extra.workspace = true
headers.workspace = true headers.workspace = true
tracing.workspace = true

View File

@@ -76,7 +76,10 @@ async fn get_oidc_client(
> { > {
let provider_metadata = CoreProviderMetadata::discover_async(issuer, http_client) let provider_metadata = CoreProviderMetadata::discover_async(issuer, http_client)
.await .await
.map_err(|_| OidcError::Other("Failed to discover OpenID provider"))?; .map_err(|err| {
tracing::error!("An error occured trying to discover OpenID provider: {err}");
OidcError::Other("Failed to discover OpenID provider")
})?;
Ok(CoreClient::from_provider_metadata( Ok(CoreClient::from_provider_metadata(
provider_metadata.clone(), provider_metadata.clone(),

View File

@@ -1,5 +1,6 @@
use axum::response::IntoResponse; use axum::response::IntoResponse;
use http::StatusCode; use http::StatusCode;
use tracing::error;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum Error { pub enum Error {
@@ -43,6 +44,14 @@ impl Error {
impl IntoResponse for Error { impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response { fn into_response(self) -> axum::response::Response {
if matches!(
self.status_code(),
StatusCode::INTERNAL_SERVER_ERROR
| StatusCode::PRECONDITION_FAILED
| StatusCode::CONFLICT
) {
error!("{self}");
}
(self.status_code(), self.to_string()).into_response() (self.status_code(), self.to_string()).into_response()
} }
} }