diff --git a/Cargo.lock b/Cargo.lock index 0377296..1c651c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -104,7 +104,7 @@ dependencies = [ "futures-util", "mio", "num_cpus", - "socket2", + "socket2 0.4.9", "tokio", "tracing", ] @@ -166,7 +166,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2", + "socket2 0.4.9", "time", "url", ] @@ -180,7 +180,16 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", ] [[package]] @@ -236,6 +245,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "asn1-rs" version = "0.3.1" @@ -260,7 +275,7 @@ checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "synstructure", ] @@ -272,7 +287,18 @@ checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "async-trait" +version = "0.1.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", ] [[package]] @@ -281,6 +307,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -340,6 +381,18 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.3.0" @@ -395,7 +448,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -475,6 +528,39 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" +[[package]] +name = "deadpool" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "tokio", +] + +[[package]] +name = "deadpool-postgres" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b75ba49590d27f677d3bebaf76cd15889ca8b308bc7ba99bfa25f1d7269c13" +dependencies = [ + "deadpool", + "tokio", + "tokio-postgres", + "tracing", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" +dependencies = [ + "tokio", +] + [[package]] name = "der-parser" version = "7.0.0" @@ -499,7 +585,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.107", ] [[package]] @@ -510,6 +596,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -520,7 +607,7 @@ checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -532,6 +619,12 @@ 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.2.8" @@ -553,6 +646,18 @@ dependencies = [ "libc", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "flate2" version = "1.0.26" @@ -593,12 +698,33 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + [[package]] name = "futures-sink" version = "0.3.25" @@ -618,9 +744,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -644,6 +773,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "h2" version = "0.3.15" @@ -656,7 +791,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.2", "slab", "tokio", "tokio-util", @@ -689,6 +824,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" + [[package]] name = "heck" version = "0.4.0" @@ -719,6 +860,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" version = "0.2.8" @@ -759,7 +909,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.1", ] [[package]] @@ -769,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -781,7 +941,7 @@ dependencies = [ "hermit-abi 0.2.6", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -799,6 +959,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "language-tags" version = "0.3.2" @@ -813,9 +982,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "linux-raw-sys" @@ -860,6 +1029,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + [[package]] name = "memchr" version = "2.5.0" @@ -889,14 +1067,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -904,12 +1082,17 @@ name = "nix-cache-bucket-gc" version = "0.1.0" dependencies = [ "actix-web", + "anyhow", "clap", + "deadpool-postgres", "handlebars", + "refinery", "serde", "serde_json", "tokio", + "tokio-postgres", "url", + "uuid", "webauthn-rs", ] @@ -963,6 +1146,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "oid-registry" version = "0.4.0" @@ -1001,7 +1193,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1043,7 +1235,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1088,7 +1280,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1102,6 +1294,24 @@ dependencies = [ "sha1", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher 0.3.11", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1120,6 +1330,35 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "postgres-protocol" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +dependencies = [ + "base64 0.21.2", + "byteorder", + "bytes", + "fallible-iterator", + "hmac", + "md-5", + "memchr", + "rand", + "sha2", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +dependencies = [ + "bytes", + "fallible-iterator", + "postgres-protocol", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1135,7 +1374,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", ] @@ -1152,18 +1391,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1207,6 +1446,51 @@ dependencies = [ "bitflags", ] +[[package]] +name = "refinery" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529664dbccc0a296947615c997a857912d72d1c44be1fafb7bae54ecfa7a8c24" +dependencies = [ + "refinery-core", + "refinery-macros", +] + +[[package]] +name = "refinery-core" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e895cb870cf06e92318cbbeb701f274d022d5ca87a16fa8244e291cd035ef954" +dependencies = [ + "async-trait", + "cfg-if", + "lazy_static", + "log", + "regex", + "serde", + "siphasher 1.0.0", + "thiserror", + "time", + "tokio", + "tokio-postgres", + "toml", + "url", + "walkdir", +] + +[[package]] +name = "refinery-macros" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123e8b80f8010c3ae38330c81e76938fc7adf6cdbfbaad20295bb8c22718b4f1" +dependencies = [ + "proc-macro2", + "quote", + "refinery-core", + "regex", + "syn 2.0.37", +] + [[package]] name = "regex" version = "1.9.1" @@ -1236,6 +1520,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1265,7 +1555,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1274,6 +1564,15 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1313,7 +1612,7 @@ checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1327,6 +1626,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1350,6 +1658,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1359,6 +1678,18 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe" + [[package]] name = "slab" version = "0.4.7" @@ -1376,20 +1707,47 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.107" @@ -1401,6 +1759,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -1409,7 +1778,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "unicode-xid", ] @@ -1439,7 +1808,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1486,33 +1855,59 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.25.1" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78819ab9e79e14aefb149593f15c07239d0cea924cb44e1259e1bec643619e6" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.4.9", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "rand", + "socket2 0.5.4", + "tokio", + "tokio-util", + "whoami", ] [[package]] @@ -1529,6 +1924,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.37" @@ -1550,7 +1979,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1615,9 +2044,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.2.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "serde", @@ -1635,12 +2064,86 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webauthn-rs" version = "0.4.8" @@ -1691,6 +2194,16 @@ dependencies = [ "url", ] +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1728,13 +2241,37 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.0", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm 0.42.0", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1743,42 +2280,93 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] + [[package]] name = "x509-parser" version = "0.13.2" diff --git a/Cargo.toml b/Cargo.toml index 35739b0..d5c6722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,8 @@ webauthn-rs = "0.4.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" handlebars = "4.3.6" +deadpool-postgres = "0.11.0" +tokio-postgres = "0.7.10" +anyhow = "1.0.75" +refinery = { version = "0.8.11", features = ["tokio-postgres"] } +uuid = { version = "1.4.1", features = ["v4"] } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 38d4217..48cb2d7 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,7 +1,7 @@ use webauthn_rs::prelude::{RegisterPublicKeyCredential, Uuid}; use actix_web::{error, HttpResponse, http::header::{ContentType, self}, web, cookie::{Cookie, SameSite}, HttpRequest}; -use crate::{models::{AppState, User}, templates}; +use crate::{models::{AppState, User, PendingRegistration}, templates}; pub async fn landing_page (app_state: web::Data>) -> HttpResponse { let content: String = templates::landing_page(app_state.hbs.clone()).unwrap(); @@ -10,16 +10,21 @@ pub async fn landing_page (app_state: web::Data>) -> HttpResponse { .body(content) } +/// First phase of the webauthn key enrolling. +/// +/// For now, we don't save anything to the DB. We just generate the +/// challenge, the UUID and store everything in the session hashmap +/// server-side, in the response and cookie on the client-side. pub async fn start_webauthn_registration(app_state: web::Data>, user: web::Json) -> HttpResponse { - let (creation_challenge_response, passkey_registration) = app_state.webauthn.start_passkey_registration(user.uuid, &user.user_name, &user.display_name, None).unwrap(); - let uuid_str = user.uuid.to_string(); + let uuid = Uuid::new_v4(); + let (creation_challenge_response, passkey_registration) = app_state.webauthn.start_passkey_registration(uuid, &user.user_name, &user.display_name, None).unwrap(); + let uuid_str = uuid.to_string(); { - let mut session = app_state.session.user_registrations.write().await; - session.insert(user.clone(), passkey_registration); - } - { - let mut uuid_db = app_state.db.user_uuid_object.write().await; - uuid_db.insert(user.uuid, user.into_inner()); + let mut user_registrations = app_state.session.user_registrations.write().await; + user_registrations.insert(uuid, PendingRegistration{ + user: user.into_inner(), + registration: passkey_registration + }); } let res = serde_json::to_string(&creation_challenge_response).unwrap(); let cookie = Cookie::build("uuid", &uuid_str) @@ -32,24 +37,37 @@ pub async fn start_webauthn_registration(app_state: web::Data>, use .body(res) } +/// Final phase of the webauthn key enrolling. +/// +/// We verify the key enrolling challenge, then store the new key in the DB. pub async fn finish_webauthn_registration(req: HttpRequest, app_state: web::Data>, register: web::Json) -> impl actix_web::Responder { let cook = req.cookie("uuid"); let uuid = Uuid::parse_str(cook.unwrap().value()).unwrap(); - let registration_result = { - let users = app_state.db.user_uuid_object.read().await; - let user = users.get(&uuid).unwrap(); - let session = app_state.session.user_registrations.read().await; - let passkey_registration = session.get(user).unwrap(); - app_state.webauthn.finish_passkey_registration(®ister, passkey_registration) + let pending_registration: Option = { + let user_registrations = app_state.session.user_registrations.read().await; + user_registrations.get(&uuid).cloned() }; - let mut user_keys = app_state.db.user_keys.write().await; - match registration_result { - Ok(passkey) => { - user_keys.insert(uuid, passkey); - HttpResponse::Ok() - .body("ok") + + // 1. Check registration. + // 2. Save user. + // 3. Save key. + match pending_registration { + Some(PendingRegistration { user, registration }) => { + let registration_result = app_state.webauthn.finish_passkey_registration(®ister, ®istration); + match registration_result { + Ok(passkey) => { + let _ = app_state.save_user(&user).await; + let _ = app_state.save_user_key(&uuid, &passkey).await; + HttpResponse::Ok() + .body("ok") + }, + Err(_) => + HttpResponse::from_error(error::ErrorUnauthorized("Webauthn challenge failed")) + } }, - Err(_) => - HttpResponse::from_error(error::ErrorUnauthorized("Webauthn challenge failed")) + None => { + return HttpResponse::from_error(error::ErrorInternalServerError("Session expired")) + } + } } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6c0a10a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +pub mod app; +pub mod handlers; +pub mod models; +pub mod templates; diff --git a/src/main.rs b/src/main.rs index 657d760..a2e8515 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,11 @@ -use std::net::SocketAddr; use actix_web::{App, web, HttpServer}; +use anyhow::{Result, Context}; use clap::Parser; +use models::Configuration; +use serde::Deserialize; +use serde_json; +use std::fs; +use std::net::SocketAddr; mod app; mod handlers; @@ -11,19 +16,30 @@ mod templates; #[command(author, version, about, long_about = None)] struct CLIArgs { #[arg(short, long)] - bind: String + bind: String, + #[arg(short, long)] + config: String +} + +fn read_config(config_path: &str) -> Result { + let content = fs::read_to_string(config_path) + .with_context(|| format!("Cannot read the configuration file at {}.", config_path))?; + let res: Configuration = serde_json::from_str(&content) + .context("Cannot parse JSON configuration.")?; + Ok(res) } #[tokio::main] async fn main() -> std::io::Result<()> { let args = CLIArgs::parse(); let addr: SocketAddr = args.bind.parse().unwrap_or_else(|_| panic!("Cannot bind to {}. Please provide a host and port like [::1]:8000", &args.bind)); - println!("Server listening to {}", &args.bind); HttpServer::new( - || { - let state = models::AppState::new(); + move || { + let config = read_config(&args.config) + .unwrap_or_else(|e| panic!("Cannot read config file: {}", e.to_string())); + let state = models::AppState::new(config); App::new().app_data(web::Data::new(state)) .route("/", web::get().to(handlers::landing_page)) .route("/account/register-init", web::post().to(handlers::start_webauthn_registration)) diff --git a/src/models/mod.rs b/src/models/mod.rs index 76c8014..a784eff 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,30 +1,47 @@ use serde::{Deserialize, Serialize}; use url::Url; +use std::ops::DerefMut; use std::sync::Arc; use std::collections::HashMap; -use tokio::sync::RwLock; - +use anyhow::Result; +use deadpool_postgres::{Manager, ManagerConfig, Pool, RecyclingMethod}; use handlebars::Handlebars; +use tokio::sync::RwLock; +use tokio_postgres::NoTls; use webauthn_rs::prelude::{Uuid, PasskeyRegistration, Passkey}; use webauthn_rs::{Webauthn, WebauthnBuilder}; +#[derive(Deserialize, Debug)] +pub struct Configuration { + pub url: String, + pub db_host: Option, + pub db_port: Option, + pub db_name: String +} + pub type DbField = Arc>; #[derive(Clone)] pub struct Db { + pub user_keys: DbField>, pub user_uuid_object: DbField>, } #[derive(Clone)] pub struct TempSession { - pub user_registrations: Arc>> + pub user_registrations: Arc>> +} + +#[derive(Clone)] +pub struct PendingRegistration { + pub user: User, + pub registration: PasskeyRegistration } #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash)] pub struct User { - pub uuid: Uuid, pub user_name: String, pub display_name: String, } @@ -32,13 +49,18 @@ pub struct User { #[derive(Clone)] pub struct AppState<'a>{ pub webauthn: Arc, - pub db: Db, + pub db: Pool, pub hbs: Arc>, pub session: TempSession } +mod embedded { + use refinery::embed_migrations; + embed_migrations!("src/sql/01-init.sql"); +} + impl AppState<'_> { - pub fn new() -> Self { + pub fn new(args: Configuration) -> Self { let rp = "localhost"; let rp_origin = Url::parse("http://localhost:8000").expect("Invalid URL"); let builder = WebauthnBuilder::new(rp, &rp_origin).expect("Invalid configuration"); @@ -47,12 +69,21 @@ impl AppState<'_> { let db: Db = Db { user_keys: Arc::new(RwLock::new(HashMap::new())), user_uuid_object: Arc::new(RwLock::new(HashMap::new())) - }; let hbs = Arc::new(crate::templates::new().unwrap()); let session: TempSession = TempSession { user_registrations: Arc::new(RwLock::new(HashMap::new())) }; + let mut pg_config = tokio_postgres::Config::new(); + pg_config.host_path("/run/postgresql"); + pg_config.host_path("/tmp"); + pg_config.user("deadpool"); + pg_config.dbname("deadpool"); + let mgr_config = ManagerConfig { + recycling_method: RecyclingMethod::Fast + }; + let mgr = Manager::from_config(pg_config, NoTls, mgr_config); + let db = Pool::builder(mgr).max_size(16).build().unwrap(); AppState { webauthn, @@ -61,4 +92,40 @@ impl AppState<'_> { session } } + + pub async fn run_migrations(&mut self) -> Result<()> { + let mut conn = self.db.get().await?; + let client = conn.deref_mut().deref_mut(); + embedded::migrations::runner().run_async(client).await?; + Ok(()) + } + + + pub async fn save_user(&self, user: &User) -> Result<()> { + let mut conn = self.db.get().await?; + let client = conn.deref_mut(); + let stmt = client.prepare_cached("INSERT INTO Users (user_name, display_name) VALUES ($1, $2, $3)").await?; + client.query(&stmt, &[&user.user_name, &user.display_name]); + Ok(()) + } + + pub async fn save_user_key(&self, uuid: &Uuid, passkey: &Passkey) -> Result<()> { + let passkey_json: String = serde_json::to_string(&passkey)?; + let mut conn = self.db.get().await?; + let client = conn.deref_mut(); + let stmt = client.prepare_cached("INSERT INTO Keys (key_dump, user_id) VALUES ($1,$2)").await?; + client.query(&stmt, &[&passkey_json, &uuid.to_string()]).await?; + Ok(()) + } + + pub async fn get_user_keys(&self, user_uuid: &Uuid) -> Result>> { + let mut conn = self.db.get().await?; + let client = conn.deref_mut(); + let stmt = client.prepare_cached("SELECT key_dump FROM Keys WHERE user_id = $1").await?; + let res = client.query(&stmt, &[&user_uuid.to_string()]).await?; + let res2 = res.iter().map(|row| { + serde_json::from_str(row.get(0)) + }).collect(); + Ok(res2) + } } diff --git a/src/sql/01-init.sql b/src/sql/01-init.sql new file mode 100644 index 0000000..e6ae594 --- /dev/null +++ b/src/sql/01-init.sql @@ -0,0 +1,16 @@ +CREATE TABLE Users ( + id uuid DEFAULT uuid_generate_v4 (), + user_name text NOT NULL, + display_name text NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE Keys ( + id integer PRIMARY KEY, + key_dump jsonb NOT NULL, + user_id uuid NOT NULL, + CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES Users(id) +); + +-- We'll mostly querying the Keys using the associated uid. +CREATE INDEX idx_keys_uid ON Keys USING HASH (user_id); diff --git a/tests/db.rs b/tests/db.rs new file mode 100644 index 0000000..2cd4926 --- /dev/null +++ b/tests/db.rs @@ -0,0 +1,61 @@ +use std::{process::{Command, Child}, env::temp_dir, path::PathBuf, fs::remove_dir_all, time::Duration}; + +use nix_cache_bucket_gc::models::{self, Configuration, AppState}; +use tokio::time::sleep; +use uuid::Uuid; +use anyhow::Result; + + +struct TestDB { + path: PathBuf, + pid: Child, + db_name: String, + port: u16 +} + +async fn setup_db() -> Result { + let mut dbdir = temp_dir(); + let dir_uuid = Uuid::new_v4(); + let db_name = "nom-nom-integration-test".to_string(); + let port: u16 = 12345; + dbdir.push(dir_uuid.to_string()); + let dbdir_str = dbdir.to_str().unwrap(); + Command::new("initdb") + .arg(&dbdir) + .spawn()? + .wait()?; + let db_proc_handle = Command::new("postgres") + .args(["-D", dbdir_str, "-c", &format!("unix_socket_directories={}", dbdir_str) , "-c", &format!("port={}", &port.to_string())]) + .spawn()?; + let test = sleep(Duration::from_secs(1)).await; + Command::new("createdb") + .args([ "-h", dbdir_str, "-p", &port.to_string(), &db_name]) + .spawn()? + .wait()?; + Ok(TestDB{ path: dbdir, pid: db_proc_handle, db_name, port }) +} + +fn teardown_db(mut db: TestDB) -> Result <()> { + db.pid.kill()?; + remove_dir_all(db.path)?; + Ok(()) +} + +#[tokio::test] +async fn test_migratios() { + let mdb = setup_db().await; + let db = mdb.expect("setup db"); + + let conf = Configuration { + url: db.path.to_str().unwrap().to_string(), + db_port: Some(db.port), + db_host: Some(db.path.to_str().unwrap().to_string()), + db_name: db.db_name.clone() + }; + + let mut state = AppState::new(conf); + let res = state.run_migrations().await; + res.expect("migrations should not fail"); + + teardown_db(db).expect("Failed to teardown DB."); +}