mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Get SQLX to work
This commit is contained in:
parent
242cf8eddd
commit
26a98ae89a
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -2,4 +2,8 @@
|
|||||||
"rust-analyzer.diagnostics.disabled": [
|
"rust-analyzer.diagnostics.disabled": [
|
||||||
"macro-error"
|
"macro-error"
|
||||||
],
|
],
|
||||||
|
"rust-analyzer.cargo.noDefaultFeatures": false,
|
||||||
|
"rust-analyzer.cargo.features": [
|
||||||
|
"sqlite"
|
||||||
|
],
|
||||||
}
|
}
|
588
Cargo.lock
generated
588
Cargo.lock
generated
@ -146,6 +146,24 @@ dependencies = [
|
|||||||
"event-listener",
|
"event-listener",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-process"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02111fd8655a613c25069ea89fc8d9bb89331fa77486eb3bc059ee757cfa481c"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"autocfg",
|
||||||
|
"blocking",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"event-listener",
|
||||||
|
"futures-lite",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"signal-hook",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-session"
|
name = "async-session"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@ -164,7 +182,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2 0.9.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -177,6 +195,7 @@ dependencies = [
|
|||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock",
|
||||||
|
"async-process",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -210,6 +229,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atoi"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -411,6 +439,12 @@ version = "3.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -474,7 +508,7 @@ dependencies = [
|
|||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time 0.1.44",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -566,6 +600,16 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05"
|
||||||
|
dependencies = [
|
||||||
|
"time 0.3.14",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -575,6 +619,31 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
|
||||||
|
dependencies = [
|
||||||
|
"crc-catalog",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc-catalog"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.10"
|
version = "0.8.10"
|
||||||
@ -667,6 +736,44 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenvy"
|
||||||
|
version = "0.15.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da3db6fcad7c1fc4abdd99bf5276a4db30d6a819127903a709ed41e5ff016e84"
|
||||||
|
dependencies = [
|
||||||
|
"dirs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "event-listener"
|
name = "event-listener"
|
||||||
version = "2.5.2"
|
version = "2.5.2"
|
||||||
@ -682,6 +789,18 @@ dependencies = [
|
|||||||
"instant",
|
"instant",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flume"
|
||||||
|
version = "0.10.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"pin-project",
|
||||||
|
"spin 0.9.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -705,6 +824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -713,6 +833,28 @@ version = "0.3.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-intrusive"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
@ -734,6 +876,17 @@ dependencies = [
|
|||||||
"waker-fn",
|
"waker-fn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-rustls"
|
||||||
|
version = "0.22.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd"
|
||||||
|
dependencies = [
|
||||||
|
"futures-io",
|
||||||
|
"rustls",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
@ -753,9 +906,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -858,6 +1013,18 @@ name = "hashbrown"
|
|||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d452c155cb93fecdfb02a73dd57b5d8e442c2063bd7aac72f1bc5e4263a43086"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "headers"
|
name = "headers"
|
||||||
@ -884,6 +1051,15 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
@ -893,6 +1069,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -967,6 +1149,17 @@ dependencies = [
|
|||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
@ -986,6 +1179,15 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
@ -1028,6 +1230,7 @@ dependencies = [
|
|||||||
"axum-auth",
|
"axum-auth",
|
||||||
"ciborium",
|
"ciborium",
|
||||||
"clap",
|
"clap",
|
||||||
|
"cookie",
|
||||||
"csv",
|
"csv",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"recipe-store",
|
"recipe-store",
|
||||||
@ -1036,6 +1239,7 @@ dependencies = [
|
|||||||
"rust-embed",
|
"rust-embed",
|
||||||
"secrecy",
|
"secrecy",
|
||||||
"serde",
|
"serde",
|
||||||
|
"sqlx",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -1186,6 +1390,17 @@ dependencies = [
|
|||||||
"zstd-sys",
|
"zstd-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
version = "1.1.8"
|
version = "1.1.8"
|
||||||
@ -1197,6 +1412,16 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.17"
|
||||||
@ -1321,6 +1546,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@ -1345,6 +1579,31 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"instant",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "password-hash"
|
name = "password-hash"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@ -1502,6 +1761,26 @@ dependencies = [
|
|||||||
"num-rational",
|
"num-rational",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"redox_syscall",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
@ -1534,6 +1813,21 @@ dependencies = [
|
|||||||
"gloo-net",
|
"gloo-net",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"spin 0.5.2",
|
||||||
|
"untrusted",
|
||||||
|
"web-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rocksdb"
|
name = "rocksdb"
|
||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
@ -1574,7 +1868,7 @@ version = "7.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029"
|
checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sha2",
|
"sha2 0.9.9",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1584,6 +1878,27 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.20.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
@ -1599,6 +1914,22 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secrecy"
|
name = "secrecy"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -1676,6 +2007,17 @@ dependencies = [
|
|||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "899bf02746a2c92bf1053d9327dadb252b01af1f81f90cdb902411f518bc7215"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest 0.10.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@ -1691,6 +2033,25 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook"
|
||||||
|
version = "0.3.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@ -1716,12 +2077,136 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlformat"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"nom",
|
||||||
|
"unicode_categories",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "788841def501aabde58d3666fcea11351ec3962e6ea75dbcd05c84a71d68bcd1"
|
||||||
|
dependencies = [
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-core"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c21d3b5e7cadfe9ba7cdc1295f72cc556c750b4419c27c219c0693198901f8e"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"atoi",
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"crc",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"event-listener",
|
||||||
|
"flume",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-intrusive",
|
||||||
|
"futures-util",
|
||||||
|
"hashlink",
|
||||||
|
"hex",
|
||||||
|
"indexmap",
|
||||||
|
"itoa 1.0.2",
|
||||||
|
"libc",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"paste",
|
||||||
|
"percent-encoding",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"serde",
|
||||||
|
"sha2 0.10.3",
|
||||||
|
"smallvec",
|
||||||
|
"sqlformat",
|
||||||
|
"sqlx-rt",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-macros"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4adfd2df3557bddd3b91377fc7893e8fa899e9b4061737cbade4e1bb85f1b45c"
|
||||||
|
dependencies = [
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"heck",
|
||||||
|
"hex",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2 0.10.3",
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-rt",
|
||||||
|
"syn",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-rt"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7be52fc7c96c136cedea840ed54f7d446ff31ad670c9dea95ebcb998530971a3"
|
||||||
|
dependencies = [
|
||||||
|
"async-std",
|
||||||
|
"futures-rustls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stringprep"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@ -1851,6 +2336,39 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b"
|
||||||
|
dependencies = [
|
||||||
|
"itoa 1.0.2",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.20.0"
|
version = "1.20.0"
|
||||||
@ -2023,12 +2541,57 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode_categories"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@ -2184,6 +2747,25 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.22.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf"
|
||||||
|
dependencies = [
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wepoll-ffi"
|
name = "wepoll-ffi"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
3
Makefile
3
Makefile
@ -12,6 +12,9 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
sqlx-prepare: wasm kitches/src/*.rs
|
||||||
|
cd kitchen; cargo sqlx-prepare
|
||||||
|
|
||||||
kitchen: wasm kitchen/src/*.rs
|
kitchen: wasm kitchen/src/*.rs
|
||||||
cd kitchen; cargo build
|
cd kitchen; cargo build
|
||||||
|
|
||||||
|
@ -56,9 +56,7 @@
|
|||||||
type = "app";
|
type = "app";
|
||||||
program = "${kitchen}/bin/kitchen";
|
program = "${kitchen}/bin/kitchen";
|
||||||
};
|
};
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.callPackage ./nix/devShell/default.nix { inherit rust-wasm; };
|
||||||
buildInputs = [ rust-wasm ] ++ (with pkgs; [wasm-bindgen-cli wasm-pack]);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -17,9 +17,9 @@ mime_guess = "2.0.4"
|
|||||||
async-trait = "0.1.57"
|
async-trait = "0.1.57"
|
||||||
async-session = "3.0.0"
|
async-session = "3.0.0"
|
||||||
ciborium = "0.2.0"
|
ciborium = "0.2.0"
|
||||||
rocksdb = "0.19.0"
|
|
||||||
tower = "0.4.13"
|
tower = "0.4.13"
|
||||||
serde = "1.0.144"
|
serde = "1.0.144"
|
||||||
|
cookie = "0.16.0"
|
||||||
|
|
||||||
[dependencies.argon2]
|
[dependencies.argon2]
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -50,4 +50,18 @@ features = [ "cargo" ]
|
|||||||
|
|
||||||
[dependencies.async-std]
|
[dependencies.async-std]
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
features = ["tokio1"]
|
features = ["tokio1"]
|
||||||
|
|
||||||
|
[dependencies.sqlx]
|
||||||
|
version = "0.6.1"
|
||||||
|
features = ["sqlite", "runtime-async-std-rustls", "offline"]
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.rocksdb]
|
||||||
|
version = "0.19.0"
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
sqlite = ["dep:sqlx"]
|
||||||
|
rocksdb = ["dep:rocksdb"]
|
||||||
|
default = ["sqlite"]
|
3
kitchen/migrations/20220831185348_initial.down.sql
Normal file
3
kitchen/migrations/20220831185348_initial.down.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- Add down migration script here
|
||||||
|
drop table sessions;
|
||||||
|
drop table users;
|
3
kitchen/migrations/20220831185348_initial.up.sql
Normal file
3
kitchen/migrations/20220831185348_initial.up.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- Add migration script here
|
||||||
|
CREATE TABLE sessions(id TEXT PRIMARY KEY, session_value BLOB NOT NULL);
|
||||||
|
CREATE TABLE users(id TEXT PRIMARY KEY, password_hashed TEXT NOT NULL);
|
79
kitchen/sqlx-data.json
Normal file
79
kitchen/sqlx-data.json
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"db": "SQLite",
|
||||||
|
"104f07472670436d3eee1733578bbf0c92dc4f965d3d13f9bf4bfbc92958c5b6": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "password_hashed",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "select password_hashed from users where id = ?"
|
||||||
|
},
|
||||||
|
"5d743897fb0d8fd54c3708f1b1c6e416346201faa9e28823c1ba5a421472b1fa": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "insert into users (id, password_hashed) values (?, ?)"
|
||||||
|
},
|
||||||
|
"7578157607967a6a4c60f12408c5d9900d15b429a49681a4cae4e02d31c524ec": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "delete from sessions where id = ?"
|
||||||
|
},
|
||||||
|
"928a479ca0f765ec7715bf8784c5490e214486edbf5b78fd501823feb328375b": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "session_value",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Blob"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "select session_value from sessions where id = ?"
|
||||||
|
},
|
||||||
|
"9ad4acd9b9d32c9f9f441276aa71a17674fe4d65698848044778bd4aef77d42d": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "insert into sessions (id, session_value) values (?, ?)"
|
||||||
|
},
|
||||||
|
"d84685a82585c5e4ae72c86ba1fe6e4a7241c4c3c9e948213e5849d956132bad": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "delete from sessions"
|
||||||
|
}
|
||||||
|
}
|
@ -45,14 +45,14 @@ fn create_app<'a>() -> clap::App<'a> {
|
|||||||
(@subcommand serve =>
|
(@subcommand serve =>
|
||||||
(about: "Serve the interface via the web")
|
(about: "Serve the interface via the web")
|
||||||
(@arg recipe_dir: -d --dir +takes_value "Directory containing recipe files to use")
|
(@arg recipe_dir: -d --dir +takes_value "Directory containing recipe files to use")
|
||||||
(@arg session_dir: --sesion_dir + takes_value "Session store directory to use")
|
(@arg session_dir: --session_dir + takes_value "Session store directory to use")
|
||||||
(@arg listen: --listen +takes_value "address and port to listen on 0.0.0.0:3030")
|
(@arg listen: --listen +takes_value "address and port to listen on 0.0.0.0:3030")
|
||||||
)
|
)
|
||||||
(@subcommand add_user =>
|
(@subcommand add_user =>
|
||||||
(about: "add users to to the interface")
|
(about: "add users to to the interface")
|
||||||
(@arg user: -u --user +takes_value +required "username to add")
|
(@arg user: -u --user +takes_value +required "username to add")
|
||||||
(@arg pass: -p --pass +takes_value +required "password to add for this user")
|
(@arg pass: -p --pass +takes_value +required "password to add for this user")
|
||||||
(@arg session_dir: --sesion_dir +takes_value "Session store directory to use")
|
(@arg session_dir: --session_dir +takes_value "Session store directory to use")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
||||||
@ -139,10 +139,13 @@ fn main() {
|
|||||||
});
|
});
|
||||||
} else if let Some(matches) = matches.subcommand_matches("add_user") {
|
} else if let Some(matches) = matches.subcommand_matches("add_user") {
|
||||||
let session_store_path: PathBuf = get_session_store_path(matches);
|
let session_store_path: PathBuf = get_session_store_path(matches);
|
||||||
web::add_user(
|
async_std::task::block_on(async {
|
||||||
session_store_path,
|
web::add_user(
|
||||||
matches.value_of("user").unwrap().to_owned(),
|
session_store_path,
|
||||||
matches.value_of("pass").unwrap().to_owned(),
|
matches.value_of("user").unwrap().to_owned(),
|
||||||
);
|
matches.value_of("pass").unwrap().to_owned(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,22 +20,23 @@ use axum::{
|
|||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use axum_auth::AuthBasic;
|
use axum_auth::AuthBasic;
|
||||||
|
use cookie::{Cookie, SameSite};
|
||||||
use secrecy::Secret;
|
use secrecy::Secret;
|
||||||
use tracing::{debug, info, instrument};
|
use tracing::{debug, info, instrument};
|
||||||
|
|
||||||
use super::session;
|
use super::session::{self, AuthStore};
|
||||||
|
|
||||||
#[instrument(skip_all, fields(user=%auth.0.0))]
|
#[instrument(skip_all, fields(user=%auth.0.0))]
|
||||||
pub async fn handler(
|
pub async fn handler(
|
||||||
auth: AuthBasic,
|
auth: AuthBasic,
|
||||||
Extension(session_store): Extension<session::RocksdbInnerStore>,
|
Extension(session_store): Extension<session::SqliteStore>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
// NOTE(jwall): It is very important that you do **not** log the password
|
// NOTE(jwall): It is very important that you do **not** log the password
|
||||||
// here. We convert the AuthBasic into UserCreds immediately to help prevent
|
// here. We convert the AuthBasic into UserCreds immediately to help prevent
|
||||||
// that. Do not circumvent that protection.
|
// that. Do not circumvent that protection.
|
||||||
let auth = session::UserCreds::from(auth);
|
let auth = session::UserCreds::from(auth);
|
||||||
info!("Handling authentication request");
|
info!("Handling authentication request");
|
||||||
if let Ok(true) = session_store.check_user_creds(&auth) {
|
if let Ok(true) = session_store.check_user_creds(&auth).await {
|
||||||
debug!("successfully authenticated user");
|
debug!("successfully authenticated user");
|
||||||
// 1. Create a session identifier.
|
// 1. Create a session identifier.
|
||||||
let mut session = Session::new();
|
let mut session = Session::new();
|
||||||
@ -44,17 +45,11 @@ pub async fn handler(
|
|||||||
let cookie_value = session_store.store_session(session).await.unwrap().unwrap();
|
let cookie_value = session_store.store_session(session).await.unwrap().unwrap();
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
// 3. Construct the Session Cookie.
|
// 3. Construct the Session Cookie.
|
||||||
// TODO(jwall): Find or Build a cookie builder.
|
let cookie = Cookie::build(session::AXUM_SESSION_COOKIE_NAME, cookie_value)
|
||||||
headers.insert(
|
.same_site(SameSite::Strict)
|
||||||
header::SET_COOKIE,
|
.secure(true)
|
||||||
format!(
|
.finish();
|
||||||
"{}={} SameSite=Strict Secure",
|
headers.insert(header::SET_COOKIE, cookie.to_string().parse().unwrap());
|
||||||
session::AXUM_SESSION_COOKIE_NAME,
|
|
||||||
cookie_value
|
|
||||||
)
|
|
||||||
.parse()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
// Respond with 200 OK
|
// Respond with 200 OK
|
||||||
(StatusCode::OK, headers, "Login Successful")
|
(StatusCode::OK, headers, "Login Successful")
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,6 +29,8 @@ use tower::ServiceBuilder;
|
|||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
use tracing::{debug, info, instrument};
|
use tracing::{debug, info, instrument};
|
||||||
|
|
||||||
|
use session::AuthStore;
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
mod session;
|
mod session;
|
||||||
|
|
||||||
@ -113,8 +115,9 @@ async fn api_categories(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_user(session_store_path: PathBuf, username: String, password: String) {
|
pub async fn add_user(session_store_path: PathBuf, username: String, password: String) {
|
||||||
let session_store = session::RocksdbInnerStore::new(session_store_path)
|
let session_store = session::SqliteStore::new(session_store_path)
|
||||||
|
.await
|
||||||
.expect("Unable to create session_store");
|
.expect("Unable to create session_store");
|
||||||
let user_creds = session::UserCreds {
|
let user_creds = session::UserCreds {
|
||||||
id: session::UserId(username),
|
id: session::UserId(username),
|
||||||
@ -122,6 +125,7 @@ pub fn add_user(session_store_path: PathBuf, username: String, password: String)
|
|||||||
};
|
};
|
||||||
session_store
|
session_store
|
||||||
.store_user_creds(user_creds)
|
.store_user_creds(user_creds)
|
||||||
|
.await
|
||||||
.expect("Failed to store user creds");
|
.expect("Failed to store user creds");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +137,8 @@ pub async fn ui_main(
|
|||||||
) {
|
) {
|
||||||
let store = Arc::new(recipe_store::AsyncFileStore::new(recipe_dir_path.clone()));
|
let store = Arc::new(recipe_store::AsyncFileStore::new(recipe_dir_path.clone()));
|
||||||
//let dir_path = (&dir_path).clone();
|
//let dir_path = (&dir_path).clone();
|
||||||
let session_store = session::RocksdbInnerStore::new(session_store_path)
|
let session_store = session::SqliteStore::new(session_store_path)
|
||||||
|
.await
|
||||||
.expect("Unable to create session_store");
|
.expect("Unable to create session_store");
|
||||||
let router = Router::new()
|
let router = Router::new()
|
||||||
.route("/", get(|| async { Redirect::temporary("/ui/plan") }))
|
.route("/", get(|| async { Redirect::temporary("/ui/plan") }))
|
||||||
|
@ -18,13 +18,16 @@ use argon2::{
|
|||||||
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||||
Argon2,
|
Argon2,
|
||||||
};
|
};
|
||||||
use async_session::{async_trait, Session, SessionStore};
|
use async_session::{Session, SessionStore};
|
||||||
|
use async_trait::async_trait;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Extension, FromRequest, RequestParts, TypedHeader},
|
extract::{Extension, FromRequest, RequestParts, TypedHeader},
|
||||||
headers::Cookie,
|
headers::Cookie,
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
};
|
};
|
||||||
use ciborium;
|
use ciborium;
|
||||||
|
use cookie::{Cookie as CookieParse, SameSite};
|
||||||
|
#[cfg(feature = "rocksdb")]
|
||||||
use rocksdb::{
|
use rocksdb::{
|
||||||
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
BoundColumnFamily, ColumnFamilyDescriptor, DBWithThreadMode, MultiThreaded, Options,
|
||||||
};
|
};
|
||||||
@ -57,12 +60,40 @@ impl UserCreds {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_id_key(cookie_value: &str) -> async_session::Result<String> {
|
||||||
|
debug!("deserializing cookie");
|
||||||
|
Ok(Session::id_from_cookie_value(cookie_value)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip_all, fields(hash=payload))]
|
||||||
|
fn check_pass(payload: &String, pass: &Secret<String>) -> bool {
|
||||||
|
let parsed_hash = PasswordHash::new(&payload).expect("Invalid Password Hash");
|
||||||
|
debug!(password_hash=?parsed_hash, "successfuly obtained password hash");
|
||||||
|
let check = Argon2::default().verify_password(pass.expose_secret().as_bytes(), &parsed_hash);
|
||||||
|
if let Err(err) = &check {
|
||||||
|
debug!(err=?err, "Couldn't verify password");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
check.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait AuthStore: SessionStore {
|
||||||
|
/// Check user credentials against the user store.
|
||||||
|
async fn check_user_creds(&self, user_creds: &UserCreds) -> async_session::Result<bool>;
|
||||||
|
|
||||||
|
/// Insert or update user credentials in the user store.
|
||||||
|
async fn store_user_creds(&self, user_creds: UserCreds) -> async_session::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rocksdb")]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RocksdbInnerStore {
|
pub struct RocksdbStore {
|
||||||
db: Arc<DBWithThreadMode<MultiThreaded>>,
|
db: Arc<DBWithThreadMode<MultiThreaded>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RocksdbInnerStore {
|
#[cfg(feature = "rocksdb")]
|
||||||
|
impl RocksdbStore {
|
||||||
pub fn new<P: AsRef<Path>>(name: P) -> Result<Self, rocksdb::Error> {
|
pub fn new<P: AsRef<Path>>(name: P) -> Result<Self, rocksdb::Error> {
|
||||||
let session_cf_opts = Options::default();
|
let session_cf_opts = Options::default();
|
||||||
let session_cf = ColumnFamilyDescriptor::new(SESSION_CF, session_cf_opts);
|
let session_cf = ColumnFamilyDescriptor::new(SESSION_CF, session_cf_opts);
|
||||||
@ -87,57 +118,14 @@ impl RocksdbInnerStore {
|
|||||||
fn get_users_column_family_handle(&self) -> Option<Arc<BoundColumnFamily>> {
|
fn get_users_column_family_handle(&self) -> Option<Arc<BoundColumnFamily>> {
|
||||||
self.db.cf_handle(USER_CF)
|
self.db.cf_handle(USER_CF)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_id_key(cookie_value: &str) -> async_session::Result<String> {
|
|
||||||
Ok(Session::id_from_cookie_value(cookie_value)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(fields(user=%user_creds.id.0), skip_all)]
|
|
||||||
pub fn check_user_creds(&self, user_creds: &UserCreds) -> async_session::Result<bool> {
|
|
||||||
info!("checking credentials for user");
|
|
||||||
let cf_handle = self
|
|
||||||
.get_users_column_family_handle()
|
|
||||||
.expect(&format!("column family {} is missing", USER_CF));
|
|
||||||
if let Some(payload) = self.db.get_cf(&cf_handle, user_creds.id.0.as_bytes())? {
|
|
||||||
debug!("Found user in credential store");
|
|
||||||
let payload = String::from_utf8_lossy(payload.as_slice()).to_string();
|
|
||||||
let parsed_hash = PasswordHash::new(&payload).expect("Invalid Password Hash");
|
|
||||||
debug!(password_hash=?parsed_hash, "successfuly obtained password hash");
|
|
||||||
let check = Argon2::default()
|
|
||||||
.verify_password(user_creds.pass.expose_secret().as_bytes(), &parsed_hash);
|
|
||||||
if let Err(err) = &check {
|
|
||||||
debug!(err=?err, "Couldn't verify password")
|
|
||||||
}
|
|
||||||
return Ok(check.is_ok());
|
|
||||||
}
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(fields(user=%user_creds.id.0), skip_all)]
|
|
||||||
pub fn store_user_creds(&self, user_creds: UserCreds) -> async_session::Result<()> {
|
|
||||||
// TODO(jwall): Enforce a password length?
|
|
||||||
info!("storing credentials for user {}", user_creds.id.0);
|
|
||||||
let cf_handle = self
|
|
||||||
.get_users_column_family_handle()
|
|
||||||
.expect(&format!("column family {} is missing", USER_CF));
|
|
||||||
let salt = SaltString::generate(&mut OsRng);
|
|
||||||
let password_hash = Argon2::default()
|
|
||||||
.hash_password(user_creds.pass.expose_secret().as_bytes(), &salt)
|
|
||||||
.expect("failed to hash password");
|
|
||||||
self.db.put_cf(
|
|
||||||
&cf_handle,
|
|
||||||
user_creds.id.0.as_bytes(),
|
|
||||||
password_hash.to_string().as_bytes(),
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rocksdb")]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl SessionStore for RocksdbInnerStore {
|
impl SessionStore for RocksdbStore {
|
||||||
#[instrument]
|
#[instrument]
|
||||||
async fn load_session(&self, cookie_value: String) -> async_session::Result<Option<Session>> {
|
async fn load_session(&self, cookie_value: String) -> async_session::Result<Option<Session>> {
|
||||||
let id = Self::make_id_key(&cookie_value)?;
|
let id = make_id_key(&cookie_value)?;
|
||||||
let cf_handle = self
|
let cf_handle = self
|
||||||
.get_session_column_family_handle()
|
.get_session_column_family_handle()
|
||||||
.expect(&format!("column family {} is missing", SESSION_CF));
|
.expect(&format!("column family {} is missing", SESSION_CF));
|
||||||
@ -178,6 +166,49 @@ impl SessionStore for RocksdbInnerStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rocksdb")]
|
||||||
|
#[async_trait]
|
||||||
|
impl AuthStore for RocksdbStore {
|
||||||
|
#[instrument(fields(user=%user_creds.id.0), skip_all)]
|
||||||
|
async fn check_user_creds(&self, user_creds: &UserCreds) -> async_session::Result<bool> {
|
||||||
|
// TODO(jwall): Make this function asynchronous.
|
||||||
|
info!("checking credentials for user");
|
||||||
|
let cf_handle = self
|
||||||
|
.get_users_column_family_handle()
|
||||||
|
.expect(&format!("column family {} is missing", USER_CF));
|
||||||
|
if let Some(payload) = self
|
||||||
|
.db
|
||||||
|
.get_cf(&cf_handle, user_creds.user_id().as_bytes())?
|
||||||
|
{
|
||||||
|
debug!("Found user in credential store");
|
||||||
|
let payload = String::from_utf8_lossy(payload.as_slice()).to_string();
|
||||||
|
return Ok(check_pass(&payload, &user_creds.pass));
|
||||||
|
}
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(jwall): Make this function asynchronous.
|
||||||
|
#[instrument(fields(user=%user_creds.id.0), skip_all)]
|
||||||
|
async fn store_user_creds(&self, user_creds: UserCreds) -> async_session::Result<()> {
|
||||||
|
// TODO(jwall): Enforce a password length?
|
||||||
|
// TODO(jwall): Make this function asynchronous.
|
||||||
|
info!("storing credentials for user {}", user_creds.id.0);
|
||||||
|
let cf_handle = self
|
||||||
|
.get_users_column_family_handle()
|
||||||
|
.expect(&format!("column family {} is missing", USER_CF));
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let password_hash = Argon2::default()
|
||||||
|
.hash_password(user_creds.pass.expose_secret().as_bytes(), &salt)
|
||||||
|
.expect("failed to hash password");
|
||||||
|
self.db.put_cf(
|
||||||
|
&cf_handle,
|
||||||
|
user_creds.id.0.as_bytes(),
|
||||||
|
password_hash.to_string().as_bytes(),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<B> FromRequest<B> for UserIdFromSession
|
impl<B> FromRequest<B> for UserIdFromSession
|
||||||
where
|
where
|
||||||
@ -187,7 +218,7 @@ where
|
|||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||||
let Extension(session_store) = Extension::<RocksdbInnerStore>::from_request(req)
|
let Extension(session_store) = Extension::<SqliteStore>::from_request(req)
|
||||||
.await
|
.await
|
||||||
.expect("No Session store configured!");
|
.expect("No Session store configured!");
|
||||||
let cookies = Option::<TypedHeader<Cookie>>::from_request(req)
|
let cookies = Option::<TypedHeader<Cookie>>::from_request(req)
|
||||||
@ -197,20 +228,24 @@ where
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|c| c.get(AXUM_SESSION_COOKIE_NAME))
|
.and_then(|c| c.get(AXUM_SESSION_COOKIE_NAME))
|
||||||
{
|
{
|
||||||
if let Some(session) = session_store
|
debug!(?session_cookie, "processing session cookie");
|
||||||
.load_session(session_cookie.to_owned())
|
match session_store.load_session(session_cookie.to_owned()).await {
|
||||||
.await
|
Ok(Some(session)) => {
|
||||||
.unwrap()
|
if let Some(user_id) = session.get::<UserId>("user_id") {
|
||||||
{
|
return Ok(Self::FoundUserId(user_id));
|
||||||
if let Some(user_id) = session.get::<UserId>("user_id") {
|
} else {
|
||||||
return Ok(Self::FoundUserId(user_id));
|
error!("No user id found in session");
|
||||||
} else {
|
return Ok(Self::NoUserId);
|
||||||
error!("No user id found in session");
|
}
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
debug!("no session defined in headers.");
|
||||||
|
return Ok(Self::NoUserId);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
debug!(err=?e, "error deserializing session");
|
||||||
return Ok(Self::NoUserId);
|
return Ok(Self::NoUserId);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
debug!("no session defined in headers.");
|
|
||||||
return Ok(Self::NoUserId);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("no cookies defined in headers.");
|
debug!("no cookies defined in headers.");
|
||||||
@ -218,3 +253,119 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
use sqlx::{
|
||||||
|
self,
|
||||||
|
sqlite::{SqliteConnectOptions, SqliteJournalMode},
|
||||||
|
SqlitePool,
|
||||||
|
};
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SqliteStore {
|
||||||
|
pool: Arc<SqlitePool>,
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
impl SqliteStore {
|
||||||
|
pub async fn new<P: AsRef<Path>>(path: P) -> sqlx::Result<Self> {
|
||||||
|
let url = format!("sqlite://{}/store.db", path.as_ref().to_string_lossy());
|
||||||
|
let options = SqliteConnectOptions::from_str(&url)?.journal_mode(SqliteJournalMode::Wal);
|
||||||
|
let pool = Arc::new(sqlx::SqlitePool::connect_with(options).await?);
|
||||||
|
Ok(Self { pool, url })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
#[async_trait]
|
||||||
|
impl SessionStore for SqliteStore {
|
||||||
|
#[instrument(fields(conn_string=self.url), skip_all)]
|
||||||
|
async fn load_session(&self, cookie_value: String) -> async_session::Result<Option<Session>> {
|
||||||
|
let id = make_id_key(&cookie_value)?;
|
||||||
|
debug!(id, "fetching session from sqlite");
|
||||||
|
if let Some(payload) =
|
||||||
|
sqlx::query_scalar!("select session_value from sessions where id = ?", id)
|
||||||
|
.fetch_optional(self.pool.as_ref())
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
debug!(sesion_id = id, "found session key");
|
||||||
|
let session: Session = ciborium::de::from_reader(payload.as_slice())?;
|
||||||
|
return Ok(Some(session));
|
||||||
|
}
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(fields(conn_string=self.url), skip_all)]
|
||||||
|
async fn store_session(&self, session: Session) -> async_session::Result<Option<String>> {
|
||||||
|
let id = session.id();
|
||||||
|
let mut payload: Vec<u8> = Vec::new();
|
||||||
|
ciborium::ser::into_writer(&session, &mut payload)?;
|
||||||
|
sqlx::query!(
|
||||||
|
"insert into sessions (id, session_value) values (?, ?)",
|
||||||
|
id,
|
||||||
|
payload
|
||||||
|
)
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await?;
|
||||||
|
debug!(sesion_id = id, "successfully inserted session key");
|
||||||
|
return Ok(session.into_cookie_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(fields(conn_string=self.url), skip_all)]
|
||||||
|
async fn destroy_session(&self, session: Session) -> async_session::Result {
|
||||||
|
let id = session.id();
|
||||||
|
sqlx::query!("delete from sessions where id = ?", id,)
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(fields(conn_string=self.url), skip_all)]
|
||||||
|
async fn clear_store(&self) -> async_session::Result {
|
||||||
|
sqlx::query!("delete from sessions")
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
#[async_trait]
|
||||||
|
impl AuthStore for SqliteStore {
|
||||||
|
#[instrument(fields(user=%user_creds.id.0, conn_string=self.url), skip_all)]
|
||||||
|
async fn check_user_creds(&self, user_creds: &UserCreds) -> async_session::Result<bool> {
|
||||||
|
let id = user_creds.user_id().to_owned();
|
||||||
|
if let Some(payload) =
|
||||||
|
sqlx::query_scalar!("select password_hashed from users where id = ?", id)
|
||||||
|
.fetch_optional(self.pool.as_ref())
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
debug!("Testing password for user");
|
||||||
|
return Ok(check_pass(&payload, &user_creds.pass));
|
||||||
|
}
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(fields(user=%user_creds.id.0, conn_string=self.url), skip_all)]
|
||||||
|
async fn store_user_creds(&self, user_creds: UserCreds) -> async_session::Result<()> {
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let password_hash = Argon2::default()
|
||||||
|
.hash_password(user_creds.pass.expose_secret().as_bytes(), &salt)
|
||||||
|
.expect("failed to hash password");
|
||||||
|
let id = user_creds.user_id().to_owned();
|
||||||
|
let password_hashed = password_hash.to_string();
|
||||||
|
debug!("adding password for user");
|
||||||
|
sqlx::query!(
|
||||||
|
"insert into users (id, password_hashed) values (?, ?)",
|
||||||
|
id,
|
||||||
|
password_hashed,
|
||||||
|
)
|
||||||
|
.execute(self.pool.as_ref())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
nix/devShell/default.nix
Normal file
6
nix/devShell/default.nix
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{ pkgs, rust-wasm }:
|
||||||
|
with pkgs;
|
||||||
|
mkShell {
|
||||||
|
buildInputs = (if stdenv.isDarwin then [ pkgs.darwin.apple_sdk.frameworks.Security ] else [ ]) ++ (with pkgs; [wasm-bindgen-cli wasm-pack llvm clang rust-wasm]);
|
||||||
|
#buildInputs = with pkgs; [wasm-bindgen-cli wasm-pack];
|
||||||
|
}
|
@ -13,7 +13,7 @@ with pkgs;
|
|||||||
buildInputs = [ rust-wasm ];
|
buildInputs = [ rust-wasm ];
|
||||||
# However the crate we are building has it's root in specific crate.
|
# However the crate we are building has it's root in specific crate.
|
||||||
src = root;
|
src = root;
|
||||||
nativeBuildInputs = if stdenv.isDarwin then [ xcbuild ] else [ ];
|
nativeBuildInputs = (if stdenv.isDarwin then [ xcbuild pkgs.darwin.apple_sdk.frameworks.Security ] else [ ]) ++ [llvm clang];
|
||||||
cargoBuildOptions = opts: opts ++ ["-p" "${pname}" ];
|
cargoBuildOptions = opts: opts ++ ["-p" "${pname}" ];
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
mkdir -p web/dist
|
mkdir -p web/dist
|
||||||
|
@ -56,6 +56,7 @@ pub fn login_form() -> View<G> {
|
|||||||
if username != "" && password != "" {
|
if username != "" && password != "" {
|
||||||
spawn_local_in_scope(async move {
|
spawn_local_in_scope(async move {
|
||||||
debug!("authenticating against ui");
|
debug!("authenticating against ui");
|
||||||
|
// TODO(jwall): Navigate to plan if the below is successful.
|
||||||
authenticate(username, password).await;
|
authenticate(username, password).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user