mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 13:32:16 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0415664ff3 | ||
|
|
677e0082fa | ||
|
|
a387885b0a | ||
|
|
990b953055 | ||
|
|
36b47a645d |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id, vcf FROM addressobjects WHERE (principal, addressbook_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) or ?)",
|
||||
"query": "SELECT id, vcf FROM addressobjects WHERE (principal, addressbook_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -22,5 +22,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "395e40a7b3333b79bc2ad50a123d99f74bc2712a16257ee2119dd211fdb61f7e"
|
||||
"hash": "246ec675667992c1297c29348d46496a884c59adb8b64b569d36f4ce10f88f47"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?)",
|
||||
"query": "SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -15,12 +15,12 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "d2f7423e2e8f97607f6664200990dcadb927445880ec6edffba3b5aedf4e199b"
|
||||
"hash": "543838c030550cb09d1af08adfeade8b7ce3575d92fddbc6e9582d141bc9e49d"
|
||||
}
|
||||
90
Cargo.lock
generated
90
Cargo.lock
generated
@@ -768,7 +768,11 @@ dependencies = [
|
||||
"base64 0.21.7",
|
||||
"byteorder",
|
||||
"hex",
|
||||
"hkdf",
|
||||
"lazy_static",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
"sha2",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
@@ -916,6 +920,21 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
@@ -1834,6 +1853,54 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.5.0+3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.30.0"
|
||||
@@ -2669,7 +2736,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -2712,7 +2779,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_caldav"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -2747,7 +2814,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_carddav"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -2779,7 +2846,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -2804,7 +2871,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav_push"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -2815,6 +2882,7 @@ dependencies = [
|
||||
"http",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
"openssl",
|
||||
"p256",
|
||||
"quick-xml",
|
||||
"rand 0.9.1",
|
||||
@@ -2830,7 +2898,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_frontend"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"askama_web",
|
||||
@@ -2863,7 +2931,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_ical"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"chrono",
|
||||
@@ -2881,7 +2949,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_oidc"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -2896,7 +2964,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -2930,7 +2998,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store_sqlite"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
@@ -2950,7 +3018,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_xml"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"quick-xml",
|
||||
"thiserror 2.0.12",
|
||||
|
||||
@@ -135,7 +135,10 @@ reqwest = { version = "0.12", features = [
|
||||
openidconnect = "4.0"
|
||||
clap = { version = "4.5", features = ["derive", "env"] }
|
||||
matchit-serde = { git = "https://github.com/lennart-k/matchit-serde", rev = "f0591d13" }
|
||||
ece = { version = "2.3", default-features = false }
|
||||
ece = { version = "2.3", default-features = false, features = [
|
||||
"backend-openssl",
|
||||
] }
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
p256 = { version = "0.13", features = ["ecdh"] }
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN case $TARGETPLATFORM in \
|
||||
*) echo "Unsupported platform ${TARGETPLATFORM}"; exit 1;; \
|
||||
esac
|
||||
|
||||
RUN apk add --no-cache musl-dev llvm19 clang \
|
||||
RUN apk add --no-cache musl-dev llvm19 clang perl pkgconf make \
|
||||
&& rustup target add "$(cat /tmp/rust_target)" \
|
||||
&& cargo install cargo-chef --locked \
|
||||
&& rm -rf "$CARGO_HOME/registry"
|
||||
|
||||
@@ -29,7 +29,7 @@ pub async fn get_objects_calendar_multiget<C: CalendarStore>(
|
||||
if let Some(filename) = href.strip_prefix(path) {
|
||||
let filename = filename.trim_start_matches("/");
|
||||
if let Some(object_id) = filename.strip_suffix(".ics") {
|
||||
match store.get_object(principal, cal_id, object_id).await {
|
||||
match store.get_object(principal, cal_id, object_id, false).await {
|
||||
Ok(object) => result.push(object),
|
||||
Err(rustical_store::Error::NotFound) => not_found.push(href.to_owned()),
|
||||
Err(err) => return Err(err.into()),
|
||||
|
||||
@@ -33,7 +33,7 @@ pub async fn get_event<C: CalendarStore>(
|
||||
}
|
||||
|
||||
let event = cal_store
|
||||
.get_object(&principal, &calendar_id, &object_id)
|
||||
.get_object(&principal, &calendar_id, &object_id, false)
|
||||
.await?;
|
||||
|
||||
let mut resp = Response::builder().status(StatusCode::OK);
|
||||
|
||||
@@ -61,7 +61,7 @@ impl<C: CalendarStore> ResourceService for CalendarObjectResourceService<C> {
|
||||
) -> Result<Self::Resource, Self::Error> {
|
||||
let object = self
|
||||
.cal_store
|
||||
.get_object(principal, calendar_id, object_id)
|
||||
.get_object(principal, calendar_id, object_id, false)
|
||||
.await?;
|
||||
Ok(CalendarObjectResource {
|
||||
object,
|
||||
|
||||
@@ -38,10 +38,10 @@ impl Resource for PrincipalResource {
|
||||
ResourcetypeInner(Some(rustical_dav::namespace::NS_DAV), "collection"),
|
||||
ResourcetypeInner(Some(rustical_dav::namespace::NS_DAV), "principal"),
|
||||
// https://github.com/apple/ccs-calendarserver/blob/13c706b985fb728b9aab42dc0fef85aae21921c3/doc/Extensions/caldav-proxy.txt
|
||||
ResourcetypeInner(
|
||||
Some(rustical_dav::namespace::NS_CALENDARSERVER),
|
||||
"calendar-proxy-write",
|
||||
),
|
||||
// ResourcetypeInner(
|
||||
// Some(rustical_dav::namespace::NS_CALENDARSERVER),
|
||||
// "calendar-proxy-write",
|
||||
// ),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::xml::TagList;
|
||||
use headers::{CacheControl, ContentType, HeaderMapExt};
|
||||
use http::StatusCode;
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot};
|
||||
@@ -109,7 +110,6 @@ impl<T1: XmlSerialize, T2: XmlSerialize> axum::response::IntoResponse
|
||||
{
|
||||
fn into_response(self) -> axum::response::Response {
|
||||
use axum::body::Body;
|
||||
use http::header;
|
||||
|
||||
let mut output: Vec<_> = b"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".into();
|
||||
let mut writer = quick_xml::Writer::new_with_indent(&mut output, b' ', 4);
|
||||
@@ -118,9 +118,9 @@ impl<T1: XmlSerialize, T2: XmlSerialize> axum::response::IntoResponse
|
||||
}
|
||||
|
||||
let mut resp = axum::response::Response::builder().status(StatusCode::MULTI_STATUS);
|
||||
resp.headers_mut()
|
||||
.unwrap()
|
||||
.insert(header::CONTENT_TYPE, "application/xml".try_into().unwrap());
|
||||
let hdrs = resp.headers_mut().unwrap();
|
||||
hdrs.typed_insert(ContentType::xml());
|
||||
hdrs.typed_insert(CacheControl::new().with_no_cache());
|
||||
resp.body(Body::from(output)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,3 +28,4 @@ p256.workspace = true
|
||||
rand.workspace = true
|
||||
ece.workspace = true
|
||||
axum.workspace = true
|
||||
openssl.workspace = true
|
||||
|
||||
@@ -58,6 +58,7 @@ pub trait CalendarStore: Send + Sync + 'static {
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
object_id: &str,
|
||||
show_deleted: bool,
|
||||
) -> Result<CalendarObject, Error>;
|
||||
async fn put_object(
|
||||
&self,
|
||||
|
||||
@@ -80,11 +80,13 @@ impl<CS: CalendarStore, BS: CalendarStore> CalendarStore for CombinedCalendarSto
|
||||
use_trashbin: bool,
|
||||
) -> Result<(), Error> {
|
||||
if cal_id.starts_with(BIRTHDAYS_PREFIX) {
|
||||
Err(Error::ReadOnly)
|
||||
} else {
|
||||
self.birthday_store
|
||||
.delete_object(principal, cal_id, object_id, use_trashbin)
|
||||
.await
|
||||
} else {
|
||||
self.cal_store
|
||||
.delete_object(principal, cal_id, object_id, use_trashbin)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,14 +96,15 @@ impl<CS: CalendarStore, BS: CalendarStore> CalendarStore for CombinedCalendarSto
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
object_id: &str,
|
||||
show_deleted: bool,
|
||||
) -> Result<CalendarObject, Error> {
|
||||
if cal_id.starts_with(BIRTHDAYS_PREFIX) {
|
||||
self.birthday_store
|
||||
.get_object(principal, cal_id, object_id)
|
||||
.get_object(principal, cal_id, object_id, show_deleted)
|
||||
.await
|
||||
} else {
|
||||
self.cal_store
|
||||
.get_object(principal, cal_id, object_id)
|
||||
.get_object(principal, cal_id, object_id, show_deleted)
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -237,4 +240,3 @@ impl<CS: CalendarStore, BS: CalendarStore> CalendarStore for CombinedCalendarSto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,13 +126,14 @@ impl<AS: AddressbookStore> CalendarStore for ContactBirthdayStore<AS> {
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
object_id: &str,
|
||||
show_deleted: bool,
|
||||
) -> Result<CalendarObject, Error> {
|
||||
let cal_id = cal_id
|
||||
.strip_prefix(BIRTHDAYS_PREFIX)
|
||||
.ok_or(Error::NotFound)?;
|
||||
let (addressobject_id, date_type) = object_id.rsplit_once("-").ok_or(Error::NotFound)?;
|
||||
self.0
|
||||
.get_object(principal, cal_id, addressobject_id, false)
|
||||
.get_object(principal, cal_id, addressobject_id, show_deleted)
|
||||
.await?
|
||||
.get_significant_dates()?
|
||||
.remove(date_type)
|
||||
|
||||
@@ -250,7 +250,7 @@ impl SqliteAddressbookStore {
|
||||
) -> Result<AddressObject, rustical_store::Error> {
|
||||
Ok(sqlx::query_as!(
|
||||
AddressObjectRow,
|
||||
"SELECT id, vcf FROM addressobjects WHERE (principal, addressbook_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) or ?)",
|
||||
"SELECT id, vcf FROM addressobjects WHERE (principal, addressbook_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
|
||||
principal,
|
||||
addressbook_id,
|
||||
object_id,
|
||||
|
||||
@@ -296,13 +296,15 @@ impl SqliteCalendarStore {
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
object_id: &str,
|
||||
show_deleted: bool,
|
||||
) -> Result<CalendarObject, Error> {
|
||||
sqlx::query_as!(
|
||||
CalendarObjectRow,
|
||||
"SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?)",
|
||||
"SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
|
||||
principal,
|
||||
cal_id,
|
||||
object_id
|
||||
object_id,
|
||||
show_deleted
|
||||
)
|
||||
.fetch_one(executor)
|
||||
.await
|
||||
@@ -454,7 +456,7 @@ impl SqliteCalendarStore {
|
||||
.unwrap_or(0);
|
||||
|
||||
for Row { object_id, .. } in changes {
|
||||
match Self::_get_object(&mut *conn, principal, cal_id, &object_id).await {
|
||||
match Self::_get_object(&mut *conn, principal, cal_id, &object_id, false).await {
|
||||
Ok(object) => objects.push(object),
|
||||
Err(rustical_store::Error::NotFound) => deleted_objects.push(object_id),
|
||||
Err(err) => return Err(err),
|
||||
@@ -557,8 +559,9 @@ impl CalendarStore for SqliteCalendarStore {
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
object_id: &str,
|
||||
show_deleted: bool,
|
||||
) -> Result<CalendarObject, Error> {
|
||||
Self::_get_object(&self.db, principal, cal_id, object_id).await
|
||||
Self::_get_object(&self.db, principal, cal_id, object_id, show_deleted).await
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
|
||||
Reference in New Issue
Block a user