Implement data model changes to support new WebDAV Push spec

This commit is contained in:
Lennart
2025-05-03 15:24:00 +02:00
parent f50ef8a1d5
commit d1f249a01b
17 changed files with 605 additions and 152 deletions

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "INSERT OR REPLACE INTO davpush_subscriptions (id, topic, expiration, push_resource, public_key, public_key_type, auth_secret) VALUES (?, ?, ?, ?, ?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 7
},
"nullable": []
},
"hash": "6d08d3a014743da9b445ab012437ec11f81fd86d3b02fc1df07a036c6b47ace2"
}

View File

@@ -0,0 +1,56 @@
{
"db_name": "SQLite",
"query": "SELECT id, topic, expiration, push_resource, public_key, public_key_type, auth_secret\n FROM davpush_subscriptions\n WHERE (topic) = (?)",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "topic",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "expiration",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "push_resource",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "public_key",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "public_key_type",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "auth_secret",
"ordinal": 6,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "809600b79c012e77c5efabe5d355a8b188f23826a723030807dedc96fd24fdcc"
}

View File

@@ -1,38 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT id, topic, expiration, push_resource\n FROM davpush_subscriptions\n WHERE (id) = (?)",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "topic",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "expiration",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "push_resource",
"ordinal": 3,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "8159ceb84de9016e738e5fdc9a5203a4c4cbc583483241e3cdee542232c1bc35"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "INSERT OR REPLACE INTO davpush_subscriptions (id, topic, expiration, push_resource) VALUES (?, ?, ?, ?)",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "84772106cd7461119dfaf0e60908f6523860b35c06010bb0a85a531ceeeadede"
}

View File

@@ -1,38 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT id, topic, expiration, push_resource\n FROM davpush_subscriptions\n WHERE (topic) = (?)",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "topic",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "expiration",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "push_resource",
"ordinal": 3,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "851fdb63dfffde80b8793c08fa6c81ecae1d70b33dd63c8bd5b296eae330b522"
}

View File

@@ -0,0 +1,56 @@
{
"db_name": "SQLite",
"query": "SELECT id, topic, expiration, push_resource, public_key, public_key_type, auth_secret\n FROM davpush_subscriptions\n WHERE (id) = (?)",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "topic",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "expiration",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "push_resource",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "public_key",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "public_key_type",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "auth_secret",
"ordinal": 6,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "ef6cf801df2237b82b55754f1b0a5da51089810fe7a0feb0d68ea801b4e2721c"
}

430
Cargo.lock generated
View File

@@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
dependencies = [
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -199,7 +199,7 @@ dependencies = [
"actix-router",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -383,6 +383,18 @@ dependencies = [
"password-hash",
]
[[package]]
name = "arrayref"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "askama"
version = "0.13.1"
@@ -410,7 +422,7 @@ dependencies = [
"rustc-hash",
"serde",
"serde_derive",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -444,7 +456,7 @@ checksum = "34921de3d57974069bad483fdfe0ec65d88c4ff892edd1ab4d8b03be0dda1b9b"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -455,7 +467,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -509,6 +521,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.20.0"
@@ -542,6 +560,12 @@ dependencies = [
"serde",
]
[[package]]
name = "binstring"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a3c2603413428303761fae99d4b6d936404208221a44eba47d7c1e6dd03a3"
[[package]]
name = "bitflags"
version = "2.9.0"
@@ -560,6 +584,17 @@ dependencies = [
"digest",
]
[[package]]
name = "blake2b_simd"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -732,7 +767,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -741,6 +776,17 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "coarsetime"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4"
dependencies = [
"libc",
"wasix",
"wasm-bindgen",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
@@ -756,12 +802,24 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-oid"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "constant_time_eq"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
[[package]]
name = "cookie"
version = "0.16.2"
@@ -857,6 +915,12 @@ dependencies = [
"typenum",
]
[[package]]
name = "ct-codecs"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e994091bae428316ad612b1d563e7bd917141ba942963f65251bb07c0f31cc55"
[[package]]
name = "ctr"
version = "0.9.2"
@@ -890,7 +954,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -914,7 +978,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -925,7 +989,17 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
name = "der"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
dependencies = [
"const-oid 0.6.2",
"der_derive",
]
[[package]]
@@ -934,11 +1008,23 @@ version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
"const-oid",
"const-oid 0.9.6",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "der_derive"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aed3b3c608dc56cf36c45fe979d04eda51242e6703d8d0bb03426ef7c41db6a"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"synstructure 0.12.6",
]
[[package]]
name = "deranged"
version = "0.4.0"
@@ -975,7 +1061,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
"unicode-xid",
]
@@ -987,7 +1073,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
"unicode-xid",
]
@@ -998,7 +1084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"const-oid 0.9.6",
"crypto-common",
"subtle",
]
@@ -1011,7 +1097,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -1032,7 +1118,7 @@ version = "0.16.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
"der 0.7.10",
"digest",
"elliptic-curve",
"rfc6979",
@@ -1040,6 +1126,24 @@ dependencies = [
"spki",
]
[[package]]
name = "ece"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2ea1d2f2cc974957a4e2575d8e5bb494549bab66338d6320c2789abcfff5746"
dependencies = [
"base64 0.21.7",
"byteorder",
"hex",
"hkdf",
"lazy_static",
"once_cell",
"openssl",
"serde",
"sha2",
"thiserror 1.0.69",
]
[[package]]
name = "ed25519"
version = "2.2.3"
@@ -1050,6 +1154,16 @@ dependencies = [
"signature",
]
[[package]]
name = "ed25519-compact"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190"
dependencies = [
"ct-codecs",
"getrandom 0.2.15",
]
[[package]]
name = "ed25519-dalek"
version = "2.1.1"
@@ -1210,6 +1324,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"
@@ -1271,7 +1400,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -1477,6 +1606,30 @@ dependencies = [
"digest",
]
[[package]]
name = "hmac-sha1-compact"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18492c9f6f9a560e0d346369b665ad2bdbc89fa9bceca75796584e79042694c3"
[[package]]
name = "hmac-sha256"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a8575493d277c9092b988c780c94737fb9fd8651a1001e16bee3eccfc1baedb"
dependencies = [
"digest",
]
[[package]]
name = "hmac-sha512"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0b3a0f572aa8389d325f5852b9e0a333a15b0f86ecccbb3fdb6e97cd86dc67c"
dependencies = [
"digest",
]
[[package]]
name = "home"
version = "0.5.11"
@@ -1763,7 +1916,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -1892,6 +2045,46 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jwt-simple"
version = "0.12.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "731011e9647a71ff4f8474176ff6ce6e0d2de87a0173f15613af3a84c3e3401a"
dependencies = [
"anyhow",
"binstring",
"blake2b_simd",
"coarsetime",
"ct-codecs",
"ed25519-compact",
"hmac-sha1-compact",
"hmac-sha256",
"hmac-sha512",
"k256",
"p256",
"p384",
"rand 0.8.5",
"serde",
"serde_json",
"superboring",
"thiserror 2.0.12",
"zeroize",
]
[[package]]
name = "k256"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
dependencies = [
"cfg-if",
"ecdsa",
"elliptic-curve",
"once_cell",
"sha2",
"signature",
]
[[package]]
name = "language-tags"
version = "0.3.2"
@@ -2178,6 +2371,44 @@ dependencies = [
"url",
]
[[package]]
name = "openssl"
version = "0.10.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
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 2.0.100",
]
[[package]]
name = "openssl-sys"
version = "0.9.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "opentelemetry"
version = "0.29.1"
@@ -2397,7 +2628,28 @@ dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
name = "pem"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb"
dependencies = [
"base64 0.13.1",
"once_cell",
"regex",
]
[[package]]
name = "pem"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
dependencies = [
"base64 0.22.1",
"serde",
]
[[package]]
@@ -2470,7 +2722,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -2491,7 +2743,7 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"der 0.7.10",
"pkcs8",
"spki",
]
@@ -2502,7 +2754,7 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"der 0.7.10",
"spki",
]
@@ -2574,7 +2826,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
"version_check",
"yansi",
]
@@ -2599,7 +2851,7 @@ dependencies = [
"itertools 0.14.0",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -2891,7 +3143,7 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
dependencies = [
"const-oid",
"const-oid 0.9.6",
"digest",
"num-bigint-dig",
"num-integer",
@@ -2899,6 +3151,7 @@ dependencies = [
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
"sha2",
"signature",
"spki",
"subtle",
@@ -2931,7 +3184,7 @@ dependencies = [
"regex",
"relative-path",
"rustc_version",
"syn",
"syn 2.0.100",
"unicode-ident",
]
@@ -2943,7 +3196,7 @@ checksum = "b3a8fb4672e840a587a66fc577a5491375df51ddb88f2a2c2a792598c326fe14"
dependencies = [
"quote",
"rand 0.8.5",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -2976,7 +3229,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn",
"syn 2.0.100",
"walkdir",
]
@@ -3141,6 +3394,7 @@ dependencies = [
"tokio",
"tracing",
"tracing-actix-web",
"web-push",
]
[[package]]
@@ -3333,13 +3587,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
dependencies = [
"base16ct",
"der",
"der 0.7.10",
"generic-array",
"pkcs8",
"subtle",
"zeroize",
]
[[package]]
name = "sec1_decode"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6326ddc956378a0739200b2c30892dccaf198992dfd7323274690b9e188af23"
dependencies = [
"der 0.4.5",
"pem 0.8.3",
"thiserror 1.0.69",
]
[[package]]
name = "semver"
version = "1.0.26"
@@ -3373,7 +3638,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3455,7 +3720,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3564,7 +3829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
"der 0.7.10",
]
[[package]]
@@ -3626,7 +3891,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3649,7 +3914,7 @@ dependencies = [
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn",
"syn 2.0.100",
"tempfile",
"tokio",
"url",
@@ -3803,7 +4068,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3812,6 +4077,30 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "superboring"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "515cce34a781d7250b8a65706e0f2a5b99236ea605cb235d4baed6685820478f"
dependencies = [
"getrandom 0.2.15",
"hmac-sha256",
"hmac-sha512",
"rand 0.8.5",
"rsa",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.100"
@@ -3832,6 +4121,18 @@ dependencies = [
"futures-core",
]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.13.1"
@@ -3840,7 +4141,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3882,7 +4183,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3893,7 +4194,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -3989,7 +4290,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4166,7 +4467,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4400,6 +4701,15 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
[[package]]
name = "wasix"
version = "0.12.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d"
dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
@@ -4422,7 +4732,7 @@ dependencies = [
"log",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
"wasm-bindgen-shared",
]
@@ -4457,7 +4767,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -4471,6 +4781,26 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "web-push"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5c305b9ee2993ab68b7744b13ef32231d83600dd879ac8183b4c76ae31d28ac"
dependencies = [
"async-trait",
"chrono",
"ct-codecs",
"ece",
"http 0.2.12",
"jwt-simple",
"log",
"pem 3.0.5",
"sec1_decode",
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "web-sys"
version = "0.3.77"
@@ -4562,7 +4892,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4573,7 +4903,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4870,7 +5200,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4899,8 +5229,8 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
"syn 2.0.100",
"synstructure 0.13.1",
]
[[package]]
@@ -4920,7 +5250,7 @@ checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]
@@ -4940,8 +5270,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
"syn 2.0.100",
"synstructure 0.13.1",
]
[[package]]
@@ -4969,7 +5299,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.100",
]
[[package]]

View File

@@ -58,6 +58,17 @@ pub async fn route_post<C: CalendarStore, S: SubscriptionStore>(
.to_owned(),
topic: calendar_resource.cal.push_topic,
expiration: expires.naive_local(),
public_key: request
.subscription
.web_push_subscription
.subscription_public_key
.key,
public_key_type: request
.subscription
.web_push_subscription
.subscription_public_key
.ty,
auth_secret: request.subscription.web_push_subscription.auth_secret,
};
subscription_store.upsert_subscription(subscription).await?;

View File

@@ -45,6 +45,17 @@ pub async fn route_post<A: AddressbookStore, S: SubscriptionStore>(
.to_owned(),
topic: addressbook.push_topic,
expiration: expires.naive_local(),
public_key: request
.subscription
.web_push_subscription
.subscription_public_key
.key,
public_key_type: request
.subscription
.web_push_subscription
.subscription_public_key
.ty,
auth_secret: request.subscription.web_push_subscription.auth_secret,
};
subscription_store.upsert_subscription(subscription).await?;

View File

@@ -23,3 +23,4 @@ reqwest.workspace = true
tokio.workspace = true
rustical_dav.workspace = true
rustical_store.workspace = true
web-push = { version = "0.11", default-features = false }

View File

@@ -1,6 +1,6 @@
use crate::{ContentUpdate, PropertyUpdate, SupportedTriggers, Transports, Trigger};
use rustical_dav::header::Depth;
use rustical_xml::{EnumUnitVariants, EnumVariants, Unparsed, XmlDeserialize, XmlSerialize};
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
#[xml(unit_variants_ident = "DavPushExtensionPropName")]

View File

@@ -1,10 +1,15 @@
use actix_web::http::StatusCode;
use reqwest::{
Method, Request,
header::{self, HeaderName, HeaderValue},
};
use rustical_dav::xml::multistatus::PropstatElement;
use rustical_store::{CollectionOperation, CollectionOperationType, SubscriptionStore};
use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot};
use std::sync::Arc;
use std::{str::FromStr, sync::Arc};
use tokio::sync::mpsc::Receiver;
use tracing::{error, info, warn};
use web_push::{SubscriptionInfo, WebPushMessage, WebPushMessageBuilder};
#[derive(XmlSerialize, Debug)]
struct PushMessageProp {
@@ -25,6 +30,40 @@ struct PushMessage {
propstat: PropstatElement<PushMessageProp>,
}
pub fn build_request(message: WebPushMessage) -> Request {
// A little janky :)
let url = reqwest::Url::from_str(&message.endpoint.to_string()).unwrap();
let mut builder = Request::new(Method::POST, url);
if let Some(topic) = message.topic {
builder
.headers_mut()
.insert("Topic", HeaderValue::from_str(topic.as_str()).unwrap());
}
if let Some(payload) = message.payload {
builder.headers_mut().insert(
header::CONTENT_ENCODING,
HeaderValue::from_static(payload.content_encoding.to_str()),
);
builder.headers_mut().insert(
header::CONTENT_TYPE,
HeaderValue::from_static("application/octet-stream"),
);
for (k, v) in payload.crypto_headers.into_iter() {
let v: &str = v.as_ref();
builder.headers_mut().insert(
HeaderName::from_static(k),
HeaderValue::from_str(&v).unwrap(),
);
}
*builder.body_mut() = Some(reqwest::Body::from(payload.content));
}
builder
}
pub async fn push_notifier(
allowed_push_servers: Option<Vec<String>>,
mut recv: Receiver<CollectionOperation>,
@@ -65,6 +104,19 @@ pub async fn push_notifier(
let payload = String::from_utf8(output).unwrap();
for subscriber in subscribers {
let push_resource = subscriber.push_resource;
let sub_info = SubscriptionInfo {
endpoint: push_resource.to_owned(),
keys: web_push::SubscriptionKeys {
p256dh: subscriber.public_key,
auth: subscriber.auth_secret,
},
};
let mut builder = WebPushMessageBuilder::new(&sub_info);
builder.set_payload(web_push::ContentEncoding::Aes128Gcm, payload.as_bytes());
let push_message = builder.build().unwrap();
let request = build_request(push_message);
let allowed = if let Some(allowed_push_servers) = &allowed_push_servers {
if let Ok(resource_url) = reqwest::Url::parse(&push_resource) {
let origin = resource_url.origin().ascii_serialization();
@@ -81,12 +133,7 @@ pub async fn push_notifier(
if allowed {
info!("Sending a push message to {}: {}", push_resource, payload);
if let Err(err) = client
.post(push_resource)
.body(payload.to_owned())
.send()
.await
{
if let Err(err) = client.execute(request).await {
error!("{err}");
}
} else {

View File

@@ -18,9 +18,9 @@ pub struct WebPushSubscription {
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
pub struct SubscriptionPublicKey {
#[xml(ty = "attr", rename = b"type")]
ty: String,
pub ty: String,
#[xml(ty = "text")]
key: String,
pub key: String,
}
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]

View File

@@ -7,6 +7,9 @@ pub struct Subscription {
pub topic: String,
pub expiration: NaiveDateTime,
pub push_resource: String,
pub public_key: String,
pub public_key_type: String,
pub auth_secret: String,
}
#[async_trait]

View File

@@ -0,0 +1,4 @@
ALTER TABLE davpush_subscriptions
DROP public_key,
DROP public_key_type,
DROP auth_secret;

View File

@@ -0,0 +1,7 @@
-- Old subscriptions are useless anyway
DELETE FROM davpush_subscriptions;
-- Now the new columns can also be set NOT NULL
ALTER TABLE davpush_subscriptions ADD public_key TEXT NOT NULL;
ALTER TABLE davpush_subscriptions ADD public_key_type TEXT NOT NULL;
ALTER TABLE davpush_subscriptions ADD auth_secret TEXT NOT NULL;

View File

@@ -7,7 +7,7 @@ impl SubscriptionStore for SqliteStore {
async fn get_subscriptions(&self, topic: &str) -> Result<Vec<Subscription>, Error> {
Ok(sqlx::query_as!(
Subscription,
r#"SELECT id, topic, expiration, push_resource
r#"SELECT id, topic, expiration, push_resource, public_key, public_key_type, auth_secret
FROM davpush_subscriptions
WHERE (topic) = (?)"#,
topic
@@ -20,7 +20,7 @@ impl SubscriptionStore for SqliteStore {
async fn get_subscription(&self, id: &str) -> Result<Subscription, Error> {
Ok(sqlx::query_as!(
Subscription,
r#"SELECT id, topic, expiration, push_resource
r#"SELECT id, topic, expiration, push_resource, public_key, public_key_type, auth_secret
FROM davpush_subscriptions
WHERE (id) = (?)"#,
id
@@ -32,11 +32,14 @@ impl SubscriptionStore for SqliteStore {
async fn upsert_subscription(&self, sub: Subscription) -> Result<bool, Error> {
sqlx::query!(
r#"INSERT OR REPLACE INTO davpush_subscriptions (id, topic, expiration, push_resource) VALUES (?, ?, ?, ?)"#,
r#"INSERT OR REPLACE INTO davpush_subscriptions (id, topic, expiration, push_resource, public_key, public_key_type, auth_secret) VALUES (?, ?, ?, ?, ?, ?, ?)"#,
sub.id,
sub.topic,
sub.expiration,
sub.push_resource
sub.push_resource,
sub.public_key,
sub.public_key_type,
sub.auth_secret
).execute(&self.db).await.map_err(crate::Error::from)?;
// TODO: Correctly return whether a subscription already existed
Ok(false)