mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-27 06:29:27 +00:00
Compare commits
6 Commits
v0.9.10
...
8ed4db5824
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ed4db5824 | ||
|
|
43d7aabf28 | ||
|
|
2fc51fac66 | ||
|
|
18882b2175 | ||
|
|
580922fd6b | ||
|
|
69274a9f5d |
80
Cargo.lock
generated
80
Cargo.lock
generated
@@ -2144,9 +2144,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6"
|
||||
checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -2158,9 +2158,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-http"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d"
|
||||
checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -2171,9 +2171,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-otlp"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b"
|
||||
checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf"
|
||||
dependencies = [
|
||||
"http",
|
||||
"opentelemetry",
|
||||
@@ -2190,27 +2190,28 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-proto"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc"
|
||||
checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
|
||||
dependencies = [
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
"prost",
|
||||
"tonic",
|
||||
"tonic-prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-semantic-conventions"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2"
|
||||
checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846"
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry_sdk"
|
||||
version = "0.30.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b"
|
||||
checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-executor",
|
||||
@@ -2218,7 +2219,6 @@ dependencies = [
|
||||
"opentelemetry",
|
||||
"percent-encoding",
|
||||
"rand 0.9.2",
|
||||
"serde_json",
|
||||
"thiserror 2.0.16",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -2548,9 +2548,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.5"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
|
||||
checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
@@ -2558,9 +2558,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.5"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -2989,7 +2989,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -3032,7 +3032,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_caldav"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
@@ -3072,7 +3072,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_carddav"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3104,7 +3104,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3129,7 +3129,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav_push"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3154,7 +3154,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_frontend"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"askama_web",
|
||||
@@ -3187,7 +3187,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_ical"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"chrono",
|
||||
@@ -3205,7 +3205,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_oidc"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3221,7 +3221,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3255,7 +3255,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store_sqlite"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
@@ -3276,7 +3276,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_xml"
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
dependencies = [
|
||||
"quick-xml",
|
||||
"thiserror 2.0.16",
|
||||
@@ -4193,9 +4193,9 @@ checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.13.1"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9"
|
||||
checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
@@ -4208,7 +4208,7 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
@@ -4217,6 +4217,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "tower"
|
||||
version = "0.5.2"
|
||||
@@ -4389,15 +4400,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-opentelemetry"
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c"
|
||||
checksum = "1e6e5658463dd88089aba75c7791e1d3120633b1bfde22478b28f625a9bb1b8e"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
"rustversion",
|
||||
"smallvec",
|
||||
"thiserror 2.0.16",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -2,7 +2,7 @@
|
||||
members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.9.10"
|
||||
version = "0.9.12"
|
||||
edition = "2024"
|
||||
description = "A CalDAV server"
|
||||
documentation = "https://lennart-k.github.io/rustical/"
|
||||
@@ -164,15 +164,15 @@ async-trait = { workspace = true }
|
||||
uuid.workspace = true
|
||||
axum.workspace = true
|
||||
|
||||
opentelemetry = { version = "0.30", optional = true }
|
||||
opentelemetry-otlp = { version = "0.30", optional = true, features = [
|
||||
opentelemetry = { version = "0.31", optional = true }
|
||||
opentelemetry-otlp = { version = "0.31", optional = true, features = [
|
||||
"grpc-tonic",
|
||||
] }
|
||||
opentelemetry_sdk = { version = "0.30", features = [
|
||||
opentelemetry_sdk = { version = "0.31", features = [
|
||||
"rt-tokio",
|
||||
], optional = true }
|
||||
opentelemetry-semantic-conventions = { version = "0.30", optional = true }
|
||||
tracing-opentelemetry = { version = "0.31", optional = true }
|
||||
opentelemetry-semantic-conventions = { version = "0.31", optional = true }
|
||||
tracing-opentelemetry = { version = "0.32", optional = true }
|
||||
tracing-subscriber = { version = "0.3", features = [
|
||||
"env-filter",
|
||||
"fmt",
|
||||
|
||||
@@ -32,10 +32,6 @@ pub async fn route_get<C: CalendarStore, S: SubscriptionStore>(
|
||||
return Err(crate::Error::Unauthorized);
|
||||
}
|
||||
|
||||
let calendar = cal_store
|
||||
.get_calendar(&principal, &calendar_id, true)
|
||||
.await?;
|
||||
|
||||
let mut timezones = HashMap::new();
|
||||
let mut vtimezones = HashMap::new();
|
||||
let objects = cal_store.get_objects(&principal, &calendar_id).await?;
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
use ical::generator::IcalEvent;
|
||||
use rustical_ical::{CalendarObject, CalendarObjectComponent, CalendarObjectType};
|
||||
|
||||
use crate::calendar::methods::report::calendar_query::{
|
||||
CompFilterElement, PropFilterElement, TimeRangeElement,
|
||||
};
|
||||
|
||||
pub trait CompFilterable {
|
||||
fn get_comp_name(&self) -> &'static str;
|
||||
|
||||
fn match_time_range(&self, time_range: &TimeRangeElement) -> bool;
|
||||
|
||||
fn match_prop_filter(&self, prop_filter: &PropFilterElement) -> bool;
|
||||
|
||||
fn match_subcomponents(&self, comp_filter: &CompFilterElement) -> bool;
|
||||
|
||||
fn matches(&self, comp_filter: &CompFilterElement) -> bool {
|
||||
let name_matches = self.get_comp_name() != comp_filter.name;
|
||||
match (comp_filter.is_not_defined.is_some(), name_matches) {
|
||||
// We are the component that's not supposed to be defined
|
||||
(true, true) => return false,
|
||||
// We shall not be and indeed we aren't
|
||||
(true, false) => return true,
|
||||
// We don't match
|
||||
(false, false) => return false,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(time_range) = comp_filter.time_range.as_ref()
|
||||
&& !self.match_time_range(time_range)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for prop_filter in &comp_filter.prop_filter {
|
||||
if !self.match_prop_filter(prop_filter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// let subcomponents = self.get_subcomponents();
|
||||
// for sub_comp_filter in &comp_filter.comp_filter {
|
||||
// if sub_comp_filter.is_not_defined.is_some() {
|
||||
// // If is_not_defined: Filter shuold match for all
|
||||
// // Confusing logic but matching also means not being the component that
|
||||
// // shouldn't be defined
|
||||
// if subcomponents
|
||||
// .iter()
|
||||
// .any(|sub| !sub.matches(sub_comp_filter))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// } else {
|
||||
// // otherwise if no component matches return false
|
||||
// if !subcomponents.iter().any(|sub| sub.matches(sub_comp_filter)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
comp_filter
|
||||
.comp_filter
|
||||
.iter()
|
||||
.all(|filter| self.match_subcomponents(filter))
|
||||
}
|
||||
}
|
||||
|
||||
impl CompFilterable for CalendarObject {
|
||||
fn get_comp_name(&self) -> &'static str {
|
||||
"VCALENDAR"
|
||||
}
|
||||
|
||||
fn match_time_range(&self, _time_range: &TimeRangeElement) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn match_prop_filter(&self, _prop_filter: &PropFilterElement) -> bool {
|
||||
// TODO
|
||||
true
|
||||
}
|
||||
|
||||
fn match_subcomponents(&self, comp_filter: &CompFilterElement) -> bool {
|
||||
self.get_data().matches(comp_filter)
|
||||
}
|
||||
}
|
||||
|
||||
impl CompFilterable for CalendarObjectComponent {
|
||||
fn get_comp_name(&self) -> &'static str {
|
||||
CalendarObjectType::from(self).as_str()
|
||||
}
|
||||
|
||||
fn match_time_range(&self, time_range: &TimeRangeElement) -> bool {
|
||||
// TODO
|
||||
true
|
||||
}
|
||||
|
||||
fn match_prop_filter(&self, _prop_filter: &PropFilterElement) -> bool {
|
||||
// TODO
|
||||
true
|
||||
}
|
||||
|
||||
fn match_subcomponents(&self, _comp_filter: &CompFilterElement) -> bool {
|
||||
// TODO: Properly check subcomponents
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ use rustical_store::CalendarStore;
|
||||
|
||||
mod elements;
|
||||
pub(crate) use elements::*;
|
||||
mod comp_filter;
|
||||
|
||||
pub async fn get_objects_calendar_query<C: CalendarStore>(
|
||||
cal_query: &CalendarQueryRequest,
|
||||
|
||||
@@ -11,7 +11,7 @@ use rustical_ical::CalendarObject;
|
||||
use rustical_store::CalendarStore;
|
||||
use rustical_store::auth::Principal;
|
||||
use std::str::FromStr;
|
||||
use tracing::{debug, instrument};
|
||||
use tracing::{debug, error, instrument};
|
||||
|
||||
#[instrument(skip(cal_store))]
|
||||
pub async fn get_event<C: CalendarStore>(
|
||||
@@ -85,7 +85,14 @@ pub async fn put_event<C: CalendarStore>(
|
||||
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
|
||||
.put_object(principal, calendar_id, object, overwrite)
|
||||
.await?;
|
||||
|
||||
@@ -12,6 +12,8 @@ pub enum Precondition {
|
||||
#[error("valid-calendar-data")]
|
||||
#[xml(ns = "rustical_dav::namespace::NS_CALDAV")]
|
||||
ValidCalendarData,
|
||||
#[error("matching-uid")]
|
||||
MatchingUid,
|
||||
}
|
||||
|
||||
impl IntoResponse for Precondition {
|
||||
@@ -83,6 +85,12 @@ impl Error {
|
||||
|
||||
impl IntoResponse for Error {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use axum::body::Body;
|
||||
use http::StatusCode;
|
||||
use rustical_xml::XmlError;
|
||||
use thiserror::Error;
|
||||
@@ -59,7 +60,12 @@ impl Error {
|
||||
|
||||
impl axum::response::IntoResponse for Error {
|
||||
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());
|
||||
if matches!(&self, &Error::Unauthorized) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use axum::response::IntoResponse;
|
||||
use http::StatusCode;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
@@ -43,6 +44,14 @@ impl Error {
|
||||
|
||||
impl IntoResponse for Error {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user