diff --git a/clearing-house-app/Cargo.lock b/clearing-house-app/Cargo.lock index 575e057..ec9a1cd 100644 --- a/clearing-house-app/Cargo.lock +++ b/clearing-house-app/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "async-trait" @@ -74,7 +74,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -86,16 +86,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-write-file" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix", - "rand", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -112,10 +102,10 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.1.0", + "hyper 1.2.0", "hyper-util", "itoa", "matchit", @@ -145,7 +135,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "mime", @@ -275,9 +265,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byteorder" @@ -293,12 +283,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -308,15 +295,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -331,7 +318,7 @@ dependencies = [ "chrono", "config", "futures", - "hyper 1.1.0", + "hyper 1.2.0", "mongodb", "num-bigint", "once_cell", @@ -772,7 +759,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -843,7 +830,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -862,7 +849,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 1.0.0", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -900,9 +887,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -937,29 +924,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "hoot" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df22a4d90f1b0e65fe3e0d6ee6a4608cc4d81f4b2eb3e670f44bb6bde711e452" -dependencies = [ - "httparse", - "log", -] - -[[package]] -name = "hootbin" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "354e60868e49ea1a39c44b9562ad207c4259dc6eabf9863bf3b0f058c55cfdb2" -dependencies = [ - "fastrand", - "hoot", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "hostname" version = "0.3.1" @@ -973,9 +937,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -984,9 +948,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1000,7 +964,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.11", + "http 0.2.12", "pin-project-lite", ] @@ -1011,18 +975,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.0.0", + "http 1.1.0", ] [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", - "futures-util", - "http 1.0.0", + "futures-core", + "http 1.1.0", "http-body 1.0.0", "pin-project-lite", ] @@ -1050,13 +1014,13 @@ dependencies = [ "futures-core", "futures-util", "h2 0.3.24", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -1065,20 +1029,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" dependencies = [ "bytes", "futures-channel", "futures-util", "h2 0.4.2", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "httparse", "httpdate", "itoa", "pin-project-lite", + "smallvec", "tokio", "want", ] @@ -1104,11 +1069,11 @@ checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", - "hyper 1.1.0", + "hyper 1.2.0", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.6", "tokio", ] @@ -1164,9 +1129,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown", @@ -1178,7 +1143,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.5", + "socket2 0.5.6", "widestring", "windows-sys 0.48.0", "winreg", @@ -1207,9 +1172,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1270,9 +1235,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru-cache" @@ -1349,9 +1314,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", @@ -1426,17 +1391,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -1561,9 +1515,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.2", "cfg-if", @@ -1582,7 +1536,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1593,9 +1547,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", @@ -1605,13 +1559,13 @@ dependencies = [ [[package]] name = "os_info" -version = "3.7.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "52a07930afc1bd77ac9e1101dc18d3fc4986c6568e939c31d1c26657eb0ccbf5" dependencies = [ "log", "serde", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -1681,22 +1635,22 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1752,9 +1706,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1827,7 +1781,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -1842,9 +1796,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1865,9 +1819,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.11.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" dependencies = [ "base64 0.21.7", "bytes", @@ -1875,7 +1829,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.3.24", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "hyper-tls", @@ -1930,16 +1884,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1983,7 +1938,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.22", ] [[package]] @@ -2016,7 +1971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -2036,7 +1991,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -2048,9 +2003,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "schannel" @@ -2073,7 +2028,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -2111,9 +2066,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "semver-parser" @@ -2231,9 +2186,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -2249,20 +2204,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "indexmap", "itoa", @@ -2272,9 +2227,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -2336,7 +2291,7 @@ checksum = "b93fb4adc70021ac1b47f7d45e8cc4169baaa7ea58483bc5b721d19a26202212" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2427,12 +2382,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2473,9 +2428,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2486,9 +2441,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ "ahash", "atoi", @@ -2497,7 +2452,6 @@ dependencies = [ "chrono", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener", "futures-channel", @@ -2531,9 +2485,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" dependencies = [ "proc-macro2", "quote", @@ -2544,11 +2498,10 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" dependencies = [ - "atomic-write-file", "dotenvy", "either", "heck", @@ -2571,9 +2524,9 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", @@ -2615,9 +2568,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", @@ -2643,7 +2596,6 @@ dependencies = [ "rand", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlx-core", @@ -2656,9 +2608,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi", "chrono", @@ -2715,9 +2667,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -2765,9 +2717,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -2794,38 +2746,38 @@ dependencies = [ [[package]] name = "testcontainers-modules" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c391cd115649a8a14e5638d0606648d5348b216700a31f402987f57e58693766" +checksum = "1d0334776e1e8ee7c504a922c5236daf865ffe413aa630d84ae91dcce0b10bc3" dependencies = [ "testcontainers", ] [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -2890,7 +2842,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] @@ -2903,7 +2855,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3021,7 +2973,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3154,9 +3106,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -3187,12 +3139,11 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.5" +version = "2.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b52731d03d6bb2fd18289d4028aee361d6c28d44977846793b994b13cdcc64d" +checksum = "11f214ce18d8b2cbe84ed3aa6486ed3f5b285cf8d8fbdbce9f3f767a724adc35" dependencies = [ "base64 0.21.7", - "hootbin", "log", "native-tls", "once_cell", @@ -3260,11 +3211,17 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3272,24 +3229,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3299,9 +3256,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3309,28 +3266,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3344,9 +3301,13 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", +] [[package]] name = "widestring" @@ -3382,7 +3343,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -3400,7 +3361,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -3420,17 +3381,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -3441,9 +3402,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3453,9 +3414,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3465,9 +3426,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3477,9 +3438,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3489,9 +3450,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3501,9 +3462,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3513,9 +3474,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winreg" @@ -3553,7 +3514,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] diff --git a/clearing-house-app/Cargo.toml b/clearing-house-app/Cargo.toml index 1296be9..2ea06ca 100644 --- a/clearing-house-app/Cargo.toml +++ b/clearing-house-app/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "clearing-house-app" version = "0.10.0" +license = "Apache-2.0" +repository = "https://github.com/ids-basecamp/clearinghouse" authors = [ "Mark Gall ", "Georg Bramm ", @@ -32,7 +34,7 @@ rand = "0.8.5" # lazy initialization of static variables once_cell = "1.18.0" # Base64 encoding -base64 = "0.21.7 " +base64 = "0.21.7" # UUID generation uuid = { version = "1", features = ["serde", "v4"] } # Big integer handling (RSA key modulus and exponent) diff --git a/clearing-house-app/src/config.rs b/clearing-house-app/src/config.rs index b1bcaf8..d35d280 100644 --- a/clearing-house-app/src/config.rs +++ b/clearing-house-app/src/config.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + /// Represents the configuration for the application #[derive(Debug, serde::Deserialize)] pub(crate) struct CHConfig { @@ -33,15 +35,16 @@ impl From for tracing::Level { } } -impl ToString for LogLevel { - fn to_string(&self) -> String { - match self { +impl Display for LogLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let str = match self { LogLevel::Trace => String::from("TRACE"), LogLevel::Debug => String::from("DEBUG"), LogLevel::Info => String::from("INFO"), LogLevel::Warn => String::from("WARN"), LogLevel::Error => String::from("ERROR"), - } + }; + write!(f, "{str}") } } @@ -119,7 +122,7 @@ mod test { #[serial] fn test_read_config_from_toml() { // Create tempfile - let file = tempfile::Builder::new().suffix(".toml").tempfile().unwrap(); + let file = tempfile::Builder::new().suffix(".toml").tempfile().expect("Failure to create tempfile"); // Write config to file let toml = r#"database_url = "mongodb://localhost:27019" diff --git a/clearing-house-app/src/db/postgres_document_store.rs b/clearing-house-app/src/db/postgres_document_store.rs index 871656f..a4a6a23 100644 --- a/clearing-house-app/src/db/postgres_document_store.rs +++ b/clearing-house-app/src/db/postgres_document_store.rs @@ -25,14 +25,14 @@ impl super::DocumentStore for PostgresDocumentStore { let doc = DocumentRow::from(doc); sqlx::query( - r#"INSERT INTO documents + r"INSERT INTO documents (id, process_id, created_at, model_version, correlation_message, transfer_contract, issued, issuer_connector, content_version, recipient_connector, sender_agent, recipient_agent, payload, payload_type, message_id) VALUES ($1, (SELECT id from processes where process_id = $2), $3, $4, $5, $6, $7, $8, $9, $10, - $11, $12, $13, $14, $15)"#, + $11, $12, $13, $14, $15)", ) .bind(doc.id) // 1 .bind(doc.process_id) // 2 @@ -61,26 +61,32 @@ impl super::DocumentStore for PostgresDocumentStore { .fetch_optional(&self.db) .await .map(|r| r.is_some()) - .map_err(|e| e.into()) + .map_err(std::convert::Into::into) } async fn get_document(&self, id: &str, pid: &str) -> anyhow::Result> { sqlx::query_as::<_, DocumentRow>( - r#"SELECT documents.id, processes.process_id, documents.created_at, model_version, correlation_message, + r"SELECT documents.id, processes.process_id, documents.created_at, model_version, correlation_message, transfer_contract, issued, issuer_connector, content_version, recipient_connector, sender_agent, recipient_agent, payload, payload_type, message_id FROM documents LEFT JOIN processes ON processes.id = documents.process_id - WHERE id = $1 AND processes.process_id = $2"#, + WHERE id = $1 AND processes.process_id = $2", ) - .bind(id) - .bind(pid) - .fetch_optional(&self.db) - .await - .map(|r| r.map(DocumentRow::into)) - .map_err(|e| e.into()) + .bind(id) + .bind(pid) + .fetch_optional(&self.db) + .await + .map(|r| r.map(DocumentRow::into)) + .map_err(std::convert::Into::into) } + /// Get documents for a process + /// + /// # Lints + /// + /// Disabled `clippy::cast_possible_wrap` because cast is handled + #[allow(clippy::cast_possible_wrap)] async fn get_documents_for_pid( &self, pid: &str, @@ -96,27 +102,35 @@ impl super::DocumentStore for PostgresDocumentStore { sqlx::query_as::<_, DocumentRow>( format!( - r#"SELECT documents.id, processes.process_id, documents.created_at, model_version, correlation_message, + r"SELECT documents.id, processes.process_id, documents.created_at, model_version, correlation_message, transfer_contract, issued, issuer_connector, content_version, recipient_connector, sender_agent, recipient_agent, payload, payload_type, message_id FROM documents LEFT JOIN processes ON processes.id = documents.process_id WHERE processes.process_id = $1 AND documents.created_at BETWEEN $2 AND $3 - ORDER BY created_at {} - LIMIT $4 OFFSET $5"#, - sort_order - ) - .as_str(), + ORDER BY created_at {sort_order} + LIMIT $4 OFFSET $5") + .as_str(), ) - .bind(pid) - .bind(date_from) - .bind(date_to) - .bind(size as i64) - .bind(((page - 1) * size) as i64) - .fetch_all(&self.db) - .await - .map(|r| r.into_iter().map(DocumentRow::into).collect()) - .map_err(|e| e.into()) + .bind(pid) + .bind(date_from) + .bind(date_to) + .bind(cast_i64(size)?) + .bind(cast_i64((page - 1) * size)?) + .fetch_all(&self.db) + .await + .map(|r| r.into_iter().map(DocumentRow::into).collect()) + .map_err(std::convert::Into::into) + } +} + +/// Cast u64 to i64 with out-of-range check +fn cast_i64(value: u64) -> anyhow::Result { + if value > i64::MAX as u64 { + Err(anyhow::anyhow!("size out-of-range")) + } else { + #[allow(clippy::cast_possible_wrap)] + Ok(value as i64) } } @@ -161,29 +175,29 @@ impl From for DocumentRow { } } -impl Into for DocumentRow { - fn into(self) -> Document { +impl From for Document { + fn from(value: DocumentRow) -> Self { use chrono::TimeZone; - Document { - id: self.id, - pid: self.process_id, - ts: chrono::Local.from_utc_datetime(&self.created_at), + Self { + id: value.id, + pid: value.process_id, + ts: chrono::Local.from_utc_datetime(&value.created_at), content: crate::model::ids::message::IdsMessage { - model_version: self.model_version, - correlation_message: self.correlation_message, - transfer_contract: self.transfer_contract, - issued: self.issued.0, - issuer_connector: self.issuer_connector.0, - content_version: self.content_version, - recipient_connector: self.recipient_connector.map(|s| s.0), - sender_agent: self.sender_agent, - recipient_agent: self.recipient_agent.map(|s| s.0), - payload: self + model_version: value.model_version, + correlation_message: value.correlation_message, + transfer_contract: value.transfer_contract, + issued: value.issued.0, + issuer_connector: value.issuer_connector.0, + content_version: value.content_version, + recipient_connector: value.recipient_connector.map(|s| s.0), + sender_agent: value.sender_agent, + recipient_agent: value.recipient_agent.map(|s| s.0), + payload: value .payload .map(|s| String::from_utf8_lossy(s.as_ref()).to_string()), - payload_type: self.payload_type, - id: self.message_id, + payload_type: value.payload_type, + id: value.message_id, ..Default::default() }, } diff --git a/clearing-house-app/src/db/postgres_process_store.rs b/clearing-house-app/src/db/postgres_process_store.rs index 4ed06fc..3c3edf5 100644 --- a/clearing-house-app/src/db/postgres_process_store.rs +++ b/clearing-house-app/src/db/postgres_process_store.rs @@ -22,15 +22,15 @@ impl PostgresProcessStore { impl super::ProcessStore for PostgresProcessStore { async fn get_processes(&self) -> anyhow::Result> { sqlx::query_as::<_, ProcessRow>( - r#"SELECT p.process_id, p.created_at, ARRAY_AGG(c.client_id) AS owners FROM processes p + r"SELECT p.process_id, p.created_at, ARRAY_AGG(c.client_id) AS owners FROM processes p LEFT JOIN process_owners po ON p.id = po.process_id LEFT JOIN clients c ON po.client_id = c.id - GROUP BY p.process_id, p.created_at"#, + GROUP BY p.process_id, p.created_at", ) - .fetch_all(&self.db) - .await - .map(|r| r.into_iter().map(|p| p.into()).collect()) - .map_err(|e| e.into()) + .fetch_all(&self.db) + .await + .map(|r| r.into_iter().map(std::convert::Into::into).collect()) + .map_err(std::convert::Into::into) } async fn delete_process(&self, pid: &str) -> anyhow::Result { @@ -39,7 +39,7 @@ impl super::ProcessStore for PostgresProcessStore { .execute(&self.db) .await .map(|r| r.rows_affected() == 1) - .map_err(|e| e.into()) + .map_err(std::convert::Into::into) } async fn exists_process(&self, pid: &str) -> anyhow::Result { @@ -48,22 +48,22 @@ impl super::ProcessStore for PostgresProcessStore { .fetch_optional(&self.db) .await .map(|r| r.is_some()) - .map_err(|e| e.into()) + .map_err(std::convert::Into::into) } async fn get_process(&self, pid: &str) -> anyhow::Result> { sqlx::query_as::<_, ProcessRow>( - r#"SELECT p.process_id, p.created_at, ARRAY_AGG(c.client_id) AS owners FROM processes p + r"SELECT p.process_id, p.created_at, ARRAY_AGG(c.client_id) AS owners FROM processes p LEFT JOIN process_owners po ON p.id = po.process_id LEFT JOIN clients c ON po.client_id = c.id WHERE p.process_id = $1 - GROUP BY p.process_id, p.created_at"#, + GROUP BY p.process_id, p.created_at", ) - .bind(pid) - .fetch_optional(&self.db) - .await - .map(|r| r.map(|p| p.into())) - .map_err(|e| e.into()) + .bind(pid) + .fetch_optional(&self.db) + .await + .map(|r| r.map(std::convert::Into::into)) + .map_err(std::convert::Into::into) } async fn store_process(&self, process: Process) -> anyhow::Result<()> { @@ -72,7 +72,7 @@ impl super::ProcessStore for PostgresProcessStore { // Create a process let process_row = - sqlx::query(r#"INSERT INTO processes (process_id) VALUES ($1) RETURNING id"#) + sqlx::query(r"INSERT INTO processes (process_id) VALUES ($1) RETURNING id") .bind(&process.process_id) .fetch_one(&mut *tx) .await?; @@ -81,7 +81,7 @@ impl super::ProcessStore for PostgresProcessStore { for o in process.owners { // Check if client exists - let client_row = sqlx::query(r#"SELECT id FROM clients WHERE client_id = $1"#) + let client_row = sqlx::query(r"SELECT id FROM clients WHERE client_id = $1") .bind(&o) .fetch_optional(&mut *tx) .await?; @@ -90,7 +90,7 @@ impl super::ProcessStore for PostgresProcessStore { let client_row = match client_row { Some(crow) => crow, None => { - sqlx::query(r#"INSERT INTO clients (client_id) VALUES ($1) RETURNING id"#) + sqlx::query(r"INSERT INTO clients (client_id) VALUES ($1) RETURNING id") .bind(&o) .fetch_one(&mut *tx) .await? @@ -98,12 +98,12 @@ impl super::ProcessStore for PostgresProcessStore { }; // Get id of client - let oid = client_row.get::("id"); + let client_id = client_row.get::("id"); // Create process owner - sqlx::query(r#"INSERT INTO process_owners (process_id, client_id) VALUES ($1, $2)"#) + sqlx::query(r"INSERT INTO process_owners (process_id, client_id) VALUES ($1, $2)") .bind(pid) - .bind(oid) + .bind(client_id) .execute(&mut *tx) .await?; } @@ -129,8 +129,8 @@ impl From for ProcessRow { } } -impl Into for ProcessRow { - fn into(self) -> Process { - Process::new(self.process_id, self.owners) +impl From for Process { + fn from(value: ProcessRow) -> Self { + Self::new(value.process_id, value.owners) } } diff --git a/clearing-house-app/src/lib.rs b/clearing-house-app/src/lib.rs index 57d10d2..62b648c 100644 --- a/clearing-house-app/src/lib.rs +++ b/clearing-house-app/src/lib.rs @@ -1,3 +1,7 @@ +#![forbid(unsafe_code)] +#![warn(clippy::all, clippy::pedantic, clippy::unwrap_used)] +#![allow(clippy::module_name_repetitions)] + #[macro_use] extern crate tracing; @@ -35,22 +39,25 @@ pub(crate) struct AppState { } impl AppState { + + /// Connect to the database and execute database migrations + async fn setup_postgres(conf: &config::CHConfig) -> anyhow::Result { + info!("Connecting to database"); + let pool = sqlx::PgPool::connect(&conf.database_url).await?; + + info!("Migrating database"); + sqlx::migrate!() + .run(&pool) + .await + .expect("Failed to migrate database!"); + + Ok(pool) + } + /// Initialize the application state from config async fn init(conf: &config::CHConfig) -> anyhow::Result { #[cfg(feature = "postgres")] - let pool = async { - info!("Connecting to database"); - let pool = sqlx::PgPool::connect(&conf.database_url).await.unwrap(); - - info!("Migrating database"); - sqlx::migrate!() - .run(&pool) - .await - .expect("Failed to migrate database!"); - - pool - } - .await; + let pool = Self::setup_postgres(conf).await?; trace!("Initializing Process store"); #[cfg(feature = "mongodb")] @@ -85,7 +92,7 @@ impl AppState { )); let service_config = Arc::new(util::init_service_config( - ENV_LOGGING_SERVICE_ID.to_string(), + ENV_LOGGING_SERVICE_ID, )?); let signing_key = util::init_signing_key(conf.signing_key.as_deref())?; @@ -97,6 +104,11 @@ impl AppState { } } +/// Initialize the application +/// +/// # Errors +/// +/// Throws an error if the `AppState` cannot be initialized pub async fn app() -> anyhow::Result { // Read configuration let conf = config::read_config(None); diff --git a/clearing-house-app/src/main.rs b/clearing-house-app/src/main.rs index 2588197..d302490 100644 --- a/clearing-house-app/src/main.rs +++ b/clearing-house-app/src/main.rs @@ -1,5 +1,5 @@ #![forbid(unsafe_code)] -#![warn(clippy::unwrap_used)] +#![warn(clippy::all, clippy::pedantic, clippy::unwrap_used)] use tokio::net::TcpListener; diff --git a/clearing-house-app/src/model/claims.rs b/clearing-house-app/src/model/claims.rs index 30958fb..49a7b66 100644 --- a/clearing-house-app/src/model/claims.rs +++ b/clearing-house-app/src/model/claims.rs @@ -12,8 +12,9 @@ pub struct ChClaims { } impl ChClaims { - pub fn new(client_id: &str) -> ChClaims { - ChClaims { + #[must_use] + pub fn new(client_id: &str) -> Self { + Self { client_id: client_id.to_string(), } } @@ -29,9 +30,9 @@ pub struct ExtractChClaims(pub ChClaims); #[async_trait::async_trait] impl axum::extract::FromRequestParts for ExtractChClaims -where - S: Send + Sync, - AppState: FromRef, + where + S: Send + Sync, + AppState: FromRef, { type Rejection = axum::response::Response; @@ -42,7 +43,7 @@ where let axum::extract::State(app_state) = axum::extract::State::::from_request_parts(parts, state) .await - .map_err(|err| err.into_response())?; + .map_err(axum::response::IntoResponse::into_response)?; if let Some(token) = parts.headers.get(SERVICE_HEADER) { let token = token.to_str().map_err(|_| { ( @@ -69,6 +70,12 @@ where } } +/// Returns the `JWKSet` for the RSA keypair at `key_path` +/// +/// # Panics +/// +/// Panics if the key at `key_path` is not a valid RSA keypair or does not exist. +#[must_use] pub fn get_jwks(key_path: &str) -> Option> { let keypair = biscuit::jws::Secret::rsa_keypair_from_file(key_path) .unwrap_or_else(|_| panic!("Failed to load keyfile from path {key_path}")); @@ -107,6 +114,12 @@ pub fn get_jwks(key_path: &str) -> Option> None } +/// Returns the fingerprint of the RSA keypair at `key_path` +/// +/// # Panics +/// +/// Panics if the key at `key_path` is not a valid RSA keypair or does not exist. +#[must_use] pub fn get_fingerprint(key_path: &str) -> Option { use ring::signature::KeyPair; let keypair = biscuit::jws::Secret::rsa_keypair_from_file(key_path) @@ -132,6 +145,11 @@ pub fn get_fingerprint(key_path: &str) -> Option { } } +/// Creates a JWT token with the given `issuer`, `audience` and `private_claims` +/// +/// # Panics +/// +/// Panics if the `ENV_SHARED_SECRET` is not set pub fn create_token< T: std::fmt::Display + Clone + serde::Serialize + for<'de> serde::Deserialize<'de>, >( @@ -139,15 +157,8 @@ pub fn create_token< audience: &str, private_claims: &T, ) -> String { - let signing_secret = match env::var(ENV_SHARED_SECRET) { - Ok(secret) => biscuit::jws::Secret::Bytes(secret.to_string().into_bytes()), - Err(_) => { - panic!( - "Shared Secret not configured. Please configure environment variable {}", - ENV_SHARED_SECRET - ); - } - }; + let secret = env::var(ENV_SHARED_SECRET).unwrap_or_else(|_| panic!("Shared Secret not configured. Please configure environment variable {ENV_SHARED_SECRET}")); + let signing_secret = biscuit::jws::Secret::Bytes(secret.to_string().into_bytes()); let expiration_date = chrono::Utc::now() + chrono::Duration::minutes(5); let claims = biscuit::ClaimsSet:: { @@ -171,11 +182,16 @@ pub fn create_token< ); jwt.into_encoded(&signing_secret) - .unwrap() + .expect("Encoded JWT with the signing secret") .unwrap_encoded() .to_string() } +/// Decodes the given `token` and validates it against the given `audience` +/// +/// # Errors +/// +/// Returns an error if the token is invalid or the audience is not as expected. pub fn decode_token serde::Deserialize<'de>>( token: &str, audience: &str, @@ -226,7 +242,7 @@ pub fn decode_token serde::Deserialize<'d mod test { #[test] fn get_fingerprint() { - let fingerprint = super::get_fingerprint("keys/private_key.der").unwrap(); + let fingerprint = super::get_fingerprint("keys/private_key.der").expect("Fingerprint can be generated"); assert_eq!(fingerprint, "Qra//29Frxbj5hh5Azef+G36SeiOm9q7s8+w8uGLD28"); } } diff --git a/clearing-house-app/src/model/document.rs b/clearing-house-app/src/model/document.rs index 2617090..0c655b1 100644 --- a/clearing-house-app/src/model/document.rs +++ b/clearing-house-app/src/model/document.rs @@ -17,6 +17,7 @@ pub struct Document { /// Documents should have a globally unique id, setting the id manually is discouraged. impl Document { + #[must_use] pub fn new(pid: String, content: IdsMessage) -> Self { Self { id: uuid::Uuid::new_v4(), diff --git a/clearing-house-app/src/model/ids/message.rs b/clearing-house-app/src/model/ids/message.rs index 46ad6c4..8b8e16c 100644 --- a/clearing-house-app/src/model/ids/message.rs +++ b/clearing-house-app/src/model/ids/message.rs @@ -107,10 +107,10 @@ impl Default for IdsMessage { type_message: MessageType::Message, id: Some(autogen("MessageProcessedNotification")), pid: None, - model_version: "".to_string(), + model_version: String::new(), correlation_message: None, issued: InfoModelDateTime::default(), - issuer_connector: InfoModelId::new("".to_string()), + issuer_connector: InfoModelId::new(String::new()), sender_agent: "https://w3id.org/idsa/core/ClearingHouse".to_string(), recipient_connector: None, recipient_agent: None, @@ -124,55 +124,55 @@ impl Default for IdsMessage { } } -/// Conversion from Document to IdsMessage +/// Conversion from `Document` to `IdsMessage` /// -/// note: Documents are converted into LogMessages. The LogMessage contains -/// the payload and payload type, which is the data that was stored previously. -/// All other fields of the LogMessage are meta data about the logging, e.g. +/// note: Documents are converted into `LogMessage`'s. The `LogMessage` contains +/// the `payload` and `payload_type`, which is the data that was stored previously. +/// All other fields of the `LogMessage` are `metadata` about the logging, e.g. /// when the message was logged, etc. /// -/// meta data that we also need to store -/// - message_id -/// - pid -/// - model_version -/// - correlation_message -/// - issued -/// - issuer_connector -/// - sender_agent -/// - transfer_contract -/// - content_version -/// - security_token -/// - authorization_token -/// - payload -/// - payload_type +/// metadata that we also need to store +/// - `message_id` +/// - `pid` +/// - `model_version` +/// - `correlation_message` +/// - `issued` +/// - `issuer_connector` +/// - `sender_agent` +/// - `transfer_contract` +/// - `content_version` +/// - `security_token` +/// - `authorization_token` +/// - `payload` +/// - `payload_type` impl From for IdsMessage { fn from(doc: Document) -> Self { doc.content.clone() } } -/// Conversion from IdsMessage to Document +/// Conversion from `IdsMessage` to `Document` /// /// most important part to store: -/// payload and payload type +/// `payload` and `payload_type` /// -/// meta data that we also need to store -/// - message_id -/// - pid -/// - model_version -/// - correlation_message -/// - issued -/// - issuer_connector -/// - sender_agent -/// - transfer_contract -/// - content_version -/// - security_token -/// - authorization_token -/// - payload -/// - payload_type -impl Into for IdsMessage { - fn into(self) -> Document { - let mut m = self.clone(); +/// metadata that we also need to store +/// - `message_id` +/// - `pid` +/// - `model_version` +/// - `correlation_message` +/// - `issued` +/// - `issuer_connector` +/// - `sender_agent` +/// - `transfer_contract` +/// - `content_version` +/// - `security_token` +/// - `authorization_token` +/// - `payload` +/// - `payload_type` +impl From for Document { + fn from(value: IdsMessage) -> Self { + let mut m = value.clone(); m.id = Some(m.id.unwrap_or_else(|| autogen("Message"))); diff --git a/clearing-house-app/src/model/ids/mod.rs b/clearing-house-app/src/model/ids/mod.rs index f72ed4c..0cb8162 100644 --- a/clearing-house-app/src/model/ids/mod.rs +++ b/clearing-house-app/src/model/ids/mod.rs @@ -29,6 +29,7 @@ impl std::fmt::Display for InfoModelComplexId { } impl InfoModelComplexId { + #[must_use] pub fn new(id: String) -> InfoModelComplexId { InfoModelComplexId { id: Some(id) } } @@ -48,6 +49,7 @@ pub enum InfoModelId { } impl InfoModelId { + #[must_use] pub fn new(id: String) -> InfoModelId { InfoModelId::SimpleId(id) } @@ -96,9 +98,9 @@ impl std::fmt::Display for InfoModelDateTime { pub struct InfoModelTimeStamp { //IDS name #[serde( - rename = "@type", - alias = "type", - skip_serializing_if = "Option::is_none" + rename = "@type", + alias = "type", + skip_serializing_if = "Option::is_none" )] pub format: Option, //IDS name @@ -118,7 +120,7 @@ impl Default for InfoModelTimeStamp { impl std::fmt::Display for InfoModelTimeStamp { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match serde_json::to_string(&self) { - Ok(result) => write!(f, "{}", result), + Ok(result) => write!(f, "{result}"), Err(e) => { error!("could not convert DateTimeStamp to json: {}", e); write!(f, "") @@ -362,6 +364,12 @@ pub struct IdsQueryResult { } impl IdsQueryResult { + /// Create a new `IdsQueryResult` + /// + /// # Panics + /// + /// Panics if the `date_from` or `date_to` seconds are out of reach for `chrono::NaiveDateTime::from_timestamp_opt` + #[must_use] pub fn new( date_from: i64, date_to: i64, diff --git a/clearing-house-app/src/model/mod.rs b/clearing-house-app/src/model/mod.rs index 36e06d8..4942808 100644 --- a/clearing-house-app/src/model/mod.rs +++ b/clearing-house-app/src/model/mod.rs @@ -14,13 +14,31 @@ pub enum SortingOrder { Descending, } +/// Time 00:00:00; idiomatic way to create a `chrono::NaiveTime` object +const fn start_of_day() -> chrono::NaiveTime { + if let Some(time) = chrono::NaiveTime::from_hms_opt(0, 0, 0) { + time + } else { + panic!("00:00:00 is a valid time") + } +} + +/// Time 23:59:59; idiomatic way to create a `chrono::NaiveTime` object +const fn end_of_day() -> chrono::NaiveTime { + if let Some(time) = chrono::NaiveTime::from_hms_opt(23, 59, 59) { + time + } else { + panic!("23:59:59 is a valid time") + } +} + /// Parses a date string into a `chrono::NaiveDateTime` object. If `to_date` is true, the time will be set to 23:59:59, otherwise it is 00:00:00. pub fn parse_date(date: Option, to_date: bool) -> Option { // If it is a to_date, we want to set the time to 23:59:59, otherwise it is 00:00:00 let time: chrono::NaiveTime = if to_date { - chrono::NaiveTime::from_hms_opt(23, 59, 59).expect("23:59:59 is a valid time") + end_of_day() } else { - chrono::NaiveTime::from_hms_opt(0, 0, 0).expect("00:00:00 is a valid time") + start_of_day() }; match date { @@ -39,6 +57,10 @@ pub fn parse_date(date: Option, to_date: bool) -> Option, date_to: Option, @@ -53,8 +75,7 @@ pub fn validate_and_sanitize_dates( let default_to_date = now.add(chrono::Duration::seconds(1)); let default_from_date = default_to_date .date() - .and_hms_opt(0, 0, 0) - .expect("00:00:00 is a valid time") + .and_time(start_of_day()) - chrono::Duration::weeks(2); match (date_from, date_to) { @@ -68,6 +89,7 @@ pub fn validate_and_sanitize_dates( #[cfg(test)] mod test { use std::ops::Add; + use crate::model::{end_of_day, start_of_day}; #[test] fn validate_and_sanitize_dates() { @@ -75,8 +97,7 @@ mod test { let date_now = chrono::Local::now().naive_local(); let date_now_midnight = date_now .date() - .and_hms_opt(0, 0, 0) - .expect("00:00:00 is a valid time"); + .and_time(start_of_day()); let date_from = date_now_midnight - chrono::Duration::weeks(2); let date_to = date_now_midnight - chrono::Duration::weeks(1); @@ -134,17 +155,15 @@ mod test { let wrong_date = Some("2020-13-01".to_string()); let valid_date = Some("2020-01-01".to_string()); let valid_date_parsed = chrono::NaiveDate::from_ymd_opt(2020, 1, 1).expect("This is valid"); - let day_start_time = chrono::NaiveTime::from_hms_opt(0, 0, 0).expect("This is valid"); - let day_end_time = chrono::NaiveTime::from_hms_opt(23, 59, 59).expect("This is valid"); assert!(super::parse_date(wrong_date, false).is_none()); assert_eq!( super::parse_date(valid_date.clone(), false), - Some(valid_date_parsed.and_time(day_start_time)) + Some(valid_date_parsed.and_time(start_of_day())) ); assert_eq!( super::parse_date(valid_date, true), - Some(valid_date_parsed.and_time(day_end_time)) + Some(valid_date_parsed.and_time(end_of_day())) ); } } diff --git a/clearing-house-app/src/model/process.rs b/clearing-house-app/src/model/process.rs index db4d6e1..1f936cb 100644 --- a/clearing-house-app/src/model/process.rs +++ b/clearing-house-app/src/model/process.rs @@ -5,10 +5,12 @@ pub struct Process { } impl Process { + #[must_use] pub fn new(id: String, owners: Vec) -> Self { Self { id, owners } } + #[must_use] pub fn is_authorized(&self, owner: &str) -> bool { self.owners.contains(&owner.to_string()) } @@ -42,6 +44,11 @@ pub struct DataTransaction { impl biscuit::CompactJson for DataTransaction {} impl DataTransaction { + /// Signs a `DataTransaction` with a given key on the `key_path` and returns a `Receipt`. + /// + /// # Panics + /// + /// Panics if the key at `key_path` is not a valid RSA keypair or does not exist pub fn sign(&self, key_path: &str) -> Receipt { let jws = biscuit::jws::Compact::new_decoded( biscuit::jws::Header::from_registered_header(biscuit::jws::RegisteredHeader { diff --git a/clearing-house-app/src/services/document_service.rs b/clearing-house-app/src/services/document_service.rs index 4620224..0fc72fc 100644 --- a/clearing-house-app/src/services/document_service.rs +++ b/clearing-house-app/src/services/document_service.rs @@ -6,7 +6,7 @@ use crate::model::{parse_date, validate_and_sanitize_dates, SortingOrder}; use crate::services::{DocumentReceipt, QueryResult}; use std::convert::TryFrom; -/// Error type for DocumentService +/// Error type for `DocumentService` #[derive(thiserror::Error, Debug)] pub enum DocumentServiceError { #[error("Document already exists!")] @@ -28,19 +28,15 @@ impl axum::response::IntoResponse for DocumentServiceError { fn into_response(self) -> axum::response::Response { use axum::http::StatusCode; match self { - Self::DocumentAlreadyExists => { - (StatusCode::BAD_REQUEST, self.to_string()).into_response() - } - Self::MissingPayload => (StatusCode::BAD_REQUEST, self.to_string()).into_response(), + Self::DocumentAlreadyExists | Self::MissingPayload | Self::InvalidDates => (StatusCode::BAD_REQUEST, self.to_string()).into_response(), Self::DatabaseError { source, description, } => ( StatusCode::INTERNAL_SERVER_ERROR, - format!("{}: {}", description, source), + format!("{description}: {source}"), ) .into_response(), - Self::InvalidDates => (StatusCode::BAD_REQUEST, self.to_string()).into_response(), Self::NotFound => (StatusCode::NOT_FOUND, self.to_string()).into_response(), } } @@ -69,26 +65,23 @@ impl DocumentService { } // check if doc id already exists - match self.db.exists_document(&doc.id).await { - Ok(true) => { - warn!("Document exists already!"); - Err(DocumentServiceError::DocumentAlreadyExists) - } - _ => { - // prepare the success result message - let receipt = DocumentReceipt::new(doc.ts, &doc.pid, &doc.id.to_string()); - - trace!("storing document ...."); - // store document - match self.db.add_document(doc).await { - Ok(_b) => Ok(receipt), - Err(e) => { - error!("Error while adding: {:?}", e); - Err(DocumentServiceError::DatabaseError { - source: e, - description: "Error while adding document".to_string(), - }) - } + if let Ok(true) = self.db.exists_document(&doc.id).await { + warn!("Document exists already!"); + Err(DocumentServiceError::DocumentAlreadyExists) + } else { + // prepare the success result message + let receipt = DocumentReceipt::new(doc.ts, &doc.pid, &doc.id.to_string()); + + trace!("storing document ...."); + // store document + match self.db.add_document(doc).await { + Ok(_b) => Ok(receipt), + Err(e) => { + error!("Error while adding: {:?}", e); + Err(DocumentServiceError::DatabaseError { + source: e, + description: "Error while adding document".to_string(), + }) } } } diff --git a/clearing-house-app/src/services/logging_service.rs b/clearing-house-app/src/services/logging_service.rs index de6b005..40fa1b3 100644 --- a/clearing-house-app/src/services/logging_service.rs +++ b/clearing-house-app/src/services/logging_service.rs @@ -12,7 +12,7 @@ use crate::model::{ }; use crate::services::document_service::DocumentService; -/// Error type for LoggingService +/// Error type for `LoggingService` #[derive(Debug, thiserror::Error)] pub enum LoggingServiceError { #[error("Received empty payload, which cannot be logged!")] @@ -42,10 +42,7 @@ impl axum::response::IntoResponse for LoggingServiceError { fn into_response(self) -> axum::response::Response { use axum::http::StatusCode; match self { - Self::EmptyPayloadReceived => { - (StatusCode::BAD_REQUEST, self.to_string()).into_response() - } - Self::AttemptedAccessToDefaultPid => { + Self::EmptyPayloadReceived | Self::AttemptedAccessToDefaultPid | Self::InvalidRequest | Self::ProcessAlreadyExists | Self::ParsingError(_) => { (StatusCode::BAD_REQUEST, self.to_string()).into_response() } Self::DatabaseError { @@ -53,18 +50,13 @@ impl axum::response::IntoResponse for LoggingServiceError { description, } => ( StatusCode::INTERNAL_SERVER_ERROR, - format!("{}: {}", description, source), + format!("{description}: {source}"), ) .into_response(), Self::UserNotAuthorized => (StatusCode::FORBIDDEN, self.to_string()).into_response(), - Self::InvalidRequest => (StatusCode::BAD_REQUEST, self.to_string()).into_response(), - Self::ProcessAlreadyExists => { - (StatusCode::BAD_REQUEST, self.to_string()).into_response() - } Self::ProcessDoesNotExist(_) => { (StatusCode::NOT_FOUND, self.to_string()).into_response() } - Self::ParsingError(_) => (StatusCode::BAD_REQUEST, self.to_string()).into_response(), Self::DocumentServiceError(e) => e.into_response(), } } @@ -204,10 +196,10 @@ impl LoggingService { match self.db.get_process(&pid).await { Ok(Some(p)) => { warn!("Requested pid '{}' already exists.", &p.id); - if !p.owners.contains(user) { - Err(LoggingServiceError::UserNotAuthorized) // Forbidden - } else { + if p.owners.contains(user) { Err(LoggingServiceError::ProcessAlreadyExists) // BadRequest + } else { + Err(LoggingServiceError::UserNotAuthorized) // Forbidden } } Ok(None) => { @@ -218,7 +210,7 @@ impl LoggingService { let new_process = Process::new(pid.clone(), owners); match self.db.store_process(new_process).await { - Ok(_) => Ok(pid.clone()), + Ok(()) => Ok(pid.clone()), Err(e) => { error!("Error while creating process '{}': {}", &pid, e); Err(LoggingServiceError::DatabaseError { @@ -289,6 +281,10 @@ impl LoggingService { } } + /// Query a single message by its `id` and `pid` + /// + /// `_message` is required because the `ClearingHouseMessage` as request body is required by the route + #[allow(clippy::no_effect_underscore_binding)] pub(crate) async fn query_id( &self, ch_claims: ChClaims, diff --git a/clearing-house-app/src/util.rs b/clearing-house-app/src/util.rs index 5af5d60..a43e2ba 100644 --- a/clearing-house-app/src/util.rs +++ b/clearing-house-app/src/util.rs @@ -5,8 +5,8 @@ pub struct ServiceConfig { pub service_id: String, } -pub(super) fn init_service_config(service_id: String) -> anyhow::Result { - match std::env::var(&service_id) { +pub(super) fn init_service_config(service_id: &str) -> anyhow::Result { + match std::env::var(service_id) { Ok(id) => Ok(ServiceConfig { service_id: id }), Err(_e) => { anyhow::bail!( @@ -29,6 +29,10 @@ pub(super) fn init_signing_key(signing_key_path: Option<&str>) -> anyhow::Result } /// Signal handler to catch a Ctrl+C and initiate a graceful shutdown +/// +/// # Panics +/// +/// May panic if the signal handler cannot be installed pub async fn shutdown_signal() { let ctrl_c = async { tokio::signal::ctrl_c() @@ -37,7 +41,7 @@ pub async fn shutdown_signal() { }; #[cfg(unix)] - let terminate = async { + let terminate = async { tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) .expect("failed to install signal handler") .recv() @@ -45,17 +49,18 @@ pub async fn shutdown_signal() { }; #[cfg(not(unix))] - let terminate = std::future::pending::<()>(); + let terminate = std::future::pending::<()>(); tokio::select! { - _ = ctrl_c => {}, - _ = terminate => {}, + () = ctrl_c => {}, + () = terminate => {}, } info!("signal received, starting graceful shutdown"); } /// Returns a new UUID as a string with hyphens. +#[must_use] pub fn new_uuid() -> String { use uuid::Uuid; Uuid::new_v4().hyphenated().to_string()