Compare commits

..

8 commits

Author SHA1 Message Date
0795d6fa4e Merge pull request 'Add template field to Link because ostatus subscribe schema needs it.' (#4) from template_link_type into master
All checks were successful
/ docker build (push) Successful in 1m46s
/ cargo test (push) Successful in 22s
Reviewed-on: #4
2024-05-07 18:06:20 +02:00
efc7b83930 Add template field to Link because ostatus subscribe schema needs it.
All checks were successful
/ cargo test (push) Successful in 20s
Also fixes a bug where Resource::compress lost every link and adds a lot more tests around that functionality.
2024-05-07 18:04:43 +02:00
8eafcf86b9 Server only docker image, but the action's documentation is apparently wrong.
All checks were successful
/ docker build (push) Successful in 1m22s
/ cargo test (push) Successful in 19s
2024-04-01 16:55:07 +02:00
6cd503711f Server only docker image
All checks were successful
/ cargo test (push) Successful in 20s
2024-04-01 16:53:23 +02:00
a38ab85320 Bump version and update dependencies
All checks were successful
/ docker build (push) Successful in 1m19s
/ cargo test (push) Successful in 20s
2024-04-01 16:31:08 +02:00
12cb4fc254 Add more testing around case-insensitivity and patch an error in merge_records creating duplicates in the database 2024-04-01 16:30:37 +02:00
92c3239c00 Merge pull request 'Slim down tokio features' (#2) from leaner-tokio into master
All checks were successful
/ docker build (push) Successful in 1m14s
/ cargo test (push) Successful in 24s
Reviewed-on: #2
2024-03-18 02:13:02 +01:00
3dbe0eb589 Slim down tokio features
All checks were successful
/ cargo test (push) Successful in 22s
2024-03-18 02:11:01 +01:00
7 changed files with 340 additions and 294 deletions

View file

@ -20,3 +20,8 @@ jobs:
push: true
tags: karcsesz/fingerlink:latest-nano
build-args: "editor=nano"
- uses: docker/build-push-action@v5
with:
push: true
tags: karcsesz/fingerlink:latest-server
file: Dockerfile.serveonly

369
Cargo.lock generated
View file

@ -113,18 +113,18 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e"
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
dependencies = [
"async-trait",
"axum-core",
"bytes",
"futures-util",
"http 1.0.0",
"http-body 1.0.0",
"http",
"http-body",
"http-body-util",
"hyper 1.1.0",
"hyper",
"hyper-util",
"itoa",
"matchit",
@ -137,7 +137,7 @@ dependencies = [
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.0",
"tokio",
"tower",
"tower-layer",
@ -154,13 +154,13 @@ dependencies = [
"async-trait",
"bytes",
"futures-util",
"http 1.0.0",
"http-body 1.0.0",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper",
"sync_wrapper 0.1.2",
"tower-layer",
"tower-service",
"tracing",
@ -187,12 +187,6 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.2"
@ -255,9 +249,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "clap"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
@ -277,9 +271,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck",
"proc-macro2",
@ -299,22 +293,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -330,21 +308,6 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "encoding_rs"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.8"
@ -363,7 +326,7 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "fingerlink"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"axum",
"clap",
@ -413,6 +376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -447,6 +411,7 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
@ -471,50 +436,6 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "h2"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.11",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "h2"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 1.0.0",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
version = "0.5.0"
@ -536,17 +457,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "http"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http"
version = "1.0.0"
@ -558,17 +468,6 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.11",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
@ -576,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.0.0",
"http",
]
[[package]]
@ -587,8 +486,8 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840"
dependencies = [
"bytes",
"futures-util",
"http 1.0.0",
"http-body 1.0.0",
"http",
"http-body",
"pin-project-lite",
]
@ -604,30 +503,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.24",
"http 0.2.11",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.1.0"
@ -637,28 +512,31 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.2",
"http 1.0.0",
"http-body 1.0.0",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
dependencies = [
"futures-util",
"http 0.2.11",
"hyper 0.14.28",
"http",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
@ -668,13 +546,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.0.0",
"http-body 1.0.0",
"hyper 1.1.0",
"http",
"http-body",
"hyper",
"pin-project-lite",
"socket2",
"tokio",
"tower",
"tower-service",
"tracing",
]
[[package]]
@ -687,16 +569,6 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "indexmap"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "ipnet"
version = "2.9.0"
@ -736,16 +608,6 @@ version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
@ -796,7 +658,7 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags 2.4.2",
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
@ -843,29 +705,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.48.5",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -928,32 +767,24 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "reqwest"
version = "0.11.26"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2"
checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338"
dependencies = [
"async-compression",
"base64",
"bytes",
"encoding_rs",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.24",
"http 0.2.11",
"http-body 0.4.6",
"hyper 0.14.28",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
"js-sys",
"log",
@ -963,11 +794,11 @@ dependencies = [
"pin-project-lite",
"rustls",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"sync_wrapper 0.1.2",
"tokio",
"tokio-rustls",
"tokio-util",
@ -1006,7 +837,7 @@ version = "0.38.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
dependencies = [
"bitflags 2.4.2",
"bitflags",
"errno",
"libc",
"linux-raw-sys",
@ -1015,14 +846,16 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.10"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki",
"sct",
"subtle",
"zeroize",
]
[[package]]
@ -1035,12 +868,19 @@ dependencies = [
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
name = "rustls-pki-types"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247"
[[package]]
name = "rustls-webpki"
version = "0.102.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
@ -1056,22 +896,6 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "serde"
version = "1.0.197"
@ -1094,9 +918,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.114"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
dependencies = [
"itoa",
"ryu",
@ -1180,6 +1004,12 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "2.0.48"
@ -1198,25 +1028,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "system-configuration"
version = "0.5.1"
name = "sync_wrapper"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
checksum = "384595c11a4e2969895cad5a8c4029115f5ab956a9e5ef4de79d11a426e5f20c"
[[package]]
name = "tempfile"
@ -1277,16 +1092,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.36.0"
version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
@ -1307,11 +1121,12 @@ dependencies = [
[[package]]
name = "tokio-rustls"
version = "0.24.1"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
"rustls",
"rustls-pki-types",
"tokio",
]
@ -1570,21 +1385,23 @@ dependencies = [
[[package]]
name = "webpki-roots"
version = "0.25.4"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "which"
version = "6.0.0"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
"windows-sys 0.52.0",
"winsafe",
]
[[package]]
@ -1750,3 +1567,15 @@ dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "winsafe"
version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
name = "zeroize"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View file

@ -1,6 +1,6 @@
[package]
name = "fingerlink"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -12,18 +12,18 @@ editor = ["reqwest", "tempfile", "which", "nix"]
[dependencies]
qpidfile = { version = "0.9.2", optional = true }
tokio = { version = "1.36.0", features = ["full"], optional = true }
tokio = { version = "1.37.0", features = ["rt-multi-thread", "signal"], optional = true }
# dashmap = { version = "5.5.3", features = ["inline"]}
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
serde_json = "1.0.115"
thiserror = "1.0.58"
clap = { version = "4.5.3", features = ["derive"]}
axum = { version = "0.7.4", optional = true }
reqwest = { version = "0.11.26", optional = true, default-features = false, features = ["rustls-tls", "blocking", "json", "gzip", "brotli", "deflate"] }
clap = { version = "4.5.4", features = ["derive"] }
axum = { version = "0.7.5", optional = true }
reqwest = { version = "0.12.2", optional = true, default-features = false, features = ["rustls-tls", "blocking", "json", "gzip", "brotli", "deflate"] }
tempfile = { version = "3.10.1", optional = true }
which = { version = "6.0.0", optional = true }
which = { version = "6.0.1", optional = true }
nix = { version = "0.28.0", optional = true, default-features = false, features = ["signal"] }
urlencoding = { version = "2.1.3"}

24
Dockerfile.serveonly Normal file
View file

@ -0,0 +1,24 @@
FROM rust:latest as builder
LABEL authors="karcsesz"
ARG target=x86_64-unknown-linux-musl
RUN apt update && apt install -y musl-tools musl-dev
RUN update-ca-certificates
RUN rustup target add $target
WORKDIR /fingerlink
COPY . .
RUN cargo build --target $target --release --no-default-features --features server
FROM scratch
ENV PATH="${PATH}:/fingerlink"
WORKDIR /fingerlink
COPY --from=builder /fingerlink/target/x86_64-unknown-linux-musl/release/fingerlink /fingerlink/fingerlink
ENTRYPOINT ["/fingerlink/fingerlink", "serve"]
CMD ["--help"]

View file

@ -46,7 +46,6 @@ impl LookupHandler {
let mut lookup = HashMap::new();
for (index, resource) in resources.0.iter().enumerate() {
for lookup_to_add in resource.keys() {
let lookup_to_add = lookup_to_add.to_lowercase();
debug!("Adding {lookup_to_add} for {}", resource.subject);
let duplicate = lookup.insert(lookup_to_add.clone(), index);
@ -162,6 +161,23 @@ mod tests {
}
}
#[test]
fn successful_case_insensitive_query() {
let data = "[{\"subject\":\"testing\"},{\"subject\":\"more_testing\"}]".as_bytes();
let data = LookupHandler::load_from_reader(data).unwrap();
for subject in ["TESTING", "mOre_testiNg"] {
assert_eq!(
data.lookup(subject),
Some(&Resource {
subject: subject.to_lowercase(),
aliases: None,
properties: None,
links: None,
})
);
}
}
#[test]
fn successful_alias_query() {
let data = "[{\"subject\":\"testing\",\"aliases\":[\"alias1\",\"alias2\"]},{\"subject\":\"red herring\",\"aliases\":[\"alias\",\"1\", \"2\"]}]".as_bytes();
@ -178,4 +194,21 @@ mod tests {
);
}
}
#[test]
fn successful_case_insensitive_alias_query() {
let data = "[{\"subject\":\"testing\",\"aliases\":[\"alias1\",\"alias2\"]},{\"subject\":\"red herring\",\"aliases\":[\"alias\",\"1\", \"2\"]}]".as_bytes();
let data = LookupHandler::load_from_reader(data).unwrap();
for subject in ["aliAS1", "aLiAs2"] {
assert_eq!(
data.lookup(subject),
Some(&Resource {
subject: "testing".to_string(),
aliases: Some(vec!["alias1".to_string(), "alias2".to_string()]),
properties: None,
links: None,
})
);
}
}
}

View file

@ -39,16 +39,16 @@ impl Resource {
}
}
/// Returns the aliases of the given record. If the `aliases` field is
/// Returns the aliases of the given record, converted to lowercase. If the `aliases` field is
/// entirely missing, returns an empty array.
pub fn keys(&self) -> impl Iterator<Item = &String> {
pub fn keys(&self) -> impl Iterator<Item=String> + '_ {
let aliases = if let Some(aliases) = &self.aliases {
aliases.as_slice()
} else {
&[]
};
aliases.iter().chain(std::iter::once(&self.subject))
aliases.iter().chain(std::iter::once(&self.subject)).map(|key| key.to_lowercase())
}
/// Replaces the current `subject` field of the WebFinger resource
@ -114,6 +114,7 @@ impl Resource {
.map(clone_hashmap_with_option_value_as_complete)
.unwrap_or_default(),
),
template: Some(link.template.clone().unwrap_or_default()),
}
}))
})
@ -146,6 +147,36 @@ impl Resource {
.links
.filter(|links| !links.is_empty())
.map(|mut links| {
// Collapse default subvalues
for link in &mut links {
if link.media_type.as_ref().map_or(false, String::is_empty) {
link.media_type = None;
}
if link.href.as_ref().map_or(false, String::is_empty) {
link.href = None;
}
if let Some(titles) = &mut link.titles {
titles.retain(|key, value| !key.is_empty() || !value.is_empty())
}
if link.titles.as_ref().map_or(false, HashMap::is_empty) {
link.titles = None;
}
if let Some(properties) = &mut link.properties {
for value in properties.values_mut() {
if value.as_ref().map_or(false, String::is_empty) {
*value = None;
}
}
properties.retain(|key, value| !key.is_empty() || !value.is_none())
}
if link.properties.as_ref().map_or(false, HashMap::is_empty) {
link.properties = None;
}
if link.template.as_ref().map_or(false, String::is_empty) {
link.template = None;
}
}
// Delete completely default links
links.retain(|link| {
// Empty `rel` is invalid, but short-circuiting here would delete records
// that are only partially edited. Better to store invalid data than to delete
@ -153,22 +184,19 @@ impl Resource {
let mut is_default = link.rel.is_empty();
is_default &= link
.media_type
.as_ref()
.filter(|media_type| !media_type.is_empty())
.is_none();
is_default &= link.href.as_ref().filter(|href| !href.is_empty()).is_none();
is_default &= link
.titles
.as_ref()
.filter(|titles| !titles.is_empty())
.is_none();
is_default &= link
.properties
.as_ref()
.filter(|titles| !titles.is_empty())
.is_none();
is_default &= link
.template
.is_none();
is_default
!is_default
});
links
@ -189,12 +217,15 @@ pub struct Link {
pub titles: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<HashMap<String, Option<String>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub template: Option<String>,
}
#[cfg(test)]
/// Functions to generate data for testing functions that manipulate `Resource` structs
pub mod test_data {
use crate::schema::resource::Resource;
use std::collections::HashMap;
use crate::schema::resource::{Link, Resource};
/// A [`Resource`] with only the `subject` field set
pub fn barebones_user() -> Resource {
@ -220,6 +251,100 @@ pub mod test_data {
links: None,
}
}
pub fn example_mastodon_user() -> Resource {
Resource {
subject: "acct:user@example.com".to_string(),
aliases: Some(vec![
"https://example.com/@user".to_string(),
"https://example.com/users/user".to_string()
]),
properties: None,
links: Some(vec![
Link {
rel: "http://webfinger.net/rel/profile-page".to_string(),
media_type: Some("text/html".to_string()),
href: Some("https://example.com/@user".to_string()),
titles: None,
properties: None,
template: None,
},
Link {
rel: "self".to_string(),
media_type: Some("application/activity+json".to_string()),
href: Some("https://example.com/users/user".to_string()),
titles: None,
properties: None,
template: None,
},
Link {
rel: "http://ostatus.org/schema/1.0/subscribe".to_string(),
media_type: None,
href: None,
titles: None,
properties: None,
template: Some("https://example.com/authorize_interaction?uri={uri}".to_string()),
},
Link {
rel: "http://webfinger.net/rel/avatar".to_string(),
media_type: Some("image/png".to_string()),
href: Some("https://example.com/system/accounts/avatars/321/423/112/234/123/527/original/1j2ioff88a9wa.png".to_string()),
titles: None,
properties: None,
template: None,
}
]),
}
}
pub fn example_firefish_user() -> Resource {
Resource {
subject: "acct:user@example.com".to_string(),
aliases: None,
properties: None,
links: Some(vec![
Link {
rel: "self".to_string(),
media_type: Some("application/activity+json".to_string()),
href: Some("https://example.com/users/8fsua89lcieaj".to_string()),
titles: None,
properties: None,
template: None,
},
Link {
rel: "http://webfinger.net/rel/profile-page".to_string(),
media_type: Some("text/html".to_string()),
href: Some("https://example.com/@user".to_string()),
titles: None,
properties: None,
template: None,
},
Link {
rel: "http://ostatus.org/schema/1.0/subscribe".to_string(),
media_type: None,
href: None,
titles: None,
properties: None,
template: Some("https://example.com/authorize-follow?acct={uri}".to_string()),
}
])
}
}
pub fn full_resource() -> Resource {
Resource {
subject: "some_subject".to_string(),
aliases: Some(vec!["ThisIsAnAlias".to_string()]),
properties: Some(HashMap::from_iter(std::iter::once(("property_key".to_string(), Some("property_value".to_string()))))),
links: Some(vec![Link {
rel: "link_relation".to_string(),
media_type: Some("media/type".to_string()),
href: Some("https://example.com/link_href".to_string()),
titles: Some(HashMap::from_iter(std::iter::once(("title_key".to_string(), "title_value".to_string())))),
properties: Some(HashMap::from_iter(std::iter::once(("property_key".to_string(), Some("property_value".to_string()))))),
template: Some("template".to_string()),
}]),
}
}
}
#[cfg(test)]
@ -288,6 +413,9 @@ mod tests {
test_data::barebones_user(),
test_data::user_with_matching_subject_and_alias(),
test_data::user_with_single_alias(),
test_data::example_firefish_user(),
test_data::example_mastodon_user(),
test_data::full_resource(),
] {
assert_eq!(data, data.as_completely_serializable().compress());
}

View file

@ -83,10 +83,10 @@ impl ResourceList {
) -> &ResourceList {
debug!("Building hashset of already taken queries...");
let unique_check: HashSet<String> =
HashSet::from_iter(self.0.iter().flat_map(Resource::keys).cloned());
HashSet::from_iter(self.0.iter().flat_map(Resource::keys));
for record in new_records {
let record_keys = HashSet::from_iter(record.keys().cloned());
let record_keys = HashSet::from_iter(record.keys());
let collisions = unique_check
.intersection(&record_keys)
.collect::<HashSet<_>>();
@ -103,7 +103,7 @@ impl ResourceList {
CollisionHandling::OverwriteSingleSkipMultiple => {
let mut collided_resources =
self.0.iter().enumerate().filter(|record| {
record.1.keys().any(|elem| collisions.contains(elem))
record.1.keys().any(|elem| collisions.contains(&elem))
});
if let Some((collided_index, collided_resource)) = collided_resources.next()
{
@ -118,7 +118,7 @@ impl ResourceList {
CollisionHandling::OverwriteMultiple => {
warn!("Overwriting already existing record(s) with new data...");
self.0.retain(|record| {
if record.keys().any(|elem| collisions.contains(elem)) {
if record.keys().any(|elem| collisions.contains(&elem)) {
warn!("Removing {record:?}");
false
} else {
@ -138,4 +138,31 @@ impl ResourceList {
self
}
#[cfg(test)]
/// Returns the amount of records stored
fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_merge_case_insensitivity() {
let mut base = ResourceList(vec![Resource::new("ThisIsASubject".to_string())]);
base.merge_records(std::iter::once(Resource::new("thisisasubject".to_string())), CollisionHandling::Skip);
assert_eq!(base.len(), 1);
}
#[test]
fn check_merge_case_insensitivity_alt() {
let mut base = Resource::new("ThisIsASubject".to_string());
base.add_new_primary_subject("ThisIsANewPrimarySubject".to_string());
let mut base = ResourceList(vec![base]);
base.merge_records(std::iter::once(Resource::new("thisisasubject".to_string())), CollisionHandling::Skip);
assert_eq!(base.len(), 1);
}
}